import my_debugger
from my_debugger_defines import *
debugger = my_debugger.debugger()
pid = raw_input("Enter the PID of the process to attach to: ")
debugger.attach(int(pid))
list = debugger.enumerate_threads()
for thread in list:
thread_context = debugger.get_thread_context(thread)
print "[*] Dumping registers for thread ID: 0x%08x" % thread
print "[**] EIP: 0x%08x" % thread_context.Eip
print "[**] ESP: 0x%08x" % thread_context.Esp
print "[**] EBP: 0x%08x" % thread_context.Ebp
print "[**] EAX: 0x%08x" % thread_context.Eax
print "[**] EBX: 0x%08x" % thread_context.Ebx
print "[**] ECX: 0x%08x" % thread_context.Ecx
print "[**] EDX: 0x%08x" % thread_context.Edx
print "[*] END DUMP"
debugger.detach()
上面是我的测试程序,它产生'bool'对象而不是可迭代错误并引用第12行:
for thread in list:
我对可迭代对象进行了一些研究,并且基本上发现它必须能够用不同的值重复自己(如果我错了,请纠正我,我的编程知识非常弱)。我不知道如何修复代码以使其工作。我做了很多谷歌搜索,我没有足够的经验来引用类似的问题,并将其应用到我自己的代码。这是代码直接出书,所以我只是想知道我是否犯了一个简单的错误,或者它是否更复杂。
这里也是枚举线程的定义函数
def enumerate_threads(self):
thread_entry = THREADENTRY32()
thread_list = []
snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid)
if snapshot is not None:
thread_entry.dwSize = sizeof(thread_entry)
success = kernel32.Thread32First(snapshot, byref(thread_entry))
while success:
if thread_entry.th32OwnerProcessID == self.pid:
thread_list.append(thread_entry.th32ThreadID)
success = kernel32.Thread32Next(snapshot, byref(thread_entry))
kernel32.CloseHandle(snapshot)
return thread_list
else:
return False
如果您需要更多信息,请与我们联系。我感谢任何帮助。提前谢谢。
答案 0 :(得分:3)
当False
不为True时,您的方法会返回thread_entry.th32OwnerProcessID == self.pid
。也许你想要返回一个空列表?
else:
return []
无论哪种方式,您的函数都会返回而不会进行迭代,因为始终 return
来自while
循环。
如果success
为False
,您的代码也会返回None
,这也不会被迭代。也许你想用:
while success:
if thread_entry.th32OwnerProcessID == self.pid:
thread_list.append(thread_entry.th32ThreadID)
success = kernel32.Thread32Next(snapshot, byref(thread_entry))
if snapshot is not None:
kernel32.CloseHandle(snapshot)
return thread_list
请注意,在代码中使用名称list
并不是一个好主意;已有一个内置类型的名称,你的代码现在正在遮蔽它。
答案 1 :(得分:1)
我有同样的问题,问题出在我的缩进中。如果您查看发布商网站(http://www.nostarch.com/download/ghpython_src.zip)上提供的源代码并将其与您自己的源代码进行比较,您可能会注意到您的缩进错误(并非我发现的不常见错误......)。
以下是我的功能代码的样子(来自本书第36-37页):
def open_thread (self, thread_id):
h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id)
if h_thread is not None:
return h_thread
else:
print "[*] Could not obtain a valid thread handle."
return False
def enumerate_threads(self):
thread_entry = THREADENTRY32()
thread_list= []
snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid)
if snapshot is not None:
# You have to set the size of the struct
# or the call will fail
thread_entry.dwSize = sizeof(thread_entry)
success = kernel32.Thread32First(snapshot, byref(thread_entry))
while success:
if thread_entry.th32OwnerProcessID == self.pid:
thread_list.append(thread_entry.th32ThreadID)
success = kernel32.Thread32Next(snapshot,byref(thread_entry))
kernel32.CloseHandle(snapshot)
return thread_list
else:
return False
def get_thread_context (self, thread_id=None,h_thread=None):
context = CONTEXT()
context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS
# Obtain a handle to the thread
h_thread = self.open_thread(thread_id)
if kernel32.GetThreadContext(h_thread,byref(context)):
kernel32.CloseHandle(h_thread)
return context
else:
return False
这将摆脱'bool'对象不可迭代的错误。一旦你编译它,它将工作,但你将得不到任何结果;至少我没有。脚本附加到进程,但它没有打印寄存器值。我发现问题是第31页的错误代码。它有“self.run()”行,您可以在其中定义attach函数。同样,如果你看一下源代码,你会注意到它不在那里。删除此行后,代码将运行正常。希望这有助于某人!