@@ -83,11 +83,13 @@ The `quiet` flag suppresses the logs about DLLs loaded and memory regions set up
8383
8484### Custom syscall implementation
8585
86- ** Note ** : This part of dumpulator still needs a lot of work.
86+ You can (re)implement syscalls by using the ` @syscall ` decorator:
8787
8888``` python
89- from dumpulator import Dumpulator, syscall
89+ from dumpulator import *
9090from dumpulator.native import *
91+ from dumpulator.handles import *
92+ from dumpulator.memory import *
9193
9294@syscall
9395def ZwQueryVolumeInformationFile (dp : Dumpulator,
@@ -100,7 +102,90 @@ def ZwQueryVolumeInformationFile(dp: Dumpulator,
100102 return STATUS_NOT_IMPLEMENTED
101103```
102104
103- You can get the syscall parameters from [ ntsyscalls.py] ( https://github.com/mrexodia/dumpulator/blob/main/src/dumpulator/ntsyscalls.py ) . There are also a lot of examples there on how to use the API.
105+ All the syscall function prototypes can be found in [ ntsyscalls.py] ( https://github.com/mrexodia/dumpulator/blob/main/src/dumpulator/ntsyscalls.py ) . There are also a lot of examples there on how to use the API.
106+
107+ To hook an existing syscall implementation you can do the following:
108+
109+ ``` python
110+ import dumpulator.ntsyscalls as ntsyscalls
111+
112+ @syscall
113+ def ZwOpenProcess (dp : Dumpulator,
114+ ProcessHandle : Annotated[P[HANDLE ], SAL(" _Out_" )],
115+ DesiredAccess : Annotated[ACCESS_MASK , SAL(" _In_" )],
116+ ObjectAttributes : Annotated[P[OBJECT_ATTRIBUTES ], SAL(" _In_" )],
117+ ClientId : Annotated[P[CLIENT_ID ], SAL(" _In_opt_" )]
118+ ):
119+ process_id = ClientId.read_ptr()
120+ assert process_id == dp.parent_process_id
121+ ProcessHandle.write_ptr(0x 1337 )
122+ return STATUS_SUCCESS
123+
124+ @syscall
125+ def ZwQueryInformationProcess (dp : Dumpulator,
126+ ProcessHandle : Annotated[HANDLE , SAL(" _In_" )],
127+ ProcessInformationClass : Annotated[PROCESSINFOCLASS , SAL(" _In_" )],
128+ ProcessInformation : Annotated[PVOID , SAL(" _Out_writes_bytes_(ProcessInformationLength)" )],
129+ ProcessInformationLength : Annotated[ULONG , SAL(" _In_" )],
130+ ReturnLength : Annotated[P[ULONG ], SAL(" _Out_opt_" )]
131+ ):
132+ if ProcessInformationClass == PROCESSINFOCLASS .ProcessImageFileNameWin32:
133+ if ProcessHandle == dp.NtCurrentProcess():
134+ main_module = dp.modules[dp.modules.main]
135+ image_path = main_module.path
136+ elif ProcessHandle == 0x 1337 :
137+ image_path = R " C:\Windows\explorer.exe"
138+ else :
139+ raise NotImplementedError ()
140+ buffer = UNICODE_STRING .create_buffer(image_path, ProcessInformation)
141+ assert ProcessInformationLength >= len (buffer)
142+ if ReturnLength.ptr:
143+ dp.write_ulong(ReturnLength.ptr, len (buffer))
144+ ProcessInformation.write(buffer)
145+ return STATUS_SUCCESS
146+ return ntsyscalls.ZwQueryInformationProcess(dp,
147+ ProcessHandle,
148+ ProcessInformationClass,
149+ ProcessInformation,
150+ ProcessInformationLength,
151+ ReturnLength
152+ )
153+ ```
154+
155+ ### Custom structures
156+
157+ Since ` v0.2.0 ` there is support for easily declaring your own structures:
158+
159+ ``` python
160+ from dumpulator.native import *
161+
162+ class PROCESS_BASIC_INFORMATION (Struct ):
163+ ExitStatus: ULONG
164+ PebBaseAddress: PVOID
165+ AffinityMask: KAFFINITY
166+ BasePriority: KPRIORITY
167+ UniqueProcessId: ULONG_PTR
168+ InheritedFromUniqueProcessId: ULONG_PTR
169+ ```
170+
171+ To instantiate these structures you have to use a ` Dumpulator ` instance:
172+
173+ ``` python
174+ pbi = PROCESS_BASIC_INFORMATION(dp)
175+ assert ProcessInformationLength == Struct.sizeof(pbi)
176+ pbi.ExitStatus = 259 # STILL_ACTIVE
177+ pbi.PebBaseAddress = dp.peb
178+ pbi.AffinityMask = 0x FFFF
179+ pbi.BasePriority = 8
180+ pbi.UniqueProcessId = dp.process_id
181+ pbi.InheritedFromUniqueProcessId = dp.parent_process_id
182+ ProcessInformation.write(bytes (pbi))
183+ if ReturnLength.ptr:
184+ dp.write_ulong(ReturnLength.ptr, Struct.sizeof(pbi))
185+ return STATUS_SUCCESS
186+ ```
187+
188+ If you pass a pointer value as a second argument the structure will be read from memory. You can declare pointers with ` myptr: P[MY_STRUCT] ` and dereferences them with ` myptr[0] ` .
104189
105190## Collecting the dump
106191
0 commit comments