回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我在Windows7 64位计算机上工作(我有管理员权限)。在</p>
<p>我使用python2.7(64位)和PyDev cypes for Eclipse来尝试读取与特定PID相关联的所有线程中的寄存器值(尝试了在64位和32位模式下运行的进程的PID),但是当我这样做时,寄存器的值都是零。当我使用<code>Wow64GetThreadContext</code>时,调用失败,<code>GetLastError</code>返回0x00000057('根据MSDN,'无效参数')</p>
<p>我成功地附加到进程,枚举线程(通过<code>CreateToolhelp32Snapshot</code>),找到进程拥有的线程,并尝试获取线程上下文。下面是我打开线程并获取线程上下文的代码:</p>
<p>打开线程:</p>
<pre><code>def open_thread(self, thread_id):
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
</code></pre>
<p>获取上下文:</p>
^{pr2}$
<p>我将此代码称为:</p>
<pre><code>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()
</code></pre>
<p>当我使用<code>GetThreadContext</code>和上下文结构运行这段代码时,我会为每个线程返回上下文对象,但是寄存器值都是零。在</p>
<p>我尝试过将<code>GetThreadContext</code>替换为<code>Wow64GetThreadContext</code>(并且分别将<code>SuspendThread</code>替换为<code>Wow64SuspendThread</code>),但是当我这样做时,调用失败,并出现错误“invalid parameters”。我给<code>Wow64GetThreadContext</code>的参数与我给<code>GetThreadContext</code>的参数相同,而不是我提供的代码中变量的名称(这是因为当我在WinNT.h中查看它们的定义时,它们是等价的(除非我遗漏了什么)。我用以下方式定义了这些结构:</p>
<pre><code>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),
]
</code></pre>
<p>关于这个问题,我在谷歌上做了大量的搜索,但没有成功:</p>
<ul>
<li><p>根据MSDN上的一条评论:<code>CONTEXT_FULL</code>应该是
<code>CONTEXT_AMD64 | CONTEXT_CONTROL | CONTEXT_INTEGER |
CONTEXT_FLOATING_POINT</code>与Win64一起正确使用。</p></li>
<li><p>我试着在我的上下文和WOW_64CONTEXT中重命名寄存器
结构,将寄存器名中的“E”替换为“R”(Eax
->;Rax等)</p></li>
</ul>
<p>有没有人用Python和cypes成功地获取了Windows上64位线程的上下文?在</p>