Что такое эффективный способ сканирования для данной функции импорта через модули в IDAPython?


0

Я пишу сценарий, который должен сначала разместить точку останова при запуске, _start, _main или main, а затем запустить отладчик IDA Pro. Затем он должен перечислить модули, которые ищут «kernel32.dll», и, наконец, сканируйте файл kernel32.dll, начиная с базового адреса модуля, до адреса размера, проверяя каждую строку имени функции «ExitProcess», и если она найдена, установите точку останова на Это. Наконец, он должен перейти к этой точке останова.

Сценарий не работает; она замерзает IDA полностью Pro после итерации 4818 и после того, как делают некоторые математике с базой и размера, я заметил, что фактический размер модуля тоже выключен, как показано на скриншоте:

enter image description here По размеру, 74BF0000 + D0000 = 74CC0000, но, как мы видим, kernel32.dll не отображает это далеко. Хотя это одна из проблем, я также не понимаю, почему IDA Pro зависает и вылетает после итерации вокруг 4791 адресов в прошлом, что привело бы нас к 74BF12D2. Вот мой сценарий:

import time 
NULL = 0 
# possible refactor to just take the module object so base and size dont need to be passed in like this? 
def get_names(base, size, desired_name): 
    print "inside get_names" 
    print ("Base: %d Size: %d Desired Name: %s" % (base, size, desired_name)) 
    global NULL 
    current_address = base 
    i = 0 
    while current_address <= base+size: 
     print "Made it into current_address loop " 
     i += 1 
     print ("interation #: %d" % (i)) 
     # print hex(current_address) TODO: REMOVE 
     if desired_name in Name(current_address): 
      print "found %s" % (desired_name) 
      return current_address 
     time.sleep(0.02) 
     current_address = NextHead(current_address) 
    print "exiting get_names" 
    return NULL 

# Enumerate modules 
def find_import_routine(the_module, desired_name): 
    print "inside find_import routine" 
    for m in Modules(): 
     if the_module.lower() in m.name.lower(): 
      base = m.base 
      size = m.size 
      analyze_area(base, base+size) 
      begin_text = get_names(base, size, desired_name) 
      if begin_text: #check for null 
       add_bpt(begin_text,0,BPT_SOFT) 
       enable_bpt(begin_text,True) 
       continue_process() 
       GetDebuggerEvent(WFNE_SUSP,-1) 
       #del_bpt(initial_bp_ea) 
       return True #return the bp addr?? 
    print "exiting find_import routine" 
    return False 
def find_start(): 
    print "inside find_start routine" 
    global NULL 
    functions = idautils.Functions() 
    for f in functions: 
     name = get_func_name(f) 
     if name == 'start' or name == '_start' or name =='main' or name == '_main': 
      return f 
    print "exiting find)start" 
    return NULL 

def main(): 
    start_addr = find_start() 
    if start_addr: 
     idc.add_bpt(start_addr) 
     StartDebugger("","",""); 
     print "after StartDebugger()" 
     GetDebuggerEvent(WFNE_SUSP, -1) 
     print "after GetDebuggerEvent" 
     find_import_routine('kernel32.dll','ExitProcess') 
     print "After find_import_routine" 
    else: 
     print "Could not find a start routine. Exiting." 
if __name__ == "__main__": 
    main() 

Обратите внимание, что сон и печать предназначены только для целей отладки.

0

Эти API отладки никогда не работали для меня, даже когда я использовал их в плагине C++. Похоже, вам нужно сделать много Wait(), чтобы заставить движок обрабатывать события.

  0

Знаете ли вы разницу между 'Wait()' и 'GetDebuggerEvent()' ?? 12 дек. 172017-12-12 19:34:57

  0

Да, я знаю, я потратил неделю, пытаясь заставить его работать несколько лет назад, и перешел на обратную IDA, чтобы понять, где она висит, и я обнаружил, что существует некоторый конфликт между событиями отладчика и событиями механизма разборки, поэтому он зависает. Удачи найти настоящую причину. 13 дек. 172017-12-13 08:51:14