我在Windows7 64位计算机上工作(我有管理员权限)。在
我使用python2.7(64位)和PyDev cypes for Eclipse来尝试读取与特定PID相关联的所有线程中的寄存器值(尝试了在64位和32位模式下运行的进程的PID),但是当我这样做时,寄存器的值都是零。当我使用Wow64GetThreadContext
时,调用失败,GetLastError
返回0x00000057('根据MSDN,'无效参数')
我成功地附加到进程,枚举线程(通过CreateToolhelp32Snapshot
),找到进程拥有的线程,并尝试获取线程上下文。下面是我打开线程并获取线程上下文的代码:
打开线程:
def open_thread(self, thread_id):
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
获取上下文:
^{pr2}$我将此代码称为:
debugger.attach(int(pid))
#debugger.run()
list = debugger.enumerate_threads()
for thread in list:
thread_context = debugger.get_thread_context(thread)
if thread_context == False:
print "[*] Thread context is false..."
else:
print "[*] Dumping registers for thread ID: 0x%08x" % thread
print "[**] Eip: 0x%016x" % thread_context.Eip
print "[**] Esp: 0x%016x" % thread_context.Esp
print "[**] Ebp: 0x%016x" % thread_context.Ebp
print "[**] Eax: 0x%016x" % thread_context.Eax
print "[**] Ebx: 0x%016x" % thread_context.Ebx
print "[**] Ecx: 0x%016x" % thread_context.Ecx
print "[**] Edx: 0x%016x" % thread_context.Edx
print "[*] End DUMP"
debugger.detach()
当我使用GetThreadContext
和上下文结构运行这段代码时,我会为每个线程返回上下文对象,但是寄存器值都是零。在
我尝试过将GetThreadContext
替换为Wow64GetThreadContext
(并且分别将SuspendThread
替换为Wow64SuspendThread
),但是当我这样做时,调用失败,并出现错误“invalid parameters”。我给Wow64GetThreadContext
的参数与我给GetThreadContext
的参数相同,而不是我提供的代码中变量的名称(这是因为当我在WinNT.h中查看它们的定义时,它们是等价的(除非我遗漏了什么)。我用以下方式定义了这些结构:
class WOW64_CONTEXT(Structure):
_fields_ = [
("ContextFlags", DWORD),
("Dr0", DWORD),
("Dr1", DWORD),
("Dr2", DWORD),
("Dr3", DWORD),
("Dr6", DWORD),
("Dr7", DWORD),
("FloatSave", WOW64_FLOATING_SAVE_AREA),
("SegGs", DWORD),
("SegFs", DWORD),
("SegEs", DWORD),
("SegDs", DWORD),
("Edi", DWORD),
("Esi", DWORD),
("Ebx", DWORD),
("Edx", DWORD),
("Ecx", DWORD),
("Eax", DWORD),
("Ebp", DWORD),
("Eip", DWORD),
("SegCs", DWORD),
("EFlags", DWORD),
("Esp", DWORD),
("SegSs", DWORD),
("ExtendedRegisters", BYTE * 512),
]
class WOW64_FLOATING_SAVE_AREA(Structure):
_fields_ = [
("ControlWord", DWORD),
("StatusWord", DWORD),
("TagWord", DWORD),
("ErrorOffset", DWORD),
("ErrorSelector", DWORD),
("DataOffset", DWORD),
("DataSelector", DWORD),
("RegisterArea", BYTE * 80),
("Cr0NpxState", DWORD),
]
class CONTEXT(Structure):
_fields_ = [
("ContextFlags", DWORD),
("Dr0", DWORD),
("Dr1", DWORD),
("Dr2", DWORD),
("Dr3", DWORD),
("Dr6", DWORD),
("Dr7", DWORD),
("FloatSave", FLOATING_SAVE_AREA),
("SegGs", DWORD),
("SegFs", DWORD),
("SegEs", DWORD),
("SegDs", DWORD),
("Edi", DWORD),
("Esi", DWORD),
("Ebx", DWORD),
("Edx", DWORD),
("Ecx", DWORD),
("Eax", DWORD),
("Ebp", DWORD),
("Eip", DWORD),
("SegCs", DWORD),
("EFlags", DWORD),
("Esp", DWORD),
("SegSs", DWORD),
("ExtendedRegisters", BYTE * 512),
]
class FLOATING_SAVE_AREA(Structure):
_fields_ = [
("ControlWord", DWORD),
("StatusWord", DWORD),
("TagWord", DWORD),
("ErrorOffset", DWORD),
("ErrorSelector", DWORD),
("DataOffset", DWORD),
("DataSelector", DWORD),
("RegisterArea", BYTE * 80),
("Cr0NpxState", DWORD),
]
关于这个问题,我在谷歌上做了大量的搜索,但没有成功:
根据MSDN上的一条评论:CONTEXT_FULL
应该是
CONTEXT_AMD64 | CONTEXT_CONTROL | CONTEXT_INTEGER |
CONTEXT_FLOATING_POINT
与Win64一起正确使用。
我试着在我的上下文和WOW_64CONTEXT中重命名寄存器 结构,将寄存器名中的“E”替换为“R”(Eax ->;Rax等)
有没有人用Python和cypes成功地获取了Windows上64位线程的上下文?在
主要问题是WOW64实际上是32位上下文,而不是64位上下文。您需要实现一个64位结构,类似于:
注意:这个定义位于WinNT.h中,如果您安装了VC++,它将位于安装它的/include目录中。在
一旦构建了这个结构,您就可以使用它来代替您构建的CONTEXT/WOW64上下文。你还得把寄存器改成RAX等等
(注意:在Python ctypes中还需要实现4个其他功能:DWORD64、M128A、DUMMYUNIONNAME、DUMMYSTRUCTNAME和XMM_SAVE_AREA32。为了简洁起见,我排除了它们,但是您可以在以下位置找到它们的定义,以便自己构建它们:
德沃德64:只是一个乌龙龙龙
DUMMYUNIONNAME,DUMMYSTRUCTNAME:在\u CONTEXT结构的WinNT.h中
M128A:http://winappdbg.sourceforge.net/doc/v1.3/winappdbg.win32.defines.M128A-class.html
XMM_SAVE_区域32:http://winappdbg.sourceforge.net/doc/v1.3/winappdbg.win32.context_amd64.XMM_SAVE_AREA32-class.html
检查ContextFlags常量的值。我从python模块win32con得到的值缺少依赖于体系结构的位。这是从my WinNT.h(来自Windows SDK Server2003SP1)的摘录:
如果不适合您,请检查windows版本的WinNT.h。在
我也有这个问题,我现在有了这个问题,我假设这是从格雷帽子的python书,经过大量的google搜索,发现Wow64GetThreadContext用于检索64位系统上的32位线程上下文,我使用了原始的GetThreadContext函数,但我传递给它的是一个定义如下的Wow64Context结构:
当然,我还没有检查寄存器中返回的值是正确的还是只是垃圾,但是值存在而不是0x00000000或错误0x57这一事实令人放心。在
访问寄存器仍然是通过线程完成的_上下文。Rip等等,不是eip
相关问题 更多 >
编程相关推荐