我正在使用Windows 7 64位机器(我有管理员权限)。我使用PyDev ctypes for Python的Python 2.7(64位)来尝试读取与特定PID关联的所有线程中的寄存器值(尝试了在64和32位模式下运行的进程的PID) ,但是当我这样做时,寄存器的值全部为零。当我使用Wow64GetThreadContext
,呼叫失败,GetLastError
返回0x00000057(“无效参数”根据MSDN)Win 64bit GetThreadContext返回zeroe'd输出寄存器,或0x57错误代码
我连接到进程顺利,枚举线程(通过CreateToolhelp32Snapshot
),发现了由过程与所拥有的线程适当的PID,并尝试获取线程上下文。这里是我开的线程和获取线程上下文代码:
打开一个线程:
def open_thread(self, thread_id):
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
获取上下文:
def get_thread_context(self, thread_id = None, h_thread = None):
context = CONTEXT()
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
#alternatively, for 64
context64 = WOW64_CONTEXT()
context64.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
#Obtain a handle to the thread
if h_thread is None:
self.h_thread = self.open_thread(thread_id)
kernel32.SuspendThread(self.h_thread)
if kernel32.GetThreadContext(self.h_thread, byref(context)):
kernel32.ResumeThread(self.h_thread)
return context
else:
kernel32.ResumeThread(self.h_thread)
return False
我打电话使用此代码:
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()
当我使用CONTEXT结构使用GetThreadContext
运行此代码时,我得到上下文对象bac k为每个线程,但寄存器值都为零。
我曾尝试(与Wow64SuspendThread
和分别为SuspendThread
)取代GetThreadContext
与Wow64GetThreadContext
,但我这样做的时候,呼叫失败,错误“无效参数”。我给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。我已经尝试通过用 'R' 的寄存器名称替换 'E' 重命名寄存器我的上下文和WOW_64CONTEXT内部 结构(EAX - > RAX等)
是否有其他人使用Python与ctypes成功获取Windows上的64位线程的上下文?
@cghlke是的,我只是试过这个无济于事。我仍然看到0x57错误代码。 – bl4ckmes4
http://go4answers.webhost4life.com/Example/visual-studio-2010-101539.aspx:一个谷歌结果(0x57 = 87),表明这不太可能与Python相关 –
我同意。有谁知道如何解决这个问题,或者如果上面贴出的代码是错误/不完整的? – bl4ckmes4