【问题标题】:'bool' object is not iterable, Gray Hat Python example'bool' 对象不可迭代,Gray Hat Python 示例
【发布时间】:2013-12-16 18:15:28
【问题描述】:
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

如果您需要更多信息,请告诉我。我很感激任何帮助。提前致谢。

【问题讨论】:

  • 除了任何答案之外,您几乎肯定不想要名为list 的变量。它隐藏了一个内置函数。

标签: python boolean iterable


【解决方案1】:

thread_entry.th32OwnerProcessID == self.pid 不为真时,您的方法返回False。也许您想返回一个空列表?

else:
    return []

无论哪种方式,您的函数都返回而不迭代,因为您总是来自while循环的return

如果successFalse,您的代码也将返回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 并不是一个好主意;已经有该名称的内置类型,您的代码现在正在隐藏它。

【讨论】:

  • 我要补充一点,OP想要return []
  • 感谢快速响应,它消除了错误,但现在调试器从进程中分离出来而不转储任何寄存器值。
  • @GrassArk:我怀疑你的问题缩进已经出路了;你可能想解决这个问题。例如,我将 print 语句的缩进更正为循环的一部分。
  • @GrassArk:我还尝试重写你的线程收集循环。我对 Win32 API 的经验为 0,所以我可能误读了您的意图。
  • 我尝试使用您提供的代码更改代码,并且调试器在不转储寄存器值的情况下分离。不过,我感谢您的帮助。
【解决方案2】:

我遇到了同样的问题,问题出在我的缩进中。如果您查看发布者网站 (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' object not iterable 错误。一旦你编译它,它就会工作,但你不会得到任何结果;至少我没有。该脚本附加到该进程,但它没有打印寄存器值。我发现问题出在第 31 页的错误代码上。它有一行“self.run()”,您在其中定义了附加函数。同样,如果您查看源代码,您会注意到它不存在。删除此行后,该代码将正常运行。希望这对某人有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-21
    • 2019-02-22
    • 2019-02-20
    • 2019-01-27
    • 2023-02-26
    • 1970-01-01
    • 2015-11-28
    • 2021-12-13
    相关资源
    最近更新 更多