Package winappdbg :: Package win32 :: Module defines
[hide private]
[frames] | no frames]

Source Code for Module winappdbg.win32.defines

  1  # Copyright (c) 2009-2010, 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  Common definitions. 
 30  """ 
 31   
 32  __revision__ = "$Id: defines.py 687 2010-06-06 16:09:38Z qvasimodo $" 
 33   
 34  import ctypes 
 35   
 36  #------------------------------------------------------------------------------ 
 37   
 38  # Some stuff from ctypes we'll be using very frequently. 
 39  sizeof      = ctypes.sizeof 
 40  SIZEOF      = ctypes.sizeof 
 41  POINTER     = ctypes.POINTER 
 42  Structure   = ctypes.Structure 
 43  Union       = ctypes.Union 
 44  WINFUNCTYPE = ctypes.WINFUNCTYPE 
 45  windll      = ctypes.windll 
 46   
 47  #------------------------------------------------------------------------------ 
 48   
 49  # XXX DEBUG 
 50  # The following code can be enabled to make the Win32 API wrappers log to 
 51  # standard output the dll and function names, the parameter values and the 
 52  # return value for each call. 
 53   
 54  ##WIN32_VERBOSE_MODE = True 
 55  WIN32_VERBOSE_MODE = False 
 56   
 57  if WIN32_VERBOSE_MODE: 
 58   
59 - class WinDllHook(object):
60 - def __getattr__(self, name):
61 if name.startswith('_'): 62 return object.__getattr__(self, name) 63 return WinFuncHook(name)
64
65 - class WinFuncHook(object):
66 - def __init__(self, name):
67 self.__name = name
68
69 - def __getattr__(self, name):
70 if name.startswith('_'): 71 return object.__getattr__(self, name) 72 return WinCallHook(self.__name, name)
73
74 - class WinCallHook(object):
75 ## def __new__(typ, dllname, funcname): 76 ## print dllname, funcname 77 ## return getattr(getattr(ctypes.windll, dllname), funcname) 78
79 - def __init__(self, dllname, funcname):
80 self.__dllname = dllname 81 self.__funcname = funcname 82 self.__func = getattr(getattr(ctypes.windll, dllname), funcname)
83
84 - def __copy_attribute(self, attribute):
85 try: 86 value = getattr(self, attribute) 87 setattr(self.__func, attribute, value) 88 except AttributeError: 89 try: 90 delattr(self.__func, attribute) 91 except AttributeError: 92 pass
93
94 - def __call__(self, *argv):
95 self.__copy_attribute('argtypes') 96 self.__copy_attribute('restype') 97 self.__copy_attribute('errcheck') 98 print "-"*10 99 print "%s ! %s %r" % (self.__dllname, self.__funcname, argv) 100 retval = self.__func(*argv) 101 print "== %r" % (retval,) 102 return retval
103 104 windll = WinDllHook() 105 106 #------------------------------------------------------------------------------ 107
108 -def winerror(e):
109 """ 110 Auxiliary function to extract the Windows error code from a C{WindowError} 111 exception instance. This is only needed for compatibility with Python 2.3. 112 113 For example, replace this code:: 114 115 try: 116 # ...some stuff... 117 except WindowsError, e: 118 if e.winerror == ERROR_ACCESS_DENIED: 119 print "Access denied!" 120 else: 121 print "Error: %s" % str(e) 122 123 With this code:: 124 125 try: 126 # ...some stuff... 127 except WindowsError, e: 128 if win32.winerror(e) == ERROR_ACCESS_DENIED: 129 print "Access denied!" 130 else: 131 print "Error: %s" % str(e) 132 133 And it'll be automagically compatible with Python 2.3. :) 134 """ 135 # Another example of the docstring being much more complex than the code :) 136 try: 137 return e.winerror # Python 2.4 and better 138 except AttributeError: 139 return e.errno # Python 2.3
140
141 -def RaiseIfZero(result, func = None, arguments = ()):
142 """ 143 Error checking for most Win32 API calls. 144 145 The function is assumed to return an integer, which is C{0} on error. 146 In that case the C{WindowsError} exception is raised. 147 """ 148 if not result: 149 raise ctypes.WinError() 150 return result
151
152 -class GuessStringType(object):
153 """ 154 Decorator that guesses the correct version (A or W) to call 155 based on the types of the strings passed as parameters. 156 157 Calls the B{ANSI} version if the only string types are ANSI. 158 159 Calls the B{Unicode} version if Unicode or mixed string types are passed. 160 161 The default if no string arguments are passed depends on the value of the 162 L{t_default} class variable. 163 164 @type fn_ansi: function 165 @ivar fn_ansi: ANSI version of the API function to call. 166 @type fn_unicode: function 167 @ivar fn_unicode: Unicode (wide) version of the API function to call. 168 169 @type t_default: type 170 @cvar t_default: Default string type to use. 171 Possible values are: 172 - type('') for ANSI 173 - type(u'') for Unicode 174 """ 175 176 # XXX TO DO 177 # Functions that do not take string parameters but return string values 178 # could use another decorator that simply chooses based on the default 179 # string type. This should still be done on runtime, NOT when importing 180 # the module, so the user can change the default string type at any time. 181 182 # ANSI and Unicode types 183 t_ansi = type('') 184 t_unicode = type(u'') 185 186 # Default is ANSI for Python 2.x 187 t_default = t_ansi 188
189 - def __init__(self, fn_ansi, fn_unicode):
190 """ 191 @type fn_ansi: function 192 @param fn_ansi: ANSI version of the API function to call. 193 @type fn_unicode: function 194 @param fn_unicode: Unicode (wide) version of the API function to call. 195 """ 196 self.fn_ansi = fn_ansi 197 self.fn_unicode = fn_unicode
198
199 - def __call__(self, *argv, **argd):
200 201 # Shortcut to self.t_ansi 202 t_ansi = self.t_ansi 203 204 # Get the types of all arguments for the function 205 v_types = [ type(item) for item in argv ] 206 v_types.extend( [ type(value) for (key, value) in argd.iteritems() ] ) 207 208 # Get the appropriate function for the default type 209 if self.t_default == t_ansi: 210 fn = self.fn_ansi 211 else: 212 fn = self.fn_unicode 213 214 # If at least one argument is a Unicode string... 215 if self.t_unicode in v_types: 216 217 # If al least one argument is an ANSI string, 218 # convert all ANSI strings to Unicode 219 if t_ansi in v_types: 220 argv = list(argv) 221 for index in xrange(len(argv)): 222 if v_types[index] == t_ansi: 223 argv[index] = unicode(argv[index]) 224 for (key, value) in argd.items(): 225 if type(value) == t_ansi: 226 argd[key] = unicode(value) 227 228 # Use the W version 229 fn = self.fn_unicode 230 231 # If at least one argument is an ANSI string, 232 # but there are no Unicode strings... 233 elif t_ansi in v_types: 234 235 # Use the A version 236 fn = self.fn_ansi 237 238 # Call the function and return the result 239 return fn(*argv, **argd)
240
241 -class MakeANSIVersion(object):
242 """ 243 Decorator that generates an ANSI version of a Unicode (wide) only API call. 244 245 @type fn: function 246 @ivar fn: Unicode (wide) version of the API function to call. 247 """ 248
249 - def __init__(self, fn):
250 """ 251 @type fn: function 252 @param fn: Unicode (wide) version of the API function to call. 253 """ 254 self.fn = fn
255
256 - def __call__(self, *argv, **argd):
257 t_ansi = type('') 258 v_types = [ type(item) for item in argv ] 259 v_types.extend( [ type(value) for (key, value) in argd.iteritems() ] ) 260 if t_ansi in v_types: 261 argv = list(argv) 262 for index in xrange(len(argv)): 263 if v_types[index] == t_ansi: 264 argv[index] = unicode(argv[index]) 265 for key, value in argd.items(): 266 if type(value) == t_ansi: 267 argd[key] = unicode(value) 268 return self.fn(*argv, **argd)
269 270 #--- Types -------------------------------------------------------------------- 271 272 # Map of basic C types to Win32 types 273 LPVOID = ctypes.c_void_p 274 CHAR = ctypes.c_char 275 WCHAR = ctypes.c_wchar 276 BYTE = ctypes.c_ubyte 277 SBYTE = ctypes.c_byte 278 WORD = ctypes.c_ushort 279 SWORD = ctypes.c_short 280 DWORD = ctypes.c_uint 281 SDWORD = ctypes.c_int 282 QWORD = ctypes.c_ulonglong 283 SQWORD = ctypes.c_longlong 284 SHORT = ctypes.c_short 285 USHORT = ctypes.c_ushort 286 INT = ctypes.c_int 287 UINT = ctypes.c_uint 288 LONG = ctypes.c_long 289 ULONG = ctypes.c_ulong 290 LONGLONG = ctypes.c_longlong 291 ULONGLONG = ctypes.c_ulonglong 292 LPSTR = ctypes.c_char_p 293 LPWSTR = ctypes.c_wchar_p 294 295 # Map size_t to SIZE_T 296 try: 297 SIZE_T = ctypes.c_size_t 298 except AttributeError: 299 # Size of a pointer 300 SIZE_T = {1:BYTE, 2:WORD, 4:DWORD, 8:QWORD}[sizeof(LPVOID)] 301 PSIZE_T = POINTER(SIZE_T) 302 303 # Not really pointers but pointer-sized integers 304 DWORD_PTR = SIZE_T 305 ULONG_PTR = SIZE_T 306 LONG_PTR = SIZE_T 307 308 # Other Win32 types, more may be added as needed 309 PVOID = LPVOID 310 PPVOID = POINTER(PVOID) 311 PSTR = LPSTR 312 PWSTR = LPWSTR 313 PCHAR = LPSTR 314 PWCHAR = LPWSTR 315 LPBYTE = POINTER(BYTE) 316 LPSBYTE = POINTER(SBYTE) 317 LPWORD = POINTER(WORD) 318 LPSWORD = POINTER(SWORD) 319 LPDWORD = POINTER(DWORD) 320 LPSDWORD = POINTER(SDWORD) 321 LPULONG = POINTER(ULONG) 322 LPLONG = POINTER(LONG) 323 PDWORD = LPDWORD 324 PDWORD_PTR = POINTER(DWORD_PTR) 325 PULONG = LPULONG 326 PLONG = LPLONG 327 BOOL = DWORD 328 BOOLEAN = BYTE 329 PBOOL = POINTER(BOOL) 330 LPBOOL = PBOOL 331 TCHAR = CHAR # XXX ANSI by default? 332 UCHAR = BYTE 333 ULONG32 = DWORD 334 DWORD32 = DWORD 335 ULONG64 = QWORD 336 DWORD64 = QWORD 337 DWORDLONG = ULONGLONG 338 LPDWORD32 = POINTER(DWORD32) 339 LPULONG32 = POINTER(ULONG32) 340 LPDWORD64 = POINTER(DWORD64) 341 LPULONG64 = POINTER(ULONG64) 342 PDWORD32 = LPDWORD32 343 PULONG32 = LPULONG32 344 PDWORD64 = LPDWORD64 345 PULONG64 = LPULONG64 346 ATOM = WORD 347 HANDLE = LPVOID 348 PHANDLE = POINTER(HANDLE) 349 LPHANDLE = PHANDLE 350 HMODULE = HANDLE 351 HINSTANCE = HANDLE 352 HTASK = HANDLE 353 HKEY = HANDLE 354 HDESK = HANDLE 355 HRSRC = HANDLE 356 HSTR = HANDLE 357 HWINSTA = HANDLE 358 HKL = HANDLE 359 HDWP = HANDLE 360 HFILE = HANDLE 361 HRESULT = LONG 362 HGLOBAL = HANDLE 363 HLOCAL = HANDLE 364 HGDIOBJ = HANDLE 365 HDC = HGDIOBJ 366 HRGN = HGDIOBJ 367 HBITMAP = HGDIOBJ 368 HPALETTE = HGDIOBJ 369 HPEN = HGDIOBJ 370 HBRUSH = HGDIOBJ 371 HMF = HGDIOBJ 372 HEMF = HGDIOBJ 373 HENHMETAFILE = HGDIOBJ 374 HMETAFILE = HGDIOBJ 375 HMETAFILEPICT = HGDIOBJ 376 HWND = HANDLE 377 NTSTATUS = LONG 378 PNTSTATUS = POINTER(NTSTATUS) 379 KAFFINITY = ULONG_PTR 380 RVA = DWORD 381 RVA64 = QWORD 382 WPARAM = DWORD 383 LPARAM = LPVOID 384 LRESULT = LPVOID 385 386 # typedef union _LARGE_INTEGER { 387 # struct { 388 # DWORD LowPart; 389 # LONG HighPart; 390 # } ; 391 # struct { 392 # DWORD LowPart; 393 # LONG HighPart; 394 # } u; 395 # LONGLONG QuadPart; 396 # } LARGE_INTEGER, 397 # *PLARGE_INTEGER; 398 399 # XXX TODO 400 401 # typedef struct _FLOAT128 { 402 # __int64 LowPart; 403 # __int64 HighPart; 404 # } FLOAT128;
405 -class FLOAT128 (Structure):
406 _fields_ = [ 407 ("LowPart", QWORD), 408 ("HighPart", QWORD), 409 ]
410 PFLOAT128 = POINTER(FLOAT128) 411 412 # typedef struct DECLSPEC_ALIGN(16) _M128A { 413 # ULONGLONG Low; 414 # LONGLONG High; 415 # } M128A, *PM128A;
416 -class M128A(Structure):
417 _fields_ = [ 418 ("Low", ULONGLONG), 419 ("High", LONGLONG), 420 ]
421 PM128A = POINTER(M128A) 422 423 #--- Constants ---------------------------------------------------------------- 424 425 NULL = None 426 INFINITE = -1 427 TRUE = 1 428 FALSE = 0 429 430 # http://blogs.msdn.com/oldnewthing/archive/2004/08/26/220873.aspx 431 ANYSIZE_ARRAY = 1 432 433 INVALID_HANDLE_VALUE = ctypes.c_void_p(-1).value #-1 #0xFFFFFFFF 434 435 MAX_MODULE_NAME32 = 255 436 MAX_PATH = 260 437 438 # Error codes 439 # TODO maybe add more error codes? 440 # if they're too many they could be pickled instead, 441 # or at the very least put in a new file 442 ERROR_SUCCESS = 0 443 ERROR_INVALID_FUNCTION = 1 444 ERROR_FILE_NOT_FOUND = 2 445 ERROR_PATH_NOT_FOUND = 3 446 ERROR_ACCESS_DENIED = 5 447 ERROR_INVALID_HANDLE = 6 448 ERROR_NOT_ENOUGH_MEMORY = 8 449 ERROR_INVALID_DRIVE = 15 450 ERROR_NO_MORE_FILES = 18 451 ERROR_BAD_LENGTH = 24 452 ERROR_HANDLE_EOF = 38 453 ERROR_HANDLE_DISK_FULL = 39 454 ERROR_NOT_SUPPORTED = 50 455 ERROR_FILE_EXISTS = 80 456 ERROR_INVALID_PARAMETER = 87 457 ERROR_BUFFER_OVERFLOW = 111 458 ERROR_DISK_FULL = 112 459 ERROR_CALL_NOT_IMPLEMENTED = 120 460 ERROR_SEM_TIMEOUT = 121 461 ERROR_INSUFFICIENT_BUFFER = 122 462 ERROR_INVALID_NAME = 123 463 ERROR_MOD_NOT_FOUND = 126 464 ERROR_PROC_NOT_FOUND = 127 465 ERROR_DIR_NOT_EMPTY = 145 466 ERROR_BAD_THREADID_ADDR = 159 467 ERROR_BAD_ARGUMENTS = 160 468 ERROR_BAD_PATHNAME = 161 469 ERROR_ALREADY_EXISTS = 183 470 ERROR_INVALID_FLAG_NUMBER = 186 471 ERROR_FILENAME_EXCED_RANGE = 206 472 WAIT_TIMEOUT = 258 473 ERROR_NO_MORE_ITEMS = 259 474 ERROR_PARTIAL_COPY = 299 475 ERROR_INVALID_ADDRESS = 487 476 ERROR_THREAD_NOT_IN_PROCESS = 566 477 ERROR_CONTROL_C_EXIT = 572 478 ERROR_UNHANDLED_EXCEPTION = 574 479 ERROR_ASSERTION_FAILURE = 668 480 ERROR_WOW_ASSERTION = 670 481 482 ERROR_DBG_EXCEPTION_NOT_HANDLED = 688 483 ERROR_DBG_REPLY_LATER = 689 484 ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE = 690 485 ERROR_DBG_TERMINATE_THREAD = 691 486 ERROR_DBG_TERMINATE_PROCESS = 692 487 ERROR_DBG_CONTROL_C = 693 488 ERROR_DBG_PRINTEXCEPTION_C = 694 489 ERROR_DBG_RIPEXCEPTION = 695 490 ERROR_DBG_CONTROL_BREAK = 696 491 ERROR_DBG_COMMAND_EXCEPTION = 697 492 ERROR_DBG_EXCEPTION_HANDLED = 766 493 ERROR_DBG_CONTINUE = 767 494 495 ERROR_NOACCESS = 998 496 497 ERROR_DEBUGGER_INACTIVE = 1284 498 499 #--- Structures --------------------------------------------------------------- 500 501 # typedef struct _LSA_UNICODE_STRING { 502 # USHORT Length; 503 # USHORT MaximumLength; 504 # PWSTR Buffer; 505 # } LSA_UNICODE_STRING, 506 # *PLSA_UNICODE_STRING, 507 # UNICODE_STRING, 508 # *PUNICODE_STRING;
509 -class UNICODE_STRING(Structure):
510 _fields_ = [ 511 ("Length", USHORT), 512 ("MaximumLength", USHORT), 513 ("Buffer", PVOID), 514 ]
515 516 # From MSDN: 517 # 518 # typedef struct _GUID { 519 # DWORD Data1; 520 # WORD Data2; 521 # WORD Data3; 522 # BYTE Data4[8]; 523 # } GUID;
524 -class GUID(Structure):
525 _fields_ = [ 526 ("Data1", DWORD), 527 ("Data2", WORD), 528 ("Data3", WORD), 529 ("Data4", BYTE * 8), 530 ]
531 532 # From MSDN: 533 # 534 # typedef struct _LIST_ENTRY { 535 # struct _LIST_ENTRY *Flink; 536 # struct _LIST_ENTRY *Blink; 537 # } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
538 -class LIST_ENTRY(Structure):
539 pass
540 LIST_ENTRY._fields_ = [ 541 ("Flink", PVOID), # POINTER(LIST_ENTRY) 542 ("Blink", PVOID), # POINTER(LIST_ENTRY) 543 ] 544