I am writing a script which should first place a breakpoint on start, _start, _main, or main and then start the IDA Pro debugger. It then should enumerate the modules looking for "kernel32.dll" and finally, scan the kernel32.dll starting from the module base address to the size address, checking each line for the function name "ExitProcess" and if found, place a breakpoint on it. Finally, it should run to this breakpoint.
The script is not working; it freezes up IDA Pro completely after iteration 4818 and after doing some math with the base and size, I noticed that the actual size of the module is also off as seen in this screenshot:
According to the size, 74BF0000 + D0000 = 74CC0000 but as we can see, kernel32.dll does not map that far. While this is one issue, I also do not understand why IDA Pro freezes up and crashes after iterating around 4791 addresses in past the base which would bring us to 74BF12D2. Here's my script:
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()
Please note that the sleep and print is only for debugging purposes.