3.9 Debugger Scripting Using IDAPython

You can use debugger scripting to automate routine tasks related to malware analysis. In the previous chapter, we looked at examples of using IDAPython for static code analysis. In this section, you will learn how to use IDAPython to perform debugging-related tasks. The IDAPython scripts demonstrated in this section make use of the new IDAPython API, meaning that if you are using older versions of IDA (lower than IDA 7.0), these scripts will not work.

The following resources should help you get started with IDAPython debugger scripting. Most of these resources (except the IDAPython documentation) demonstrate scripting capabilities using the old IDAPython API, but they should be good enough for you to get the idea. Anytime you get stuck, you can refer to IDAPython documentation:

This section will give you a feel for how to use IDAPython for debugging-related tasks. First, load the executable in IDA, and select the debugger (via Debugger | Select debugger). For testing the following script commands, Local Windows debugger was chosen. After the executable has loaded, you can execute the Python code snippets mentioned in the following in IDA's Python shell, or by selecting File | Script Command (Shift + F2) and choosing the Scripting language as Python (from the drop-down menu). If you wish to run it as a standalone script, you may have to import the appropriate modules (for example, import idc).

The following code snippet sets a breakpoint at the current cursor location, starts the debugger, waits for the suspend debugger event to occur, and then prints the address and the disassembly text associated with the breakpoint address:

idc.add_bpt(idc.get_screen_ea())
idc.start_process('', '', '')
evt_code = idc.wait_for_next_event(WFNE_SUSP, -1)
if (evt_code > 0) and (evt_code != idc.PROCESS_EXITED):
evt_ea = idc.get_event_ea()
print "Breakpoint Triggered at:", hex(evt_ea),idc.generate_disasm_line(evt_ea, 0)

The following is the output generated as a result of executing the preceding script commands:

Breakpoint Triggered at: 0x1171010 push ebp

The following code snippet steps into the next instruction and prints the address and the disassembly text. In the same manner, you can use idc.step_over() to step over the instruction:

idc.step_into()
evt_code = idc.wait_for_next_event(WFNE_SUSP, -1)
if (evt_code > 0) and (evt_code != idc.PROCESS_EXITED):
evt_ea = idc.get_event_ea()
print "Stepped Into:", hex(evt_ea),idc.generate_disasm_line(evt_ea, 0)

The results of executing the preceding script commands are shown here:

Stepped Into: 0x1171011 mov ebp,esp

To get the value of a register,  you can use idc.get_reg_value(). The following example gets the value of the esp register and prints it in the output window:

Python>esp_value = idc.get_reg_value("esp")
Python>print hex(esp_value)
0x1bf950

To get the dword value at the address 0x14fb04, use the following code. In the same manneryou can use idc.read_dbg_byte(ea), idc.read_dbg_word(ea), and idc.read_dbg_qword(ea) to get the byte, word, and qword values at a particular address:

Python>ea = 0x14fb04
print hex(idc.read_dbg_dword(ea))
0x14fb54

To get an ASCII string at the address 0x01373000use the following. By default, the idc.get_strlit_contents() function gets the ASCII string at a given address:

Python>ea = 0x01373000
Python>print idc.get_strlit_contents(ea)
This is a simple program

To get the UNICODE string, you can use the idc.get_strlit_contents() function by setting its strtype argument to a constant value, idc.STRTYPE_C_16, as follows. You can find the defined constant values in the idc.idc file, which is located in your IDA installation directory:

Python>ea = 0x00C37860
Python>print idc.get_strlit_contents(ea, strtype=idc.STRTYPE_C_16)
SHAMple.dat

The following code lists all of the loaded modules (executables and DLLs) and their base addresses:

import idautils
for m in idautils.Modules():
print "0x%08x %s" % (m.base, m.name)

The result of executing the preceding script commands is shown here:

0x00400000 C:malware5340.exe
0x735c0000 C:WindowsSYSTEM32wow64cpu.dll
0x735d0000 C:WindowsSYSTEM32wow64win.dll
0x73630000 C:WindowsSYSTEM32wow64.dll
0x749e0000 C:Windowssyswow64cryptbase.dll
[REMOVED]

To get the address of the CreateFileA function in kernel32.dll, use the following code:

Python>ea = idc.get_name_ea_simple("kernel32_CreateFileA")
Python>print hex(ea)
0x768a53c6

To resume a suspended process, you can use the following code:

Python>idc.resume_process()
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.249.158