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 Debugging API wrappers in ctypes.
30
31 @see: U{http://apps.sourceforge.net/trac/winappdbg/wiki/Win32APIWrappers}
32 """
33
34 __revision__ = "$Id: context_amd64.py 382 2009-08-25 21:20:54Z QvasiModo $"
35
36 from defines import *
37
38
39
40
41 EXCEPTION_READ_FAULT = 0
42 EXCEPTION_WRITE_FAULT = 1
43 EXCEPTION_EXECUTE_FAULT = 8
44
45 CONTEXT_AMD64 = 0x00100000
46
47 CONTEXT_CONTROL = (CONTEXT_AMD64 | 0x1L)
48 CONTEXT_INTEGER = (CONTEXT_AMD64 | 0x2L)
49 CONTEXT_SEGMENTS = (CONTEXT_AMD64 | 0x4L)
50 CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | 0x8L)
51 CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | 0x10L)
52
53 CONTEXT_MMX_REGISTERS = CONTEXT_FLOATING_POINT
54
55 CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
56
57 CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \
58 CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
59
60 CONTEXT_EXCEPTION_ACTIVE = 0x8000000
61 CONTEXT_SERVICE_ACTIVE = 0x10000000
62 CONTEXT_EXCEPTION_REQUEST = 0x40000000
63 CONTEXT_EXCEPTION_REPORTING = 0x80000000
64
65 INITIAL_MXCSR = 0x1f80
66 INITIAL_FPCSR = 0x027f
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 -class XMM_SAVE_AREA32(Structure):
87 _pack_ = 1
88 _fields_ = [
89 ('ControlWord', WORD),
90 ('StatusWord', WORD),
91 ('TagWord', BYTE),
92 ('Reserved1', BYTE),
93 ('ErrorOpcode', WORD),
94 ('ErrorOffset', DWORD),
95 ('ErrorSelector', WORD),
96 ('Reserved2', WORD),
97 ('DataOffset', DWORD),
98 ('DataSelector', WORD),
99 ('Reserved3', WORD),
100 ('MxCsr', DWORD),
101 ('MxCsr_Mask', DWORD),
102 ('FloatRegisters', M128A * 8),
103 ('XmmRegisters', M128A * 16),
104 ('Reserved4', BYTE * 96),
105 ]
106
107 LEGACY_SAVE_AREA_LENGTH = sizeof(XMM_SAVE_AREA32)
108
109 PXMM_SAVE_AREA32 = ctypes.POINTER(XMM_SAVE_AREA32)
110 LPXMM_SAVE_AREA32 = PXMM_SAVE_AREA32
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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 -class _CONTEXT_FLTSAVE_STRUCT(Structure):
265 _fields_ = [
266 ('Header', M128A * 2),
267 ('Legacy', M128A * 8),
268 ('Xmm0', M128A),
269 ('Xmm1', M128A),
270 ('Xmm2', M128A),
271 ('Xmm3', M128A),
272 ('Xmm4', M128A),
273 ('Xmm5', M128A),
274 ('Xmm6', M128A),
275 ('Xmm7', M128A),
276 ('Xmm8', M128A),
277 ('Xmm9', M128A),
278 ('Xmm10', M128A),
279 ('Xmm11', M128A),
280 ('Xmm12', M128A),
281 ('Xmm13', M128A),
282 ('Xmm14', M128A),
283 ('Xmm15', M128A),
284 ]
290
291 -class CONTEXT(Structure):
292 arch = 'amd64'
293
294 _pack_ = 16
295 _fields_ = [
296
297
298 ('P1Home', DWORD64),
299 ('P2Home', DWORD64),
300 ('P3Home', DWORD64),
301 ('P4Home', DWORD64),
302 ('P5Home', DWORD64),
303 ('P6Home', DWORD64),
304
305
306 ('ContextFlags', DWORD),
307 ('MxCsr', DWORD),
308
309
310 ('SegCs', WORD),
311 ('SegDs', WORD),
312 ('SegEs', WORD),
313 ('SegFs', WORD),
314 ('SegGs', WORD),
315 ('SegSs', WORD),
316 ('EFlags', DWORD),
317
318
319 ('Dr0', DWORD64),
320 ('Dr1', DWORD64),
321 ('Dr2', DWORD64),
322 ('Dr3', DWORD64),
323 ('Dr6', DWORD64),
324 ('Dr7', DWORD64),
325
326
327 ('Rax', DWORD64),
328 ('Rcx', DWORD64),
329 ('Rdx', DWORD64),
330 ('Rbx', DWORD64),
331 ('Rsp', DWORD64),
332 ('Rbp', DWORD64),
333 ('Rsi', DWORD64),
334 ('Rdi', DWORD64),
335 ('R8', DWORD64),
336 ('R9', DWORD64),
337 ('R10', DWORD64),
338 ('R11', DWORD64),
339 ('R12', DWORD64),
340 ('R13', DWORD64),
341 ('R14', DWORD64),
342 ('R15', DWORD64),
343
344
345 ('Rip', DWORD64),
346
347
348 ('FltSave', _CONTEXT_FLTSAVE_UNION),
349
350
351 ('VectorRegister', M128A * 26),
352 ('VectorControl', DWORD64),
353
354
355 ('DebugControl', DWORD64),
356 ('LastBranchToRip', DWORD64),
357 ('LastBranchFromRip', DWORD64),
358 ('LastExceptionToRip', DWORD64),
359 ('LastExceptionFromRip', DWORD64),
360 ]
361
362 _others = ('P1Home', 'P2Home', 'P3Home', 'P4Home', 'P5Home', 'P6Home', \
363 'MxCsr', 'VectorRegister', 'VectorControl')
364 _control = ('SegSs', 'Rsp', 'SegCs', 'Rip', 'EFlags')
365 _integer = ('Rax', 'Rcx', 'Rdx', 'Rbx', 'Rsp', 'Rbp', 'Rsi', 'Rdi', \
366 'R8', 'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15')
367 _segments = ('SegDs', 'SegEs', 'SegFs', 'SegGs')
368 _debug = ('Dr0', 'Dr1', 'Dr2', 'Dr3', 'Dr6', 'Dr7', \
369 'DebugControl', 'LastBranchToRip', 'LastBranchFromRip', \
370 'LastExceptionToRip', 'LastExceptionFromRip')
371 _mmx = ('Xmm0', 'Xmm1', 'Xmm2', 'Xmm3', 'Xmm4', 'Xmm5', 'Xmm6', 'Xmm7', \
372 'Xmm8', 'Xmm9', 'Xmm10', 'Xmm11', 'Xmm12', 'Xmm13', 'Xmm14', 'Xmm15')
373
374
375
376
377 @classmethod
378 - def from_dict(cls, ctx):
379 'Instance a new structure from a Python dictionary.'
380 ctx = Context(ctx)
381 s = cls()
382 ContextFlags = ctx['ContextFlags']
383 s.ContextFlags = ContextFlags
384 for key in cls._others:
385 setattr(s, key, ctx[key])
386 if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL:
387 for key in cls._control:
388 setattr(s, key, ctx[key])
389 if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER:
390 for key in cls._integer:
391 setattr(s, key, ctx[key])
392 if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS:
393 for key in cls._segments:
394 setattr(s, key, ctx[key])
395 if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS:
396 for key in cls._debug:
397 setattr(s, key, ctx[key])
398 if (ContextFlags & CONTEXT_MMX_REGISTERS) == CONTEXT_MMX_REGISTERS:
399 xmm = s.FltSave.xmm
400 for key in cls._mmx:
401 setattr(xmm, key, ctx[key])
402 return s
403
405 'Convert a structure into a Python dictionary.'
406 ctx = Context()
407 ContextFlags = self.ContextFlags
408 ctx['ContextFlags'] = ContextFlags
409 for key in self._others:
410 ctx[key] = getattr(self, key)
411 if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL:
412 for key in self._control:
413 ctx[key] = getattr(self, key)
414 if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER:
415 for key in self._integer:
416 ctx[key] = getattr(self, key)
417 if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS:
418 for key in self._segments:
419 ctx[key] = getattr(self, key)
420 if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS:
421 for key in self._debug:
422 ctx[key] = getattr(self, key)
423 if (ContextFlags & CONTEXT_MMX_REGISTERS) == CONTEXT_MMX_REGISTERS:
424 xmm = self.FltSave.xmm
425 for key in self._mmx:
426 ctx[key] = getattr(xmm, key)
427 return ctx
428
429 PCONTEXT = ctypes.POINTER(CONTEXT)
430 LPCONTEXT = PCONTEXT
431
432 -class Context(dict):
433 """
434 Register context dictionary for the %s architecture.
435 """ % CONTEXT.arch
436 arch = CONTEXT.arch
437
438 - def __get_pc(self):
440 - def __set_pc(self, value):
442 pc = property(__get_pc, __set_pc)
443
444 - def __get_sp(self):
446 - def __set_sp(self, value):
448 sp = property(__get_sp, __set_sp)
449
450 - def __get_fp(self):
452 - def __set_fp(self, value):
454 fp = property(__get_fp, __set_fp)
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484 -class _LDT_ENTRY_BYTES_(Structure):
485 _pack_ = 1
486 _fields_ = [
487 ('BaseMid', BYTE),
488 ('Flags1', BYTE),
489 ('Flags2', BYTE),
490 ('BaseHi', BYTE),
491 ]
492
493 -class _LDT_ENTRY_BITS_(Structure):
494 _pack_ = 1
495 _fields_ = [
496 ('BaseMid', DWORD, 8),
497 ('Type', DWORD, 5),
498 ('Dpl', DWORD, 2),
499 ('Pres', DWORD, 1),
500 ('LimitHi', DWORD, 4),
501 ('Sys', DWORD, 1),
502 ('Reserved_0', DWORD, 1),
503 ('Default_Big', DWORD, 1),
504 ('Granularity', DWORD, 1),
505 ('BaseHi', DWORD, 8),
506 ]
507
509 _pack_ = 1
510 _fields_ = [
511 ('Bytes', _LDT_ENTRY_BYTES_),
512 ('Bits', _LDT_ENTRY_BITS_),
513 ]
514
515 -class LDT_ENTRY(Structure):
516 _pack_ = 1
517 _fields_ = [
518 ('LimitLow', WORD),
519 ('BaseLow', WORD),
520 ('HighWord', _LDT_ENTRY_HIGHWORD_),
521 ]
522
523 PLDT_ENTRY = POINTER(LDT_ENTRY)
524 LPLDT_ENTRY = PLDT_ENTRY
525
526
527
528
529
530
531
532
533 -def GetThreadSelectorEntry(hThread, dwSelector):
534 _GetThreadSelectorEntry = windll.kernel32.GetThreadSelectorEntry
535 _GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, LPLDT_ENTRY]
536 _GetThreadSelectorEntry.restype = bool
537 _GetThreadSelectorEntry.errcheck = RaiseIfZero
538
539 ldt = LDT_ENTRY()
540 _GetThreadSelectorEntry(hThread, dwSelector, ctypes.byref(ldt))
541 return ldt
542
543
544
545
546
547 -def GetThreadContext(hThread, ContextFlags = None):
548 _GetThreadContext = windll.kernel32.GetThreadContext
549 _GetThreadContext.argtypes = [HANDLE, LPCONTEXT]
550 _GetThreadContext.restype = bool
551 _GetThreadContext.errcheck = RaiseIfZero
552
553 if ContextFlags is None:
554 ContextFlags = CONTEXT_ALL
555 lpContext = CONTEXT()
556 lpContext.ContextFlags = ContextFlags
557 _GetThreadContext(hThread, ctypes.byref(lpContext))
558 return lpContext.to_dict()
559
560
561
562
563
564 -def SetThreadContext(hThread, lpContext):
565 _SetThreadContext = windll.kernel32.SetThreadContext
566 _SetThreadContext.argtypes = [HANDLE, LPCONTEXT]
567 _SetThreadContext.restype = bool
568 _SetThreadContext.errcheck = RaiseIfZero
569
570 if isinstance(lpContext, dict):
571 lpContext = CONTEXT.from_dict(lpContext)
572 _SetThreadContext(hThread, ctypes.byref(lpContext))
573
574
575
576
577
578
579 -def Wow64GetThreadSelectorEntry(hThread, dwSelector):
580 _Wow64GetThreadSelectorEntry = windll.kernel32.Wow64GetThreadSelectorEntry
581 _Wow64GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, PWOW64_LDT_ENTRY]
582 _Wow64GetThreadSelectorEntry.restype = bool
583 _Wow64GetThreadSelectorEntry.errcheck = RaiseIfZero
584
585 lpSelectorEntry = WOW64_LDT_ENTRY()
586 _Wow64GetThreadSelectorEntry(hThread, dwSelector, ctypes.byref(lpSelectorEntry))
587 return lpSelectorEntry
588
593 _Wow64ResumeThread = windll.kernel32.Wow64ResumeThread
594 _Wow64ResumeThread.argtypes = [HANDLE]
595 _Wow64ResumeThread.restype = DWORD
596
597 previousCount = _Wow64ResumeThread(hThread)
598 if previousCount == DWORD(-1).value:
599 raise ctypes.WinError()
600 return previousCount
601
606 _Wow64SuspendThread = windll.kernel32.Wow64SuspendThread
607 _Wow64SuspendThread.argtypes = [HANDLE]
608 _Wow64SuspendThread.restype = DWORD
609
610 previousCount = _Wow64SuspendThread(hThread)
611 if previousCount == DWORD(-1).value:
612 raise ctypes.WinError()
613 return previousCount
614
615
616
617
618
619
620
621
622 -def Wow64GetThreadContext(hThread, ContextFlags = None, lpContext = None):
623 _Wow64GetThreadContext = windll.kernel32.Wow64GetThreadContext
624 _Wow64GetThreadContext.argtypes = [HANDLE, LPVOID]
625 _Wow64GetThreadContext.restype = bool
626 _Wow64GetThreadContext.errcheck = RaiseIfZero
627
628
629
630 if lpContext is None:
631 lpContext = WOW64_CONTEXT()
632 if ContextFlags is None:
633 lpContext.ContextFlags = WOW64_CONTEXT_ALL
634 else:
635 lpContext.ContextFlags = ContextFlags
636 elif ContextFlags is not None:
637 lpContext.ContextFlags = ContextFlags
638 _Wow64GetThreadContext(hThread, ctypes.byref(lpContext))
639 return lpContext.to_dict()
640
641
642
643
644
645 -def Wow64SetThreadContext(hThread, lpContext):
646 _Wow64SetThreadContext = windll.kernel32.Wow64SetThreadContext
647 _Wow64SetThreadContext.argtypes = [HANDLE, PWOW64_CONTEXT]
648 _Wow64SetThreadContext.restype = bool
649 _Wow64SetThreadContext.errcheck = RaiseIfZero
650
651 if isinstance(lpContext, dict):
652 lpContext = WOW64_CONTEXT.from_dict(lpContext)
653 _Wow64SetThreadContext(hThread, ctypes.byref(lpContext))
654