| Home | Trees | Indices | Help |
|
|---|
|
|
1 # Copyright (c) 2009, Mario Vilas
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
6 #
7 # * Redistributions of source code must retain the above copyright notice,
8 # this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above copyright
10 # notice,this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
12 # * Neither the name of the copyright holder nor the names of its
13 # contributors may be used to endorse or promote products derived from
14 # this software without specific prior written permission.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 # POSSIBILITY OF SUCH DAMAGE.
27
28 """
29 Debugging API wrappers in ctypes.
30
31 @see: U{http://apps.sourceforge.net/trac/winappdbg/wiki/Win32APIWrappers}
32 """
33
34 __revision__ = "$Id: ntdll.py 478 2009-11-28 04:19:09Z qvasimodo $"
35
36 from defines import *
37 from peb_teb import *
38
39 #--- Types --------------------------------------------------------------------
40
41 SYSDBG_COMMAND = DWORD
42 PROCESSINFOCLASS = DWORD
43 THREADINFOCLASS = DWORD
44 FILE_INFORMATION_CLASS = DWORD
45
46 #--- Constants ----------------------------------------------------------------
47
48 # DEP flags for ProcessExecuteFlags
49 MEM_EXECUTE_OPTION_ENABLE = 1
50 MEM_EXECUTE_OPTION_DISABLE = 2
51 MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4
52 MEM_EXECUTE_OPTION_PERMANENT = 8
53
54 # SYSTEM_INFORMATION_CLASS
55 # http://www.informit.com/articles/article.aspx?p=22442&seqNum=4
56 SystemBasicInformation = 1 # 0x002C
57 SystemProcessorInformation = 2 # 0x000C
58 SystemPerformanceInformation = 3 # 0x0138
59 SystemTimeInformation = 4 # 0x0020
60 SystemPathInformation = 5 # not implemented
61 SystemProcessInformation = 6 # 0x00F8 + per process
62 SystemCallInformation = 7 # 0x0018 + (n * 0x0004)
63 SystemConfigurationInformation = 8 # 0x0018
64 SystemProcessorCounters = 9 # 0x0030 per cpu
65 SystemGlobalFlag = 10 # 0x0004
66 SystemInfo10 = 11 # not implemented
67 SystemModuleInformation = 12 # 0x0004 + (n * 0x011C)
68 SystemLockInformation = 13 # 0x0004 + (n * 0x0024)
69 SystemInfo13 = 14 # not implemented
70 SystemPagedPoolInformation = 15 # checked build only
71 SystemNonPagedPoolInformation = 16 # checked build only
72 SystemHandleInformation = 17 # 0x0004 + (n * 0x0010)
73 SystemObjectInformation = 18 # 0x0038+ + (n * 0x0030+)
74 SystemPagefileInformation = 19 # 0x0018+ per page file
75 SystemInstemulInformation = 20 # 0x0088
76 SystemInfo20 = 21 # invalid info class
77 SystemCacheInformation = 22 # 0x0024
78 SystemPoolTagInformation = 23 # 0x0004 + (n * 0x001C)
79 SystemProcessorStatistics = 24 # 0x0000, or 0x0018 per cpu
80 SystemDpcInformation = 25 # 0x0014
81 SystemMemoryUsageInformation1 = 26 # checked build only
82 SystemLoadImage = 27 # 0x0018, set mode only
83 SystemUnloadImage = 28 # 0x0004, set mode only
84 SystemTimeAdjustmentInformation = 29 # 0x000C, 0x0008 writeable
85 SystemMemoryUsageInformation2 = 30 # checked build only
86 SystemInfo30 = 31 # checked build only
87 SystemInfo31 = 32 # checked build only
88 SystemCrashDumpInformation = 33 # 0x0004
89 SystemExceptionInformation = 34 # 0x0010
90 SystemCrashDumpStateInformation = 35 # 0x0008
91 SystemDebuggerInformation = 36 # 0x0002
92 SystemThreadSwitchInformation = 37 # 0x0030
93 SystemRegistryQuotaInformation = 38 # 0x000C
94 SystemLoadDriver = 39 # 0x0008, set mode only
95 SystemPrioritySeparationInformation = 40 # 0x0004, set mode only
96 SystemInfo40 = 41 # not implemented
97 SystemInfo41 = 42 # not implemented
98 SystemInfo42 = 43 # invalid info class
99 SystemInfo43 = 44 # invalid info class
100 SystemTimeZoneInformation = 45 # 0x00AC
101 SystemLookasideInformation = 46 # n * 0x0020
102 # info classes specific to Windows 2000
103 # WTS = Windows Terminal Server
104 SystemSetTimeSlipEvent = 47 # set mode only
105 SystemCreateSession = 48 # WTS, set mode only
106 SystemDeleteSession = 49 # WTS, set mode only
107 SystemInfo49 = 50 # invalid info class
108 SystemRangeStartInformation = 51 # 0x0004
109 SystemVerifierInformation = 52 # 0x0068
110 SystemAddVerifier = 53 # set mode only
111 SystemSessionProcessesInformation = 54 # WTS
112
113 # NtQueryInformationProcess constants (from MSDN)
114 ##ProcessBasicInformation = 0
115 ##ProcessDebugPort = 7
116 ##ProcessWow64Information = 26
117 ##ProcessImageFileName = 27
118
119 # PROCESS_INFORMATION_CLASS
120 # http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PROCESS_INFORMATION_CLASS.html
121 ProcessBasicInformation = 0
122 ProcessQuotaLimits = 1
123 ProcessIoCounters = 2
124 ProcessVmCounters = 3
125 ProcessTimes = 4
126 ProcessBasePriority = 5
127 ProcessRaisePriority = 6
128 ProcessDebugPort = 7
129 ProcessExceptionPort = 8
130 ProcessAccessToken = 9
131 ProcessLdtInformation = 10
132 ProcessLdtSize = 11
133 ProcessDefaultHardErrorMode = 12
134 ProcessIoPortHandlers = 13
135 ProcessPooledUsageAndLimits = 14
136 ProcessWorkingSetWatch = 15
137 ProcessUserModeIOPL = 16
138 ProcessEnableAlignmentFaultFixup = 17
139 ProcessPriorityClass = 18
140 ProcessWx86Information = 19
141 ProcessHandleCount = 20
142 ProcessAffinityMask = 21
143 ProcessPriorityBoost = 22
144
145 ProcessWow64Information = 26
146 ProcessImageFileName = 27
147
148 # http://www.codeproject.com/KB/security/AntiReverseEngineering.aspx
149 ProcessDebugObjectHandle = 30
150
151 ProcessExecuteFlags = 34
152
153 # THREAD_INFORMATION_CLASS
154 ThreadBasicInformation = 0
155 ThreadTimes = 1
156 ThreadPriority = 2
157 ThreadBasePriority = 3
158 ThreadAffinityMask = 4
159 ThreadImpersonationToken = 5
160 ThreadDescriptorTableEntry = 6
161 ThreadEnableAlignmentFaultFixup = 7
162 ThreadEventPair = 8
163 ThreadQuerySetWin32StartAddress = 9
164 ThreadZeroTlsCell = 10
165 ThreadPerformanceCount = 11
166 ThreadAmILastThread = 12
167 ThreadIdealProcessor = 13
168 ThreadPriorityBoost = 14
169 ThreadSetTlsArrayAddress = 15
170 ThreadIsIoPending = 16
171 ThreadHideFromDebugger = 17
172
173 # OBJECT_INFORMATION_CLASS
174 ObjectBasicInformation = 0
175 ObjectNameInformation = 1
176 ObjectTypeInformation = 2
177 ObjectAllTypesInformation = 3
178 ObjectHandleInformation = 4
179
180 # FILE_INFORMATION_CLASS
181 FileDirectoryInformation = 1
182 FileFullDirectoryInformation = 2
183 FileBothDirectoryInformation = 3
184 FileBasicInformation = 4
185 FileStandardInformation = 5
186 FileInternalInformation = 6
187 FileEaInformation = 7
188 FileAccessInformation = 8
189 FileNameInformation = 9
190 FileRenameInformation = 10
191 FileLinkInformation = 11
192 FileNamesInformation = 12
193 FileDispositionInformation = 13
194 FilePositionInformation = 14
195 FileFullEaInformation = 15
196 FileModeInformation = 16
197 FileAlignmentInformation = 17
198 FileAllInformation = 18
199 FileAllocationInformation = 19
200 FileEndOfFileInformation = 20
201 FileAlternateNameInformation = 21
202 FileStreamInformation = 22
203 FilePipeInformation = 23
204 FilePipeLocalInformation = 24
205 FilePipeRemoteInformation = 25
206 FileMailslotQueryInformation = 26
207 FileMailslotSetInformation = 27
208 FileCompressionInformation = 28
209 FileCopyOnWriteInformation = 29
210 FileCompletionInformation = 30
211 FileMoveClusterInformation = 31
212 FileQuotaInformation = 32
213 FileReparsePointInformation = 33
214 FileNetworkOpenInformation = 34
215 FileObjectIdInformation = 35
216 FileTrackingInformation = 36
217 FileOleDirectoryInformation = 37
218 FileContentIndexInformation = 38
219 FileInheritContentIndexInformation = 37
220 FileOleInformation = 39
221 FileMaximumInformation = 40
222
223 # From http://www.nirsoft.net/kernel_struct/vista/EXCEPTION_DISPOSITION.html
224 # typedef enum _EXCEPTION_DISPOSITION
225 # {
226 # ExceptionContinueExecution = 0,
227 # ExceptionContinueSearch = 1,
228 # ExceptionNestedException = 2,
229 # ExceptionCollidedUnwind = 3
230 # } EXCEPTION_DISPOSITION;
231 ExceptionContinueExecution = 0
232 ExceptionContinueSearch = 1
233 ExceptionNestedException = 2
234 ExceptionCollidedUnwind = 3
235
236 #--- PROCESS_BASIC_INFORMATION structure --------------------------------------
237
238 # From MSDN:
239 #
240 # typedef struct _PROCESS_BASIC_INFORMATION {
241 # PVOID Reserved1;
242 # PPEB PebBaseAddress;
243 # PVOID Reserved2[2];
244 # ULONG_PTR UniqueProcessId;
245 # PVOID Reserved3;
246 # } PROCESS_BASIC_INFORMATION;
247 ##class PROCESS_BASIC_INFORMATION(Structure):
248 ## _fields_ = [
249 ## ("Reserved1", PVOID),
250 ## ("PebBaseAddress", PPEB),
251 ## ("Reserved2", PVOID * 2),
252 ## ("UniqueProcessId", ULONG_PTR),
253 ## ("Reserved3", PVOID),
254 ##]
255
256 # From http://catch22.net/tuts/tips2
257 # (Only valid for 32 bits)
258 #
259 # typedef struct
260 # {
261 # ULONG ExitStatus;
262 # PVOID PebBaseAddress;
263 # ULONG AffinityMask;
264 # ULONG BasePriority;
265 # ULONG_PTR UniqueProcessId;
266 # ULONG_PTR InheritedFromUniqueProcessId;
267 # } PROCESS_BASIC_INFORMATION;
268
269 # My own definition follows:
271 _fields_ = [
272 ("ExitStatus", NTSTATUS),
273 ("PebBaseAddress", PVOID), # PPEB
274 ("AffinityMask", KAFFINITY),
275 ("BasePriority", SDWORD),
276 ("UniqueProcessId", PVOID),
277 ("InheritedFromUniqueProcessId", PVOID),
278 ]
279
280 #--- THREAD_BASIC_INFORMATION structure ---------------------------------------
281
282 # From http://undocumented.ntinternals.net/UserMode/Structures/THREAD_BASIC_INFORMATION.html
283 #
284 # typedef struct _THREAD_BASIC_INFORMATION {
285 # NTSTATUS ExitStatus;
286 # PVOID TebBaseAddress;
287 # CLIENT_ID ClientId;
288 # KAFFINITY AffinityMask;
289 # KPRIORITY Priority;
290 # KPRIORITY BasePriority;
291 # } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
293 _fields_ = [
294 ("ExitStatus", NTSTATUS),
295 ("TebBaseAddress", PVOID), # PTEB
296 ("ClientId", CLIENT_ID),
297 ("AffinityMask", KAFFINITY),
298 ("Priority", SDWORD),
299 ("BasePriority", SDWORD),
300 ]
301
302 #--- FILE_NAME_INFORMATION structure ------------------------------------------
303
304 # typedef struct _FILE_NAME_INFORMATION {
305 # ULONG FileNameLength;
306 # WCHAR FileName[1];
307 # } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
313
314 #--- SYSDBG_MSR structure and constants ---------------------------------------
315
316 SysDbgReadMsr = 16
317 SysDbgWriteMsr = 17
318
324
325 #--- IO_STATUS_BLOCK structure ------------------------------------------------
326
327 # typedef struct _IO_STATUS_BLOCK {
328 # union {
329 # NTSTATUS Status;
330 # PVOID Pointer;
331 # };
332 # ULONG_PTR Information;
333 # } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
335 _fields_ = [
336 ("Status", NTSTATUS),
337 ("Information", ULONG_PTR),
338 ]
340 return PVOID(self.Status)
343 Pointer = property(__get_Pointer, __set_Pointer)
344
345 PIO_STATUS_BLOCK = POINTER(IO_STATUS_BLOCK)
346
347 #--- ntdll.dll ----------------------------------------------------------------
348
349 # ULONG WINAPI RtlNtStatusToDosError(
350 # __in NTSTATUS Status
351 # );
353 _RtlNtStatusToDosError = windll.ntdll.RtlNtStatusToDosError
354 _RtlNtStatusToDosError.argtypes = [NTSTATUS]
355 _RtlNtStatusToDosError.restype = ULONG
356 return _RtlNtStatusToDosError(Status)
357
358 # NTSYSAPI NTSTATUS NTAPI NtSystemDebugControl(
359 # IN SYSDBG_COMMAND Command,
360 # IN PVOID InputBuffer OPTIONAL,
361 # IN ULONG InputBufferLength,
362 # OUT PVOID OutputBuffer OPTIONAL,
363 # IN ULONG OutputBufferLength,
364 # OUT PULONG ReturnLength OPTIONAL
365 # );
366 -def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, OutputBuffer = None, OutputBufferLength = None):
367 _NtSystemDebugControl = windll.ntdll.NtSystemDebugControl
368 _NtSystemDebugControl.argtypes = [SYSDBG_COMMAND, PVOID, ULONG, PVOID, ULONG, PULONG]
369 _NtSystemDebugControl.restype = NTSTATUS
370 if InputBuffer is None:
371 InputBuffer = NULL
372 if InputBufferLength is None:
373 if InputBuffer == NULL:
374 InputBufferLength = 0
375 else:
376 InputBufferLength = sizeof(InputBuffer)
377 if OutputBuffer is None:
378 if OutputBufferLength is None:
379 OutputBuffer = NULL
380 OutputBufferLength = 0
381 else:
382 OutputBuffer = ctypes.create_string_buffer("", OutputBufferLength)
383 elif OutputBufferLength is None:
384 OutputBufferLength = sizeof(OutputBuffer)
385 if InputBuffer != NULL:
386 InputBuffer = ctypes.byref(InputBuffer)
387 if OutputBuffer != NULL:
388 OutputBuffer = ctypes.byref(OutputBuffer)
389 ReturnLength = ULONG(0)
390 ntstatus = _NtSystemDebugControl(Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ctypes.byref(ReturnLength))
391 if ntstatus != 0:
392 raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
393 return OutputBuffer, ReturnLength.value
394
395 ZwSystemDebugControl = NtSystemDebugControl
396
397 # NTSTATUS WINAPI NtQueryInformationProcess(
398 # __in HANDLE ProcessHandle,
399 # __in PROCESSINFOCLASS ProcessInformationClass,
400 # __out PVOID ProcessInformation,
401 # __in ULONG ProcessInformationLength,
402 # __out_opt PULONG ReturnLength
403 # );
404 -def NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformationLength = None):
405 _NtQueryInformationProcess = windll.ntdll.NtQueryInformationProcess
406 _NtQueryInformationProcess.argtypes = [HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG]
407 _NtQueryInformationProcess.restype = NTSTATUS
408 if ProcessInformationLength is not None:
409 ProcessInformation = ctypes.create_string_buffer("", ProcessInformationLength)
410 else:
411 if ProcessInformationClass == ProcessBasicInformation:
412 ProcessInformation = PROCESS_BASIC_INFORMATION()
413 ProcessInformationLength = sizeof(PROCESS_BASIC_INFORMATION)
414 elif ProcessInformationClass == ProcessImageFileName:
415 unicode_buffer = ctypes.create_unicode_buffer(u"", 0x1000)
416 ProcessInformation = UNICODE_STRING(0, 0x1000, ctypes.addressof(unicode_buffer))
417 ProcessInformationLength = sizeof(UNICODE_STRING)
418 elif ProcessInformationClass in (ProcessDebugPort, ProcessWow64Information, ProcessWx86Information, ProcessHandleCount, ProcessPriorityBoost):
419 ProcessInformation = DWORD()
420 ProcessInformationLength = sizeof(DWORD)
421 else:
422 raise Exception, "Unknown ProcessInformationClass, use an explicit ProcessInformationLength value instead"
423 ReturnLength = ULONG(0)
424 ntstatus = _NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ctypes.byref(ProcessInformation), ProcessInformationLength, ctypes.byref(ReturnLength))
425 if ntstatus != 0:
426 raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
427 if ProcessInformationClass == ProcessBasicInformation:
428 retval = ProcessInformation
429 elif ProcessInformationClass in (ProcessDebugPort, ProcessWow64Information, ProcessWx86Information, ProcessHandleCount, ProcessPriorityBoost):
430 retval = ProcessInformation.value
431 elif ProcessInformationClass == ProcessImageFileName:
432 vptr = ctypes.c_void_p(ProcessInformation.Buffer)
433 cptr = ctypes.cast( vptr, ctypes.c_wchar * ProcessInformation.Length )
434 retval = cptr.contents.raw
435 else:
436 retval = ProcessInformation.raw[:ReturnLength.value]
437 return retval
438
439 ZwQueryInformationProcess = NtQueryInformationProcess
440
441 # NTSTATUS WINAPI NtQueryInformationThread(
442 # __in HANDLE ThreadHandle,
443 # __in THREADINFOCLASS ThreadInformationClass,
444 # __out PVOID ThreadInformation,
445 # __in ULONG ThreadInformationLength,
446 # __out_opt PULONG ReturnLength
447 # );
448 -def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformationLength = None):
449 _NtQueryInformationThread = windll.ntdll.NtQueryInformationThread
450 _NtQueryInformationThread.argtypes = [HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG]
451 _NtQueryInformationThread.restype = NTSTATUS
452 if ThreadInformationLength is not None:
453 ThreadInformation = ctypes.create_string_buffer("", ThreadInformationLength)
454 else:
455 if ThreadInformationClass == ThreadBasicInformation:
456 ThreadInformation = THREAD_BASIC_INFORMATION()
457 ThreadInformationLength = sizeof(THREAD_BASIC_INFORMATION)
458 elif ThreadInformationClass in (ThreadQuerySetWin32StartAddress, ThreadAmILastThread, ThreadPriorityBoost, ThreadHideFromDebugger):
459 ThreadInformation = DWORD()
460 ThreadInformationLength = sizeof(DWORD)
461 elif ThreadInformationClass == ThreadPerformanceCount:
462 ThreadInformation = LONGLONG() # LARGE_INTEGER
463 ThreadInformationLength = sizeof(LONGLONG)
464 else:
465 raise Exception, "Unknown ThreadInformationClass, use an explicit ThreadInformationLength value instead"
466 ReturnLength = ULONG(0)
467 ntstatus = _NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ctypes.byref(ThreadInformation), ThreadInformationLength, ctypes.byref(ReturnLength))
468 if ntstatus != 0:
469 raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
470 if ThreadInformationClass == ThreadBasicInformation:
471 retval = ThreadInformation
472 elif ThreadInformationClass in (ThreadQuerySetWin32StartAddress, ThreadAmILastThread, ThreadPriorityBoost, ThreadHideFromDebugger):
473 retval = ThreadInformation.value
474 elif ThreadInformationClass == ThreadPerformanceCount:
475 retval = ThreadInformation.value
476 else:
477 retval = ThreadInformation.raw[:ReturnLength.value]
478 return retval
479
480 ZwQueryInformationThread = NtQueryInformationThread
481
482 # NTSTATUS
483 # NtQueryInformationFile(
484 # IN HANDLE FileHandle,
485 # OUT PIO_STATUS_BLOCK IoStatusBlock,
486 # OUT PVOID FileInformation,
487 # IN ULONG Length,
488 # IN FILE_INFORMATION_CLASS FileInformationClass
489 # );
491 _NtQueryInformationFile = windll.ntdll.NtQueryInformationFile
492 _NtQueryInformationFile.argtypes = [HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, DWORD]
493 _NtQueryInformationFile.restype = NTSTATUS
494 IoStatusBlock = IO_STATUS_BLOCK()
495 ntstatus = _NtQueryInformationFile(FileHandle, ctypes.byref(IoStatusBlock), ctypes.byref(FileInformation), Length, FileInformationClass)
496 if ntstatus != 0:
497 raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) )
498 return IoStatusBlock
499
500 ZwQueryInformationFile = NtQueryInformationFile
501
502 # DWORD STDCALL CsrGetProcessId (VOID);
504 _CsrGetProcessId = windll.ntdll.CsrGetProcessId
505 _CsrGetProcessId.argtypes = []
506 _CsrGetProcessId.restype = DWORD
507 return _CsrGetProcessId()
508
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Feb 12 19:47:42 2010 | http://epydoc.sourceforge.net |