Grass Ark
Grass Ark

Reputation: 11

'bool' object is not iterable, Gray Hat Python example

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

Answers (2)

Jimmy Delgado
Jimmy Delgado

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

Martijn Pieters
Martijn Pieters

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

Related Questions