ntmemoryapi 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ntmemoryapi/misc.py ADDED
@@ -0,0 +1,102 @@
1
+ # +-------------------------------------+
2
+ # | ~ Author : Xenely ~ |
3
+ # +=====================================+
4
+ # | GitHub: https://github.com/Xenely14 |
5
+ # | Discord: xenely |
6
+ # +-------------------------------------+
7
+
8
+ import ctypes
9
+ import struct
10
+ import typing
11
+ import ctypes.wintypes
12
+
13
+ # ==-------------------------------------------------------------------== #
14
+ # DLL functions #
15
+ # ==-------------------------------------------------------------------== #
16
+
17
+ # DLL libraries loading
18
+ _kernel32 = ctypes.windll.kernel32
19
+
20
+ # DLL libraries functions loading
21
+ _LoadLibraryA = _kernel32.LoadLibraryA
22
+ _GetProcAddress = _kernel32.GetProcAddress
23
+ _VirtualProtect = _kernel32.VirtualProtect
24
+
25
+ # Define of DLL libraries functions return type
26
+ _LoadLibraryA.restype = ctypes.wintypes.LPVOID
27
+ _GetProcAddress.restype = ctypes.wintypes.LPVOID
28
+ _VirtualProtect.restype = ctypes.wintypes.BOOL
29
+
30
+ # Define of DLL libraries functions argument types
31
+ _LoadLibraryA .argtypes = [ctypes.wintypes.LPCSTR]
32
+ _GetProcAddress.argtypes = [ctypes.wintypes.LPVOID, ctypes.wintypes.LPCSTR]
33
+ _VirtualProtect.argtypes = [ctypes.wintypes.LPVOID, ctypes.c_size_t, ctypes.wintypes.DWORD, ctypes.POINTER(ctypes.wintypes.DWORD)]
34
+
35
+
36
+ # ==-------------------------------------------------------------------== #
37
+ # Functions #
38
+ # ==-------------------------------------------------------------------== #
39
+ def syscall(nt_function_name: str, *, result_type: typing.Any, arguments_types: list[typing.Any], module: bytes = b"ntdll.dll") -> ctypes.WINFUNCTYPE:
40
+ """Finds function in DLL module by it name, retrieves it's syscall ID, wraps it into raw function buffer and casts to `WINFUNCTYPE` to make call shadowed."""
41
+
42
+ # Module loading
43
+ if not (module_handle := _LoadLibraryA(module)):
44
+ raise Exception("Unable to load module `%s`" % module.decode())
45
+
46
+ # Retrieve nt-function pointer
47
+ if not (nt_function := _GetProcAddress(module_handle, nt_function_name.encode())):
48
+ raise Exception("Function `%s` not found" % nt_function_name)
49
+
50
+ offset = 0
51
+ syscall_id = None
52
+
53
+ # Retrieve syscall ID from nt-function pointer
54
+ while True:
55
+
56
+ # Syscall ID not found
57
+ if offset > 0x16:
58
+ break
59
+
60
+ # Retrieve syscall ID from memory
61
+ if ctypes.cast(nt_function + offset, ctypes.POINTER(ctypes.c_ubyte)).contents.value == 0xB8:
62
+ syscall_id = ctypes.cast(nt_function + offset + 1, ctypes.POINTER(ctypes.c_ushort)).contents.value
63
+ break
64
+
65
+ offset += 1
66
+
67
+ # Syscall ID not found
68
+ if syscall_id is None:
69
+ raise Exception("Syscall ID for function `%s` not found" % nt_function_name)
70
+
71
+ # Convert syscall ID to hex-bytes list
72
+ syscall_id_bytes = [hex(item)[2:] if len(hex(item)[2:]) == 2 else "0" + hex(item)[2:] for item in struct.pack("<h", syscall_id)]
73
+
74
+ # NOTE: I actually don't know why does this code require access `gs` segment.
75
+ # I've just used this repo as reference: https://github.com/opcode86/SysCaller
76
+ #
77
+ # mov rax, gs:[0x60]
78
+ # mov r10, rcx
79
+ # mov eax, <syscall id>,
80
+ # syscall
81
+ # ret
82
+ shellcode = bytes.fromhex("""
83
+ 65 48 8B 04 25 60 00
84
+ 00 00
85
+ 4C 8B D1
86
+ B8 %s %s 00 00
87
+ 0F 05
88
+ C3
89
+ """ % tuple([*syscall_id_bytes]))
90
+
91
+ # Allocate buffer for function machine code
92
+ buffer = (ctypes.c_uint8 * len(shellcode))()
93
+ shellcode_buffer = ctypes.cast(buffer, ctypes.c_void_p)
94
+
95
+ # Copy shellcode into function machine code buffer
96
+ ctypes.memmove(shellcode_buffer, ctypes.create_string_buffer(shellcode, len(shellcode)), len(shellcode))
97
+
98
+ # Update of function machine code buffer memory protection to make it executable
99
+ ctypes.windll.kernel32.VirtualProtect(shellcode_buffer, len(shellcode), 0x40, ctypes.wintypes.LPDWORD(ctypes.wintypes.DWORD()))
100
+
101
+ # Return wrapped syscall function
102
+ return ctypes.cast(shellcode_buffer, ctypes.WINFUNCTYPE(result_type, *arguments_types))
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.3
2
+ Name: ntmemoryapi
3
+ Version: 1.0.0
4
+ Summary: Simple library for Windows to manipulate process virtual memory with stelthy syscall wraps
5
+ Author: Xenely
6
+ Requires-Python: >=3.10
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Description-Content-Type: text/markdown
13
+
14
+
@@ -0,0 +1,6 @@
1
+ ntmemoryapi/__init__.py,sha256=K8YAkx1OKyniDeEkv0u2Ydf89mOE5lL9kDFLkCWDMGo,38893
2
+ ntmemoryapi/embed.py,sha256=CQXFDPwHZDoouMSxveng8YL_PWjyhQsw1akdUEjXnCk,113455
3
+ ntmemoryapi/misc.py,sha256=pG_O8EzddXRNADTYfDPOMUiHwKrxeGGMeJhlAV1xkRQ,4168
4
+ ntmemoryapi-1.0.0.dist-info/METADATA,sha256=sy0rvsFy4r4lyH8-sTtV2sERFaTNoLhV_Q4lJBT6Z0Q,488
5
+ ntmemoryapi-1.0.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
6
+ ntmemoryapi-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.1.3
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any