1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2009-2014, Mario Vilas 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, 11# this list of conditions and the following disclaimer. 12# * Redistributions in binary form must reproduce the above copyright 13# notice,this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# * Neither the name of the copyright holder nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29# POSSIBILITY OF SUCH DAMAGE. 30 31""" 32CONTEXT structure for amd64. 33""" 34 35__revision__ = "$Id$" 36 37from winappdbg.win32.defines import * 38from winappdbg.win32.version import ARCH_AMD64 39from winappdbg.win32 import context_i386 40 41#============================================================================== 42# This is used later on to calculate the list of exported symbols. 43_all = None 44_all = set(vars().keys()) 45#============================================================================== 46 47#--- CONTEXT structures and constants ----------------------------------------- 48 49# The following values specify the type of access in the first parameter 50# of the exception record when the exception code specifies an access 51# violation. 52EXCEPTION_READ_FAULT = 0 # exception caused by a read 53EXCEPTION_WRITE_FAULT = 1 # exception caused by a write 54EXCEPTION_EXECUTE_FAULT = 8 # exception caused by an instruction fetch 55 56CONTEXT_AMD64 = 0x00100000 57 58CONTEXT_CONTROL = (CONTEXT_AMD64 | long(0x1)) 59CONTEXT_INTEGER = (CONTEXT_AMD64 | long(0x2)) 60CONTEXT_SEGMENTS = (CONTEXT_AMD64 | long(0x4)) 61CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | long(0x8)) 62CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | long(0x10)) 63 64CONTEXT_MMX_REGISTERS = CONTEXT_FLOATING_POINT 65 66CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) 67 68CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ 69 CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) 70 71CONTEXT_EXCEPTION_ACTIVE = 0x8000000 72CONTEXT_SERVICE_ACTIVE = 0x10000000 73CONTEXT_EXCEPTION_REQUEST = 0x40000000 74CONTEXT_EXCEPTION_REPORTING = 0x80000000 75 76INITIAL_MXCSR = 0x1f80 # initial MXCSR value 77INITIAL_FPCSR = 0x027f # initial FPCSR value 78 79# typedef struct _XMM_SAVE_AREA32 { 80# WORD ControlWord; 81# WORD StatusWord; 82# BYTE TagWord; 83# BYTE Reserved1; 84# WORD ErrorOpcode; 85# DWORD ErrorOffset; 86# WORD ErrorSelector; 87# WORD Reserved2; 88# DWORD DataOffset; 89# WORD DataSelector; 90# WORD Reserved3; 91# DWORD MxCsr; 92# DWORD MxCsr_Mask; 93# M128A FloatRegisters[8]; 94# M128A XmmRegisters[16]; 95# BYTE Reserved4[96]; 96# } XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; 97class XMM_SAVE_AREA32(Structure): 98 _pack_ = 1 99 _fields_ = [ 100 ('ControlWord', WORD), 101 ('StatusWord', WORD), 102 ('TagWord', BYTE), 103 ('Reserved1', BYTE), 104 ('ErrorOpcode', WORD), 105 ('ErrorOffset', DWORD), 106 ('ErrorSelector', WORD), 107 ('Reserved2', WORD), 108 ('DataOffset', DWORD), 109 ('DataSelector', WORD), 110 ('Reserved3', WORD), 111 ('MxCsr', DWORD), 112 ('MxCsr_Mask', DWORD), 113 ('FloatRegisters', M128A * 8), 114 ('XmmRegisters', M128A * 16), 115 ('Reserved4', BYTE * 96), 116 ] 117 118 def from_dict(self): 119 raise NotImplementedError() 120 121 def to_dict(self): 122 d = dict() 123 for name, type in self._fields_: 124 if name in ('FloatRegisters', 'XmmRegisters'): 125 d[name] = tuple([ (x.LowPart + (x.HighPart << 64)) for x in getattr(self, name) ]) 126 elif name == 'Reserved4': 127 d[name] = tuple([ chr(x) for x in getattr(self, name) ]) 128 else: 129 d[name] = getattr(self, name) 130 return d 131 132LEGACY_SAVE_AREA_LENGTH = sizeof(XMM_SAVE_AREA32) 133 134PXMM_SAVE_AREA32 = ctypes.POINTER(XMM_SAVE_AREA32) 135LPXMM_SAVE_AREA32 = PXMM_SAVE_AREA32 136 137# // 138# // Context Frame 139# // 140# // This frame has a several purposes: 1) it is used as an argument to 141# // NtContinue, 2) is is used to constuct a call frame for APC delivery, 142# // and 3) it is used in the user level thread creation routines. 143# // 144# // 145# // The flags field within this record controls the contents of a CONTEXT 146# // record. 147# // 148# // If the context record is used as an input parameter, then for each 149# // portion of the context record controlled by a flag whose value is 150# // set, it is assumed that that portion of the context record contains 151# // valid context. If the context record is being used to modify a threads 152# // context, then only that portion of the threads context is modified. 153# // 154# // If the context record is used as an output parameter to capture the 155# // context of a thread, then only those portions of the thread's context 156# // corresponding to set flags will be returned. 157# // 158# // CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags. 159# // 160# // CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15. 161# // 162# // CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs. 163# // 164# // CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7. 165# // 166# // CONTEXT_MMX_REGISTERS specifies the floating point and extended registers 167# // Mm0/St0-Mm7/St7 and Xmm0-Xmm15). 168# // 169# 170# typedef struct DECLSPEC_ALIGN(16) _CONTEXT { 171# 172# // 173# // Register parameter home addresses. 174# // 175# // N.B. These fields are for convience - they could be used to extend the 176# // context record in the future. 177# // 178# 179# DWORD64 P1Home; 180# DWORD64 P2Home; 181# DWORD64 P3Home; 182# DWORD64 P4Home; 183# DWORD64 P5Home; 184# DWORD64 P6Home; 185# 186# // 187# // Control flags. 188# // 189# 190# DWORD ContextFlags; 191# DWORD MxCsr; 192# 193# // 194# // Segment Registers and processor flags. 195# // 196# 197# WORD SegCs; 198# WORD SegDs; 199# WORD SegEs; 200# WORD SegFs; 201# WORD SegGs; 202# WORD SegSs; 203# DWORD EFlags; 204# 205# // 206# // Debug registers 207# // 208# 209# DWORD64 Dr0; 210# DWORD64 Dr1; 211# DWORD64 Dr2; 212# DWORD64 Dr3; 213# DWORD64 Dr6; 214# DWORD64 Dr7; 215# 216# // 217# // Integer registers. 218# // 219# 220# DWORD64 Rax; 221# DWORD64 Rcx; 222# DWORD64 Rdx; 223# DWORD64 Rbx; 224# DWORD64 Rsp; 225# DWORD64 Rbp; 226# DWORD64 Rsi; 227# DWORD64 Rdi; 228# DWORD64 R8; 229# DWORD64 R9; 230# DWORD64 R10; 231# DWORD64 R11; 232# DWORD64 R12; 233# DWORD64 R13; 234# DWORD64 R14; 235# DWORD64 R15; 236# 237# // 238# // Program counter. 239# // 240# 241# DWORD64 Rip; 242# 243# // 244# // Floating point state. 245# // 246# 247# union { 248# XMM_SAVE_AREA32 FltSave; 249# struct { 250# M128A Header[2]; 251# M128A Legacy[8]; 252# M128A Xmm0; 253# M128A Xmm1; 254# M128A Xmm2; 255# M128A Xmm3; 256# M128A Xmm4; 257# M128A Xmm5; 258# M128A Xmm6; 259# M128A Xmm7; 260# M128A Xmm8; 261# M128A Xmm9; 262# M128A Xmm10; 263# M128A Xmm11; 264# M128A Xmm12; 265# M128A Xmm13; 266# M128A Xmm14; 267# M128A Xmm15; 268# }; 269# }; 270# 271# // 272# // Vector registers. 273# // 274# 275# M128A VectorRegister[26]; 276# DWORD64 VectorControl; 277# 278# // 279# // Special debug control registers. 280# // 281# 282# DWORD64 DebugControl; 283# DWORD64 LastBranchToRip; 284# DWORD64 LastBranchFromRip; 285# DWORD64 LastExceptionToRip; 286# DWORD64 LastExceptionFromRip; 287# } CONTEXT, *PCONTEXT; 288 289class _CONTEXT_FLTSAVE_STRUCT(Structure): 290 _fields_ = [ 291 ('Header', M128A * 2), 292 ('Legacy', M128A * 8), 293 ('Xmm0', M128A), 294 ('Xmm1', M128A), 295 ('Xmm2', M128A), 296 ('Xmm3', M128A), 297 ('Xmm4', M128A), 298 ('Xmm5', M128A), 299 ('Xmm6', M128A), 300 ('Xmm7', M128A), 301 ('Xmm8', M128A), 302 ('Xmm9', M128A), 303 ('Xmm10', M128A), 304 ('Xmm11', M128A), 305 ('Xmm12', M128A), 306 ('Xmm13', M128A), 307 ('Xmm14', M128A), 308 ('Xmm15', M128A), 309 ] 310 311 def from_dict(self): 312 raise NotImplementedError() 313 314 def to_dict(self): 315 d = dict() 316 for name, type in self._fields_: 317 if name in ('Header', 'Legacy'): 318 d[name] = tuple([ (x.Low + (x.High << 64)) for x in getattr(self, name) ]) 319 else: 320 x = getattr(self, name) 321 d[name] = x.Low + (x.High << 64) 322 return d 323 324class _CONTEXT_FLTSAVE_UNION(Union): 325 _fields_ = [ 326 ('flt', XMM_SAVE_AREA32), 327 ('xmm', _CONTEXT_FLTSAVE_STRUCT), 328 ] 329 330 def from_dict(self): 331 raise NotImplementedError() 332 333 def to_dict(self): 334 d = dict() 335 d['flt'] = self.flt.to_dict() 336 d['xmm'] = self.xmm.to_dict() 337 return d 338 339class CONTEXT(Structure): 340 arch = ARCH_AMD64 341 342 _pack_ = 16 343 _fields_ = [ 344 345 # Register parameter home addresses. 346 ('P1Home', DWORD64), 347 ('P2Home', DWORD64), 348 ('P3Home', DWORD64), 349 ('P4Home', DWORD64), 350 ('P5Home', DWORD64), 351 ('P6Home', DWORD64), 352 353 # Control flags. 354 ('ContextFlags', DWORD), 355 ('MxCsr', DWORD), 356 357 # Segment Registers and processor flags. 358 ('SegCs', WORD), 359 ('SegDs', WORD), 360 ('SegEs', WORD), 361 ('SegFs', WORD), 362 ('SegGs', WORD), 363 ('SegSs', WORD), 364 ('EFlags', DWORD), 365 366 # Debug registers. 367 ('Dr0', DWORD64), 368 ('Dr1', DWORD64), 369 ('Dr2', DWORD64), 370 ('Dr3', DWORD64), 371 ('Dr6', DWORD64), 372 ('Dr7', DWORD64), 373 374 # Integer registers. 375 ('Rax', DWORD64), 376 ('Rcx', DWORD64), 377 ('Rdx', DWORD64), 378 ('Rbx', DWORD64), 379 ('Rsp', DWORD64), 380 ('Rbp', DWORD64), 381 ('Rsi', DWORD64), 382 ('Rdi', DWORD64), 383 ('R8', DWORD64), 384 ('R9', DWORD64), 385 ('R10', DWORD64), 386 ('R11', DWORD64), 387 ('R12', DWORD64), 388 ('R13', DWORD64), 389 ('R14', DWORD64), 390 ('R15', DWORD64), 391 392 # Program counter. 393 ('Rip', DWORD64), 394 395 # Floating point state. 396 ('FltSave', _CONTEXT_FLTSAVE_UNION), 397 398 # Vector registers. 399 ('VectorRegister', M128A * 26), 400 ('VectorControl', DWORD64), 401 402 # Special debug control registers. 403 ('DebugControl', DWORD64), 404 ('LastBranchToRip', DWORD64), 405 ('LastBranchFromRip', DWORD64), 406 ('LastExceptionToRip', DWORD64), 407 ('LastExceptionFromRip', DWORD64), 408 ] 409 410 _others = ('P1Home', 'P2Home', 'P3Home', 'P4Home', 'P5Home', 'P6Home', \ 411 'MxCsr', 'VectorRegister', 'VectorControl') 412 _control = ('SegSs', 'Rsp', 'SegCs', 'Rip', 'EFlags') 413 _integer = ('Rax', 'Rcx', 'Rdx', 'Rbx', 'Rsp', 'Rbp', 'Rsi', 'Rdi', \ 414 'R8', 'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15') 415 _segments = ('SegDs', 'SegEs', 'SegFs', 'SegGs') 416 _debug = ('Dr0', 'Dr1', 'Dr2', 'Dr3', 'Dr6', 'Dr7', \ 417 'DebugControl', 'LastBranchToRip', 'LastBranchFromRip', \ 418 'LastExceptionToRip', 'LastExceptionFromRip') 419 _mmx = ('Xmm0', 'Xmm1', 'Xmm2', 'Xmm3', 'Xmm4', 'Xmm5', 'Xmm6', 'Xmm7', \ 420 'Xmm8', 'Xmm9', 'Xmm10', 'Xmm11', 'Xmm12', 'Xmm13', 'Xmm14', 'Xmm15') 421 422 # XXX TODO 423 # Convert VectorRegister and Xmm0-Xmm15 to pure Python types! 424 425 @classmethod 426 def from_dict(cls, ctx): 427 'Instance a new structure from a Python native type.' 428 ctx = Context(ctx) 429 s = cls() 430 ContextFlags = ctx['ContextFlags'] 431 s.ContextFlags = ContextFlags 432 for key in cls._others: 433 if key != 'VectorRegister': 434 setattr(s, key, ctx[key]) 435 else: 436 w = ctx[key] 437 v = (M128A * len(w))() 438 i = 0 439 for x in w: 440 y = M128A() 441 y.High = x >> 64 442 y.Low = x - (x >> 64) 443 v[i] = y 444 i += 1 445 setattr(s, key, v) 446 if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL: 447 for key in cls._control: 448 setattr(s, key, ctx[key]) 449 if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER: 450 for key in cls._integer: 451 setattr(s, key, ctx[key]) 452 if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS: 453 for key in cls._segments: 454 setattr(s, key, ctx[key]) 455 if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS: 456 for key in cls._debug: 457 setattr(s, key, ctx[key]) 458 if (ContextFlags & CONTEXT_MMX_REGISTERS) == CONTEXT_MMX_REGISTERS: 459 xmm = s.FltSave.xmm 460 for key in cls._mmx: 461 y = M128A() 462 y.High = x >> 64 463 y.Low = x - (x >> 64) 464 setattr(xmm, key, y) 465 return s 466 467 def to_dict(self): 468 'Convert a structure into a Python dictionary.' 469 ctx = Context() 470 ContextFlags = self.ContextFlags 471 ctx['ContextFlags'] = ContextFlags 472 for key in self._others: 473 if key != 'VectorRegister': 474 ctx[key] = getattr(self, key) 475 else: 476 ctx[key] = tuple([ (x.Low + (x.High << 64)) for x in getattr(self, key) ]) 477 if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL: 478 for key in self._control: 479 ctx[key] = getattr(self, key) 480 if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER: 481 for key in self._integer: 482 ctx[key] = getattr(self, key) 483 if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS: 484 for key in self._segments: 485 ctx[key] = getattr(self, key) 486 if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS: 487 for key in self._debug: 488 ctx[key] = getattr(self, key) 489 if (ContextFlags & CONTEXT_MMX_REGISTERS) == CONTEXT_MMX_REGISTERS: 490 xmm = self.FltSave.xmm.to_dict() 491 for key in self._mmx: 492 ctx[key] = xmm.get(key) 493 return ctx 494 495PCONTEXT = ctypes.POINTER(CONTEXT) 496LPCONTEXT = PCONTEXT 497 498class Context(dict): 499 """ 500 Register context dictionary for the amd64 architecture. 501 """ 502 503 arch = CONTEXT.arch 504 505 def __get_pc(self): 506 return self['Rip'] 507 def __set_pc(self, value): 508 self['Rip'] = value 509 pc = property(__get_pc, __set_pc) 510 511 def __get_sp(self): 512 return self['Rsp'] 513 def __set_sp(self, value): 514 self['Rsp'] = value 515 sp = property(__get_sp, __set_sp) 516 517 def __get_fp(self): 518 return self['Rbp'] 519 def __set_fp(self, value): 520 self['Rbp'] = value 521 fp = property(__get_fp, __set_fp) 522 523#--- LDT_ENTRY structure ------------------------------------------------------ 524 525# typedef struct _LDT_ENTRY { 526# WORD LimitLow; 527# WORD BaseLow; 528# union { 529# struct { 530# BYTE BaseMid; 531# BYTE Flags1; 532# BYTE Flags2; 533# BYTE BaseHi; 534# } Bytes; 535# struct { 536# DWORD BaseMid :8; 537# DWORD Type :5; 538# DWORD Dpl :2; 539# DWORD Pres :1; 540# DWORD LimitHi :4; 541# DWORD Sys :1; 542# DWORD Reserved_0 :1; 543# DWORD Default_Big :1; 544# DWORD Granularity :1; 545# DWORD BaseHi :8; 546# } Bits; 547# } HighWord; 548# } LDT_ENTRY, 549# *PLDT_ENTRY; 550 551class _LDT_ENTRY_BYTES_(Structure): 552 _pack_ = 1 553 _fields_ = [ 554 ('BaseMid', BYTE), 555 ('Flags1', BYTE), 556 ('Flags2', BYTE), 557 ('BaseHi', BYTE), 558 ] 559 560class _LDT_ENTRY_BITS_(Structure): 561 _pack_ = 1 562 _fields_ = [ 563 ('BaseMid', DWORD, 8), 564 ('Type', DWORD, 5), 565 ('Dpl', DWORD, 2), 566 ('Pres', DWORD, 1), 567 ('LimitHi', DWORD, 4), 568 ('Sys', DWORD, 1), 569 ('Reserved_0', DWORD, 1), 570 ('Default_Big', DWORD, 1), 571 ('Granularity', DWORD, 1), 572 ('BaseHi', DWORD, 8), 573 ] 574 575class _LDT_ENTRY_HIGHWORD_(Union): 576 _pack_ = 1 577 _fields_ = [ 578 ('Bytes', _LDT_ENTRY_BYTES_), 579 ('Bits', _LDT_ENTRY_BITS_), 580 ] 581 582class LDT_ENTRY(Structure): 583 _pack_ = 1 584 _fields_ = [ 585 ('LimitLow', WORD), 586 ('BaseLow', WORD), 587 ('HighWord', _LDT_ENTRY_HIGHWORD_), 588 ] 589 590PLDT_ENTRY = POINTER(LDT_ENTRY) 591LPLDT_ENTRY = PLDT_ENTRY 592 593#--- WOW64 CONTEXT structure and constants ------------------------------------ 594 595# Value of SegCs in a Wow64 thread when running in 32 bits mode 596WOW64_CS32 = 0x23 597 598WOW64_CONTEXT_i386 = long(0x00010000) 599WOW64_CONTEXT_i486 = long(0x00010000) 600 601WOW64_CONTEXT_CONTROL = (WOW64_CONTEXT_i386 | long(0x00000001)) 602WOW64_CONTEXT_INTEGER = (WOW64_CONTEXT_i386 | long(0x00000002)) 603WOW64_CONTEXT_SEGMENTS = (WOW64_CONTEXT_i386 | long(0x00000004)) 604WOW64_CONTEXT_FLOATING_POINT = (WOW64_CONTEXT_i386 | long(0x00000008)) 605WOW64_CONTEXT_DEBUG_REGISTERS = (WOW64_CONTEXT_i386 | long(0x00000010)) 606WOW64_CONTEXT_EXTENDED_REGISTERS = (WOW64_CONTEXT_i386 | long(0x00000020)) 607 608WOW64_CONTEXT_FULL = (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS) 609WOW64_CONTEXT_ALL = (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS | WOW64_CONTEXT_FLOATING_POINT | WOW64_CONTEXT_DEBUG_REGISTERS | WOW64_CONTEXT_EXTENDED_REGISTERS) 610 611WOW64_SIZE_OF_80387_REGISTERS = 80 612WOW64_MAXIMUM_SUPPORTED_EXTENSION = 512 613 614class WOW64_FLOATING_SAVE_AREA (context_i386.FLOATING_SAVE_AREA): 615 pass 616 617class WOW64_CONTEXT (context_i386.CONTEXT): 618 pass 619 620class WOW64_LDT_ENTRY (context_i386.LDT_ENTRY): 621 pass 622 623PWOW64_FLOATING_SAVE_AREA = POINTER(WOW64_FLOATING_SAVE_AREA) 624PWOW64_CONTEXT = POINTER(WOW64_CONTEXT) 625PWOW64_LDT_ENTRY = POINTER(WOW64_LDT_ENTRY) 626 627############################################################################### 628 629# BOOL WINAPI GetThreadSelectorEntry( 630# __in HANDLE hThread, 631# __in DWORD dwSelector, 632# __out LPLDT_ENTRY lpSelectorEntry 633# ); 634def GetThreadSelectorEntry(hThread, dwSelector): 635 _GetThreadSelectorEntry = windll.kernel32.GetThreadSelectorEntry 636 _GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, LPLDT_ENTRY] 637 _GetThreadSelectorEntry.restype = bool 638 _GetThreadSelectorEntry.errcheck = RaiseIfZero 639 640 ldt = LDT_ENTRY() 641 _GetThreadSelectorEntry(hThread, dwSelector, byref(ldt)) 642 return ldt 643 644# BOOL WINAPI GetThreadContext( 645# __in HANDLE hThread, 646# __inout LPCONTEXT lpContext 647# ); 648def GetThreadContext(hThread, ContextFlags = None, raw = False): 649 _GetThreadContext = windll.kernel32.GetThreadContext 650 _GetThreadContext.argtypes = [HANDLE, LPCONTEXT] 651 _GetThreadContext.restype = bool 652 _GetThreadContext.errcheck = RaiseIfZero 653 654 if ContextFlags is None: 655 ContextFlags = CONTEXT_ALL | CONTEXT_AMD64 656 Context = CONTEXT() 657 Context.ContextFlags = ContextFlags 658 _GetThreadContext(hThread, byref(Context)) 659 if raw: 660 return Context 661 return Context.to_dict() 662 663# BOOL WINAPI SetThreadContext( 664# __in HANDLE hThread, 665# __in const CONTEXT* lpContext 666# ); 667def SetThreadContext(hThread, lpContext): 668 _SetThreadContext = windll.kernel32.SetThreadContext 669 _SetThreadContext.argtypes = [HANDLE, LPCONTEXT] 670 _SetThreadContext.restype = bool 671 _SetThreadContext.errcheck = RaiseIfZero 672 673 if isinstance(lpContext, dict): 674 lpContext = CONTEXT.from_dict(lpContext) 675 _SetThreadContext(hThread, byref(lpContext)) 676 677# BOOL Wow64GetThreadSelectorEntry( 678# __in HANDLE hThread, 679# __in DWORD dwSelector, 680# __out PWOW64_LDT_ENTRY lpSelectorEntry 681# ); 682def Wow64GetThreadSelectorEntry(hThread, dwSelector): 683 _Wow64GetThreadSelectorEntry = windll.kernel32.Wow64GetThreadSelectorEntry 684 _Wow64GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, PWOW64_LDT_ENTRY] 685 _Wow64GetThreadSelectorEntry.restype = bool 686 _Wow64GetThreadSelectorEntry.errcheck = RaiseIfZero 687 688 lpSelectorEntry = WOW64_LDT_ENTRY() 689 _Wow64GetThreadSelectorEntry(hThread, dwSelector, byref(lpSelectorEntry)) 690 return lpSelectorEntry 691 692# DWORD WINAPI Wow64ResumeThread( 693# __in HANDLE hThread 694# ); 695def Wow64ResumeThread(hThread): 696 _Wow64ResumeThread = windll.kernel32.Wow64ResumeThread 697 _Wow64ResumeThread.argtypes = [HANDLE] 698 _Wow64ResumeThread.restype = DWORD 699 700 previousCount = _Wow64ResumeThread(hThread) 701 if previousCount == DWORD(-1).value: 702 raise ctypes.WinError() 703 return previousCount 704 705# DWORD WINAPI Wow64SuspendThread( 706# __in HANDLE hThread 707# ); 708def Wow64SuspendThread(hThread): 709 _Wow64SuspendThread = windll.kernel32.Wow64SuspendThread 710 _Wow64SuspendThread.argtypes = [HANDLE] 711 _Wow64SuspendThread.restype = DWORD 712 713 previousCount = _Wow64SuspendThread(hThread) 714 if previousCount == DWORD(-1).value: 715 raise ctypes.WinError() 716 return previousCount 717 718# XXX TODO Use this http://www.nynaeve.net/Code/GetThreadWow64Context.cpp 719# Also see http://www.woodmann.com/forum/archive/index.php/t-11162.html 720 721# BOOL WINAPI Wow64GetThreadContext( 722# __in HANDLE hThread, 723# __inout PWOW64_CONTEXT lpContext 724# ); 725def Wow64GetThreadContext(hThread, ContextFlags = None): 726 _Wow64GetThreadContext = windll.kernel32.Wow64GetThreadContext 727 _Wow64GetThreadContext.argtypes = [HANDLE, PWOW64_CONTEXT] 728 _Wow64GetThreadContext.restype = bool 729 _Wow64GetThreadContext.errcheck = RaiseIfZero 730 731 # XXX doesn't exist in XP 64 bits 732 733 Context = WOW64_CONTEXT() 734 if ContextFlags is None: 735 Context.ContextFlags = WOW64_CONTEXT_ALL | WOW64_CONTEXT_i386 736 else: 737 Context.ContextFlags = ContextFlags 738 _Wow64GetThreadContext(hThread, byref(Context)) 739 return Context.to_dict() 740 741# BOOL WINAPI Wow64SetThreadContext( 742# __in HANDLE hThread, 743# __in const WOW64_CONTEXT *lpContext 744# ); 745def Wow64SetThreadContext(hThread, lpContext): 746 _Wow64SetThreadContext = windll.kernel32.Wow64SetThreadContext 747 _Wow64SetThreadContext.argtypes = [HANDLE, PWOW64_CONTEXT] 748 _Wow64SetThreadContext.restype = bool 749 _Wow64SetThreadContext.errcheck = RaiseIfZero 750 751 # XXX doesn't exist in XP 64 bits 752 753 if isinstance(lpContext, dict): 754 lpContext = WOW64_CONTEXT.from_dict(lpContext) 755 _Wow64SetThreadContext(hThread, byref(lpContext)) 756 757#============================================================================== 758# This calculates the list of exported symbols. 759_all = set(vars().keys()).difference(_all) 760__all__ = [_x for _x in _all if not _x.startswith('_')] 761__all__.sort() 762#============================================================================== 763