2013-12-16 1 views
1
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() 

Выше моя тестовая программа, и выдает «Ие» объект не итерация ошибки и ссылка Строка 12:«BOOL» не итерация, например, Gray Hat Python

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 

Пожалуйста, дайте мне знать, если вам нужно больше информации. Я ценю любую помощь. Заранее спасибо.

+4

В дополнение к любым ответам вы почти наверняка не хотите переменную с именем 'list'. Он тень встроенный. – geoffspear

ответ

3

Ваш метод возвращает False, когда thread_entry.th32OwnerProcessID == self.pid не является истинным. Возможно, вы хотели вернуть пустой список?

else: 
    return [] 

В любом случае, ваша функция возвращает без перебора, как вы всегдаreturn из цикла while.

Если success is 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 в коде; теперь есть встроенный тип этого имени, и ваш код теперь затеняет его.

+0

Я бы добавил, что OP хочет 'return []' –

+0

Оцените быстрый ответ, который избавился от этой ошибки, но теперь отладчик отделяется от процесса без сброса каких-либо значений регистра. –

+0

@GrassArk: Я подозреваю, что ваш вопрос вдавлен в выход; вы можете это исправить. Я исправил отступы для операторов 'print', которые, к примеру, являются частью цикла. –

0

У меня была такая же проблема, и проблема была в моем отступе. Если вы посмотрите на исходный код, представленный на веб-сайте издателя (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» объект не Iterable ошибки. Когда вы скомпилируете это, он будет работать, но вы не получите никаких результатов; по крайней мере, я этого не сделал. Сценарий был связан с процессом, но он не печатал значения регистра. Я нашел проблему неправильным кодом со страницы 31. У него была строка «self.run()», где вы определяете функцию attach. Опять же, если вы посмотрите на исходный код, вы заметите, что его там нет. Как только вы удалите эту строку, код будет работать нормально. Надеюсь, это поможет кому-то!