1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """
32 CONTEXT structure for amd64.
33 """
34
35 __revision__ = "$Id: context_amd64.py 1299 2013-12-20 09:30:55Z qvasimodo $"
36
37 from defines import *
38 from version import ARCH_AMD64
39 import context_i386
40
41
42
43 _all = None
44 _all = set(vars().keys())
45
46
47
48
49
50
51
52 EXCEPTION_READ_FAULT = 0
53 EXCEPTION_WRITE_FAULT = 1
54 EXCEPTION_EXECUTE_FAULT = 8
55
56 CONTEXT_AMD64 = 0x00100000
57
58 CONTEXT_CONTROL = (CONTEXT_AMD64 | 0x1L)
59 CONTEXT_INTEGER = (CONTEXT_AMD64 | 0x2L)
60 CONTEXT_SEGMENTS = (CONTEXT_AMD64 | 0x4L)
61 CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | 0x8L)
62 CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | 0x10L)
63
64 CONTEXT_MMX_REGISTERS = CONTEXT_FLOATING_POINT
65
66 CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
67
68 CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \
69 CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
70
71 CONTEXT_EXCEPTION_ACTIVE = 0x8000000
72 CONTEXT_SERVICE_ACTIVE = 0x10000000
73 CONTEXT_EXCEPTION_REQUEST = 0x40000000
74 CONTEXT_EXCEPTION_REPORTING = 0x80000000
75
76 INITIAL_MXCSR = 0x1f80
77 INITIAL_FPCSR = 0x027f
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 -class 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
119 raise NotImplementedError()
120
131
132 LEGACY_SAVE_AREA_LENGTH = sizeof(XMM_SAVE_AREA32)
133
134 PXMM_SAVE_AREA32 = ctypes.POINTER(XMM_SAVE_AREA32)
135 LPXMM_SAVE_AREA32 = PXMM_SAVE_AREA32
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 -class _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
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
325 _fields_ = [
326 ('flt', XMM_SAVE_AREA32),
327 ('xmm', _CONTEXT_FLTSAVE_STRUCT),
328 ]
329
330 - def from_dict(self):
331 raise NotImplementedError()
332
334 d = dict()
335 d['flt'] = self.flt.to_dict()
336 d['xmm'] = self.xmm.to_dict()
337 return d
338
339 -class CONTEXT(Structure):
340 arch = ARCH_AMD64
341
342 _pack_ = 16
343 _fields_ = [
344
345
346 ('P1Home', DWORD64),
347 ('P2Home', DWORD64),
348 ('P3Home', DWORD64),
349 ('P4Home', DWORD64),
350 ('P5Home', DWORD64),
351 ('P6Home', DWORD64),
352
353
354 ('ContextFlags', DWORD),
355 ('MxCsr', DWORD),
356
357
358 ('SegCs', WORD),
359 ('SegDs', WORD),
360 ('SegEs', WORD),
361 ('SegFs', WORD),
362 ('SegGs', WORD),
363 ('SegSs', WORD),
364 ('EFlags', DWORD),
365
366
367 ('Dr0', DWORD64),
368 ('Dr1', DWORD64),
369 ('Dr2', DWORD64),
370 ('Dr3', DWORD64),
371 ('Dr6', DWORD64),
372 ('Dr7', DWORD64),
373
374
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
393 ('Rip', DWORD64),
394
395
396 ('FltSave', _CONTEXT_FLTSAVE_UNION),
397
398
399 ('VectorRegister', M128A * 26),
400 ('VectorControl', DWORD64),
401
402
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
423
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
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
495 PCONTEXT = ctypes.POINTER(CONTEXT)
496 LPCONTEXT = PCONTEXT
497
498 -class Context(dict):
499 """
500 Register context dictionary for the amd64 architecture.
501 """
502
503 arch = CONTEXT.arch
504
505 - def __get_pc(self):
507 - def __set_pc(self, value):
509 pc = property(__get_pc, __set_pc)
510
511 - def __get_sp(self):
513 - def __set_sp(self, value):
515 sp = property(__get_sp, __set_sp)
516
517 - def __get_fp(self):
519 - def __set_fp(self, value):
521 fp = property(__get_fp, __set_fp)
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551 -class _LDT_ENTRY_BYTES_(Structure):
552 _pack_ = 1
553 _fields_ = [
554 ('BaseMid', BYTE),
555 ('Flags1', BYTE),
556 ('Flags2', BYTE),
557 ('BaseHi', BYTE),
558 ]
559
560 -class _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
576 _pack_ = 1
577 _fields_ = [
578 ('Bytes', _LDT_ENTRY_BYTES_),
579 ('Bits', _LDT_ENTRY_BITS_),
580 ]
581
582 -class LDT_ENTRY(Structure):
583 _pack_ = 1
584 _fields_ = [
585 ('LimitLow', WORD),
586 ('BaseLow', WORD),
587 ('HighWord', _LDT_ENTRY_HIGHWORD_),
588 ]
589
590 PLDT_ENTRY = POINTER(LDT_ENTRY)
591 LPLDT_ENTRY = PLDT_ENTRY
592
593
594
595
596 WOW64_CS32 = 0x23
597
598 WOW64_CONTEXT_i386 = 0x00010000L
599 WOW64_CONTEXT_i486 = 0x00010000L
600
601 WOW64_CONTEXT_CONTROL = (WOW64_CONTEXT_i386 | 0x00000001L)
602 WOW64_CONTEXT_INTEGER = (WOW64_CONTEXT_i386 | 0x00000002L)
603 WOW64_CONTEXT_SEGMENTS = (WOW64_CONTEXT_i386 | 0x00000004L)
604 WOW64_CONTEXT_FLOATING_POINT = (WOW64_CONTEXT_i386 | 0x00000008L)
605 WOW64_CONTEXT_DEBUG_REGISTERS = (WOW64_CONTEXT_i386 | 0x00000010L)
606 WOW64_CONTEXT_EXTENDED_REGISTERS = (WOW64_CONTEXT_i386 | 0x00000020L)
607
608 WOW64_CONTEXT_FULL = (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS)
609 WOW64_CONTEXT_ALL = (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS | WOW64_CONTEXT_FLOATING_POINT | WOW64_CONTEXT_DEBUG_REGISTERS | WOW64_CONTEXT_EXTENDED_REGISTERS)
610
611 WOW64_SIZE_OF_80387_REGISTERS = 80
612 WOW64_MAXIMUM_SUPPORTED_EXTENSION = 512
616
617 -class WOW64_CONTEXT (context_i386.CONTEXT):
619
620 -class WOW64_LDT_ENTRY (context_i386.LDT_ENTRY):
622
623 PWOW64_FLOATING_SAVE_AREA = POINTER(WOW64_FLOATING_SAVE_AREA)
624 PWOW64_CONTEXT = POINTER(WOW64_CONTEXT)
625 PWOW64_LDT_ENTRY = POINTER(WOW64_LDT_ENTRY)
626
627
628
629
630
631
632
633
634 -def 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
645
646
647
648 -def 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
664
665
666
667 -def 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
678
679
680
681
682 -def 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
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
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
719
720
721
722
723
724
725 -def 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
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
742
743
744
745 -def Wow64SetThreadContext(hThread, lpContext):
746 _Wow64SetThreadContext = windll.kernel32.Wow64SetThreadContext
747 _Wow64SetThreadContext.argtypes = [HANDLE, PWOW64_CONTEXT]
748 _Wow64SetThreadContext.restype = bool
749 _Wow64SetThreadContext.errcheck = RaiseIfZero
750
751
752
753 if isinstance(lpContext, dict):
754 lpContext = WOW64_CONTEXT.from_dict(lpContext)
755 _Wow64SetThreadContext(hThread, byref(lpContext))
756
757
758
759 _all = set(vars().keys()).difference(_all)
760 __all__ = [_x for _x in _all if not _x.startswith('_')]
761 __all__.sort()
762
763