Basic IDA Python Scripting

Today’s post is about some notes that I write down regarding IDA Python Scripting which I hope it benefits others and also a place for me to refer to in the future. I would like to apologize if there are any mistakes as I am still learning. Do comment on any errors I made and I will edit the post to correct them. Thank you!

Note: Some of the functions here are no longer applicable to IDA version 7.4 and above. The functions are still the same but with a new name. You can see the new function names for them here.

Today we will be talking about the basics of IDA Pro’s Python scripting. Let use see some of IDA’s in-built functions we can use to assist our reverse engineering.

Message():

Just like in C language and IDC, python in IDA allows you to print messages using the same format. Do take note that you must include semi colon to end that statement cause it is not a native Python’s statement. Below is an example of its usage.

Message(“%s\n”, “Hello!”);

Message(“Hello!\n);

print():

Alternatively, you can do a usual Python print message method like how you normally code in python using print. Below is an example of its usage.

print(“Hello!”)

long ScreenEA():

This is a build-in function that allows you to get the address of where the current cursor is. However, note that this function returns a long value, which is a decimal base. Hence, to obtain the same value you see in your IDA, you have to convert it into a hex base. To do that, wrap it with hex(). Example of usage:

Code:

print(ScreenEA())

print(hex(ScreenEA()))

Result:

4198400

0x401000L

string GetMnem(long address):

This in-built function allows you to get the text representation of the type of the instruction at that address. Example of results are: add, cmp, etc.

Usage example:

Code:

addr = ScreenEA()

print(GMnem(addr))

Result:

push

long NextHead(long address):

Gets the address of the next defined instruction or data based on the address you input as argument to NextHead(). A usage example below.

Code:

addr = ScreenEA()

newAdd = hex(NextHead(addr))

print(newAdd)

Result:

0x401001L

long PrevHead(long address):

Similar to NextHead(), the function does the opposite which it gets the address of the previous defined instruction or data based on the address you input as an argument to PrevHead(). Example below.

Code:

addr = ScreenEA()

newAdd = hex(NextHead(addr))

print(newAdd)

Result:

0x400FFDL

Boolean idc.Jump(long address):

Jump to the next defined instruction or data. Will return if it is successful.

Code:

addr = ScreenEA()

print(hex(addr ))

nextAddr = NextHead(addr)

print(hex(idc.Jump(nextAddr)))

Result:

0x401000L

0x401001L

PatchByte(long address, long value):

Changes the byte at the address to value (decimal base).

Code:

PatchByte(ScreenEA(), long(0x90))

Result:

Instruction at that address will become a NOP instruction if the byte of an instruction is 0x90, it is a NOP instruction.

void idaapi.add_hotkey(string hotkey, string function_name):

This helps to call the function that was passed to idaapi.add_hotkey() as a parameter when that hotkey was pressed.

Code:

def nop():

            PatchByte(ScreenEA(), long(0x90))

            MakeCode(ScreenEA())

             idc.Jump(NextHead(ScreenEA()))

idaapi.add_hotkey(“Ctrl-Shift-Alt-J”, nop)

Result:

When “Ctrl-Shift-Alt-J” hotkeys are all pressed, nop() will be call and the code inside the function will be executed. Hence, based on nop(), the current cursor location’s instruction will become a NOP instruction, change the instruction into code, (MakeCode() is the same as pressing hotkey ‘c’ in IDA), before jumping to the next instruction.

string idc.GetDisasm(long address):

Get the assembly instruction of that address. This includes the comment on the instruction as well.

Code:

print(idc.GetDisasm(ScreenEA())

Result:

mov eax, edx; “move content”

long get_name_ea_simple(string name):

Get the address of function or variables based on the name of it.

Code:

print(get_name_ea_simple(“a43438S911”))

Result:

4227208

string GetString(long address, long length, long strtype):

Get the string content from the address.

Length: Length of the string to get. -1 indicates get the content of the whole string.

strtype: The type of string. Refers to https://www.hex-rays.com/products/ida/support/idadoc/283.shtml or use GetStringType().

Code:

ea = ScreenEA()

print(GetString(ea, -1, GetStringType(ea)))

Result:

Hi!

long GetStringType(long address):

Get the type of string. Usually useful for GetString().

Code:

GetStringType(ScreenEA())

Result:

0

Boolean MakeComm(long address, string comment):

Puts comment onto that line (that address’s) of assembly instruction. The method will return a boolean if it is successful.

Code:

MakeComm(ScreenEA(), “Hello!”)

Result:

True

In-code:

mov eax, ebp ; Hello!

Boolean MakeRptCmt(long address, string comment):

Similar to MakeComm, this function puts repeatable comment onto that line (that address’s) of assembly instruction. The method will return a boolean if it is successful.

Code:

MakeComm(ScreenEA(), “Hello!”)

Result:

True

In-code:

mov eax, ebp ; Hello!

string GetOpnd(long address, int n):

Gets the operand of the instruction.

n: number of the operand

  1. n = 0, get the 1st operand.
  2. n = 1, get the 2nd operand.

In-code:

mov eax, [ebp+var_3]

Code:

GetOpnd(ScreenEA(), 0)

Result:

eax

long get_frame_id(long address):

Get the function’s frame structure’s id.

Address: Can be any address of that function you would like to inspect.

Code:

get_frame_id(ScreenEA())

Result:

4278190166

ptr StructMembers(long structID):

Get the members’ information of the structure based on the structure’s ID. If frame’s ID is sent to StructMembers(), it will return the stack variables’ information.

StructMembers() returns a list of the tuple which the content is this: (offset, name, size).

Code:

aList = StructMembers(get_frame_id(ScreenEA()))

for item in aList:

          print(item)

Result:

(4L, ‘var_264, 4)

(8L, ‘aName’, 1)

void set_member_name(long structPtr, long offset, string name):

This function sets the variable’s name. The offset will help to determine which variable to set. Note, the offset be the offset of the variable you want to set based on the frame pointer or structure pointer.

structPtr: Can be structure’s pointer or ID of frame. If ID of frame, variables of the stack will be renamed to what you want.

Code:

set_member_name(get_frame_id(ScreenEA()), 4, “a”)

Result:

mov [ebp+a], eax

object idautils.XrefsTo(long address, int flags):

This function returns objects that contains information of all reference to address. So basically it returns the same content as when you click on a variable or function and press on keyboard Ctrl_X. Main thing of this function is frm variable as it returns the address of that instruction that uses this variable or calls this function.

flags: You can choose any of the flags from the link below. The constant must be ida_xref.XREF_* where * can be ALL, FAR, etc. See the link: https://www.hex-rays.com/products/ida/support/idapython_docs/ida_xref-module.html

idautils.XrefsTo() returns an object take contains these variables:

  1. type variable: description
  2. long type: Cross-reference type codes. Can use XrefTypeName(long type) to convert cross-reference type codes to readable names.
  3. long frm: Address that reference to address used as this function’s argument.
  4. long to: Address that you input as address used as this function’s argument.
  5. long iscode: Contains 0 or 1. If is 1, means address used as this function’s argument is a code.

Code:

for xrefs in idautils.XrefsTo(ScreenEA(), 0):

          print(hex(xrefs.frm))

Result:

0x401a42L

0x401a62L

Other links that you can check it out which contains similar to what I have written for this post:
https://www.hex-rays.com/products/ida/support/idapython_docs/ida_kernwin-module.html

I hope this article will be helpful to you. Feel free to leave any comments below. You may also send me some tips if you like my work and want to see more of such content. Funds will mostly be used for my boba milk tea addiction. The link is here. 🙂

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.