在 IDAPython 中跨模块扫描给定导入函数的有效方法是什么?

逆向工程 艾达 蟒蛇
2021-06-28 22:59:03

我正在编写一个脚本,它应该首先在 start、_start、_main 或 main 上放置一个断点,然后启动 IDA Pro 调试器。然后它应该枚举寻找“kernel32.dll”的模块,最后,从模块基地址到大小地址扫描kernel32.dll,检查每一行的函数名称“ExitProcess”,如果找到,则在其上放置一个断点它。最后,它应该运行到这个断点。

脚本不起作用;它在迭代 4818 之后完全冻结了 IDA Pro,并且在对基础和大小进行了一些数学运算后,我注意到模块的实际大小也已关闭,如下面的屏幕截图所示:

在此处输入图片说明 根据大小,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()

请注意,睡眠和打印仅用于调试目的。

1个回答

那些调试 API 也从来没有对我有用,即使我在 c++ 插件中使用过它们。似乎您必须执行很多 Wait() 才能使引擎处理事件。