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_i386.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_i386 = 0x00010000
46 CONTEXT_i486 = 0x00010000
47
48 CONTEXT_CONTROL = (CONTEXT_i386 | 0x00000001L)
49 CONTEXT_INTEGER = (CONTEXT_i386 | 0x00000002L)
50 CONTEXT_SEGMENTS = (CONTEXT_i386 | 0x00000004L)
51 CONTEXT_FLOATING_POINT = (CONTEXT_i386 | 0x00000008L)
52 CONTEXT_DEBUG_REGISTERS = (CONTEXT_i386 | 0x00000010L)
53 CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 | 0x00000020L)
54
55 CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
56
57 CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \
58 CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \
59 CONTEXT_EXTENDED_REGISTERS)
60
61 SIZE_OF_80387_REGISTERS = 80
62 MAXIMUM_SUPPORTED_EXTENSION = 512
76 _pack_ = 1
77 _fields_ = [
78 ('ControlWord', DWORD),
79 ('StatusWord', DWORD),
80 ('TagWord', DWORD),
81 ('ErrorOffset', DWORD),
82 ('ErrorSelector', DWORD),
83 ('DataOffset', DWORD),
84 ('DataSelector', DWORD),
85 ('RegisterArea', BYTE * SIZE_OF_80387_REGISTERS),
86 ('Cr0NpxState', DWORD),
87 ]
88
89 _integer_members = ('ControlWord', 'StatusWord', 'TagWord', 'ErrorOffset', 'ErrorSelector', 'DataOffset', 'DataSelector', 'Cr0NpxState')
90
91 @classmethod
103
113
114 PFLOATING_SAVE_AREA = POINTER(FLOATING_SAVE_AREA)
115 LPFLOATING_SAVE_AREA = PFLOATING_SAVE_AREA
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 -class CONTEXT(Structure):
145 arch = 'i386'
146
147 _pack_ = 1
148
149
150
151
152
153
154
155
156
157 _fields_ = [
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 ('ContextFlags', DWORD),
176
177
178
179
180
181 ('Dr0', DWORD),
182 ('Dr1', DWORD),
183 ('Dr2', DWORD),
184 ('Dr3', DWORD),
185 ('Dr6', DWORD),
186 ('Dr7', DWORD),
187
188
189
190
191 ('FloatSave', FLOATING_SAVE_AREA),
192
193
194
195
196 ('SegGs', DWORD),
197 ('SegFs', DWORD),
198 ('SegEs', DWORD),
199 ('SegDs', DWORD),
200
201
202
203
204 ('Edi', DWORD),
205 ('Esi', DWORD),
206 ('Ebx', DWORD),
207 ('Edx', DWORD),
208 ('Ecx', DWORD),
209 ('Eax', DWORD),
210
211
212
213
214 ('Ebp', DWORD),
215 ('Eip', DWORD),
216 ('SegCs', DWORD),
217 ('EFlags', DWORD),
218 ('Esp', DWORD),
219 ('SegSs', DWORD),
220
221
222
223
224
225 ('ExtendedRegisters', BYTE * MAXIMUM_SUPPORTED_EXTENSION),
226 ]
227
228 _ctx_debug = ('Dr0', 'Dr1', 'Dr2', 'Dr3', 'Dr6', 'Dr7')
229 _ctx_segs = ('SegGs', 'SegFs', 'SegEs', 'SegDs', )
230 _ctx_int = ('Edi', 'Esi', 'Ebx', 'Edx', 'Ecx', 'Eax')
231 _ctx_ctrl = ('Ebp', 'Eip', 'SegCs', 'EFlags', 'Esp', 'SegSs')
232
233 @classmethod
234 - def from_dict(cls, ctx):
235 'Instance a new structure from a Python dictionary.'
236 ctx = Context(ctx)
237 s = cls()
238 ContextFlags = ctx['ContextFlags']
239 setattr(s, 'ContextFlags', ContextFlags)
240 if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS:
241 for key in s._ctx_debug:
242 setattr(s, key, ctx[key])
243 if (ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT:
244 fsa = ctx['FloatSave']
245 s.FloatSave = FLOATING_SAVE_AREA.from_dict(fsa)
246 if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS:
247 for key in s._ctx_segs:
248 setattr(s, key, ctx[key])
249 if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER:
250 for key in s._ctx_int:
251 setattr(s, key, ctx[key])
252 if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL:
253 for key in s._ctx_ctrl:
254 setattr(s, key, ctx[key])
255 if (ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS:
256 er = ctx['ExtendedRegisters']
257 for index in xrange(0, MAXIMUM_SUPPORTED_EXTENSION):
258 s.ExtendedRegisters[index] = er[index]
259 return s
260
262 'Convert a structure into a Python dictionary.'
263 ctx = Context()
264 ContextFlags = self.ContextFlags
265 ctx['ContextFlags'] = ContextFlags
266 if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS:
267 for key in self._ctx_debug:
268 ctx[key] = getattr(self, key)
269 if (ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT:
270 ctx['FloatSave'] = self.FloatSave.to_dict()
271 if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS:
272 for key in self._ctx_segs:
273 ctx[key] = getattr(self, key)
274 if (ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER:
275 for key in self._ctx_int:
276 ctx[key] = getattr(self, key)
277 if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL:
278 for key in self._ctx_ctrl:
279 ctx[key] = getattr(self, key)
280 if (ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS:
281 er = [ self.ExtendedRegisters[index] for index in xrange(0, MAXIMUM_SUPPORTED_EXTENSION) ]
282 er = tuple(er)
283 ctx['ExtendedRegisters'] = er
284 return ctx
285
286 PCONTEXT = POINTER(CONTEXT)
287 LPCONTEXT = PCONTEXT
288
289 -class Context(dict):
290 """
291 Register context dictionary for the %s architecture.
292 """ % CONTEXT.arch
293 arch = CONTEXT.arch
294
295 - def __get_pc(self):
297 - def __set_pc(self, value):
299 pc = property(__get_pc, __set_pc)
300
301 - def __get_sp(self):
303 - def __set_sp(self, value):
305 sp = property(__get_sp, __set_sp)
306
307 - def __get_fp(self):
309 - def __set_fp(self, value):
311 fp = property(__get_fp, __set_fp)
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341 -class _LDT_ENTRY_BYTES_(Structure):
342 _pack_ = 1
343 _fields_ = [
344 ('BaseMid', BYTE),
345 ('Flags1', BYTE),
346 ('Flags2', BYTE),
347 ('BaseHi', BYTE),
348 ]
349
350 -class _LDT_ENTRY_BITS_(Structure):
351 _pack_ = 1
352 _fields_ = [
353 ('BaseMid', DWORD, 8),
354 ('Type', DWORD, 5),
355 ('Dpl', DWORD, 2),
356 ('Pres', DWORD, 1),
357 ('LimitHi', DWORD, 4),
358 ('Sys', DWORD, 1),
359 ('Reserved_0', DWORD, 1),
360 ('Default_Big', DWORD, 1),
361 ('Granularity', DWORD, 1),
362 ('BaseHi', DWORD, 8),
363 ]
364
366 _pack_ = 1
367 _fields_ = [
368 ('Bytes', _LDT_ENTRY_BYTES_),
369 ('Bits', _LDT_ENTRY_BITS_),
370 ]
371
372 -class LDT_ENTRY(Structure):
373 _pack_ = 1
374 _fields_ = [
375 ('LimitLow', WORD),
376 ('BaseLow', WORD),
377 ('HighWord', _LDT_ENTRY_HIGHWORD_),
378 ]
379
380 PLDT_ENTRY = POINTER(LDT_ENTRY)
381 LPLDT_ENTRY = PLDT_ENTRY
382
383
384
385
386
387
388
389
390 -def GetThreadSelectorEntry(hThread, dwSelector):
391 _GetThreadSelectorEntry = windll.kernel32.GetThreadSelectorEntry
392 _GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, LPLDT_ENTRY]
393 _GetThreadSelectorEntry.restype = bool
394 _GetThreadSelectorEntry.errcheck = RaiseIfZero
395
396 ldt = LDT_ENTRY()
397 _GetThreadSelectorEntry(hThread, dwSelector, ctypes.byref(ldt))
398 return ldt
399
400
401
402
403
404 -def GetThreadContext(hThread, ContextFlags = None):
405 _GetThreadContext = windll.kernel32.GetThreadContext
406 _GetThreadContext.argtypes = [HANDLE, LPCONTEXT]
407 _GetThreadContext.restype = bool
408 _GetThreadContext.errcheck = RaiseIfZero
409
410 if ContextFlags is None:
411 ContextFlags = CONTEXT_ALL
412 lpContext = CONTEXT()
413 lpContext.ContextFlags = ContextFlags
414 _GetThreadContext(hThread, ctypes.byref(lpContext))
415 return lpContext.to_dict()
416
417
418
419
420
421 -def SetThreadContext(hThread, lpContext):
422 _SetThreadContext = windll.kernel32.SetThreadContext
423 _SetThreadContext.argtypes = [HANDLE, LPCONTEXT]
424 _SetThreadContext.restype = bool
425 _SetThreadContext.errcheck = RaiseIfZero
426
427 if isinstance(lpContext, dict):
428 lpContext = CONTEXT.from_dict(lpContext)
429 _SetThreadContext(hThread, ctypes.byref(lpContext))
430