Reputation: 11
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()
Above is my test program and it produces the 'bool' object not iterable error and references line 12:
for thread in list:
I did some research on iterable objects and basically found that it must be able to reiterate itself with different values (please correct me if I am wrong I have a very weak programming knowledge). I don't know how to fix the code to make this work. I have done a lot of googling and I am not experienced enough to reference a similar issue and apply it to my own code. This is code straight out of the book so I am just wondering if I have made a simple mistake or if it is more complicated.
Also here is the defined function for enumerate threads
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
Please let me know if you need more info. I appreciate any help. Thanks in advance.
Upvotes: 1
Views: 4427
Reputation: 11
I had the same issue and the problem was in my indentation. If you look at the source code provided on the publisher's website (http://www.nostarch.com/download/ghpython_src.zip) and compare it against your own, you will probably notice that your indentation is wrong (not an uncommon error I have found...).
Here's how my functioning code looks like (from pages 36-37 in the book):
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
This will get rid of the 'bool' object not iterable error. Once you compile this, it will work but you will get no results; at least I didn't. The script was attaching to the process but it wasn't printing the register values. I found the problem to be incorrect code from page 31. It had the line "self.run()" where you define the attach function. Again, if you look at the source code you will notice that it's not there. Once you delete this line that code will run just fine. Hope this help someone!
Upvotes: 1
Reputation: 1123730
Your method returns False
when thread_entry.th32OwnerProcessID == self.pid
is not True. Perhaps you wanted to return an empty list instead?
else:
return []
Either way, your function returns without iterating, as you always return
from the while
loop.
If success
is False
your code will also return None
, which won't be iterable either. Perhaps you wanted to use:
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
Note that it is rarely a good idea to use the name list
in your code; there is a built-in type of that name already, and your code is now shadowing it.
Upvotes: 3