python – Win 64bit GetThreadContext返回zeroe’d寄存器,或0x57错误代码

weixin_38054205 2019-09-12 10:29:12
我正在使用Windows 7 64位计算机(我有管理员权限). 我正在使用Python 2.7(64位)和PyDev ctypes for Eclipse来尝试读取与特定PID相关的所有线程中的寄存器值(尝试在64位和32位模式下运行的两个进程的PID),但是当我这样做,寄存器的值都是零.当我使用Wow64GetThreadContext时,调用失败,GetLastError返回0x00000057(根据MSDN,’无效参数’) 我成功附加到进程,枚举线程(通过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运行此代码时,我会为每个线程返回上下文对象,但寄存器值都为零. 我已经尝试用Wow64GetThreadContext替换GetThreadContext(分别使用Wow64SuspendThread替换SuspendThread),但是当我这样做时,调用失败并出现错误’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 |正确使用Win64的CONTEXT_FLOATING_POINT.>我已经尝试重命名我的CONTEXT和WOW_64CONTEXT中的寄存器通过用’R’替换寄存器名称中的’E'(Eax – > Rax等) 有没有其他人使用Python与ctypes成功获取Windows上的64位线程的上下文?
...全文
209 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_38061848 2019-09-12
  • 打赏
  • 举报
回复
你的主要问题是WOW64实际上是32位上下文,而不是64位.您需要实现64位结构,类似于: class CONTEXT64(Structure): _pack_ = 16 _fields_ = [ ("P1Home", DWORD64), ("P2Home", DWORD64), ("P3Home", DWORD64), ("P4Home", DWORD64), ("P5Home", DWORD64), ("P6Home", DWORD64), ("ContextFlags", DWORD), ("MxCsr", DWORD), ("SegCs", WORD), ("SegDs", WORD), ("SegEs", WORD), ("SegFs", WORD), ("SegGs", WORD), ("SegSs", WORD), ("EFlags", DWORD), ("Dr0", DWORD64), ("Dr1", DWORD64), ("Dr2", DWORD64), ("Dr3", DWORD64), ("Dr6", DWORD64), ("Dr7", DWORD64), ("Rax", DWORD64), ("Rcx", DWORD64), ("Rdx", DWORD64), ("Rbx", DWORD64), ("Rsp", DWORD64), ("Rbp", DWORD64), ("Rsi", DWORD64), ("Rdi", DWORD64), ("R8", DWORD64), ("R9", DWORD64), ("R10", DWORD64), ("R11", DWORD64), ("R12", DWORD64), ("R13", DWORD64), ("R14", DWORD64), ("R15", DWORD64), ("Rip", DWORD64), ("DebugControl", DWORD64), ("LastBranchToRip", DWORD64), ("LastBranchFromRip", DWORD64), ("LastExceptionToRip", DWORD64), ("LastExceptionFromRip", DWORD64), ("DUMMYUNIONNAME", DUMMYUNIONNAME), ("VectorRegister", M128A * 26), ("VectorControl", DWORD64) ] 注意:此定义位于WinNT.h中 – 如果安装了VC,它将位于安装它的/ include目录中. 一旦建立了这个结构,你就可以使用它而不是你构建的CONTEXT / WOW64语境.您还必须明显将寄存器更改为RAX等. (注意:你还需要在Python ctypes中实现4个其他的东西:DWORD64,M128A,DUMMYUNIONNAME,DUMMYSTRUCTNAME和XMM_SAVE_AREA32.为简洁起见,我已将它们排除在外,但您可以在以下位置找到它们的定义来构建他们自己: DWORD64:只是一个c_ulonglong DUMMYUNIONNAME,DUMMYSTRUCTNAME:在_CONTEXT结构中的WinNT.h中 M128A:http://winappdbg.sourceforge.net/doc/v1.3/winappdbg.win32.defines.M128A-class.html XMM_SAVE_AREA32:http://winappdbg.sourceforge.net/doc/v1.3/winappdbg.win32.context_amd64.XMM_SAVE_AREA32-class.html

477

社区成员

发帖
与我相关
我的任务
社区描述
其他技术讨论专区
其他 技术论坛(原bbs)
社区管理员
  • 其他技术讨论专区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧