Pengantar IDAPython


Tidak ada banyak artikel tentang bekerja dengan IDAPython dalam bahasa Rusia (dan di Habr, khususnya), kami akan mencoba mengisi celah ini.


Untuk siapa. Bagi yang sudah tahu cara bekerja di IDA Pro, tetapi belum pernah menulis skrip di IDAPython. Jika Anda sudah memiliki pengalaman menulis skrip di bawah IDAPython, Anda tidak akan menemukan sesuatu yang baru di sini.


Apa yang tidak akan ada di sini. Kami tidak akan mengajarkan pemrograman Python dan pekerjaan dasar di IDA Pro.


0x00.


, IDAPython β€” - Python, IDA . IDAPython "" IDC ( - IDA Pro).


, IDAPython , API . IDAPython python IDA ( C:\Program Files\IDA 7.0\python).


IDA Pro 7.0. IDAPython IDA "" ( ). IDA 7.4 Python 2.7 64-bit.



7- IDAPython API, 7.4 API. idc_bc695.py , - . 2017 API, .


0x01.


IDAPython β€” , , , .


:


  • ,
  • /,
  • / ( , ),
  • - /,
  • .

, β€” .



IDAPython :


  • ea β€” Effective Address β€” IDA, ;
  • here() , Disassembly-. β€” long;
  • idc, . , ;
  • "" ELF.


IDAPython :


  • IDA;
  • File β€” Script file (Alt + F7);
  • File β€” Script command (Shift + F2);
  • IDA Pro -S.

.


IDA CLI


IDA. , , Python.



Python CLI


IDA CLI


  • Python.
  • (, , ) , .
  • Tab.
  • .
  • help dir Python .
  • Output window (Alt + 0).


Segments idautils , IDA. Output window IDA CLI:


Python>import idautils
Python>help(idautils.Segments)
Help on function Segments in module idautils:
Segments()
Get list of segments (sections) in the binary image
@return: List of segment start addresses.
Python>for ea in idautils.Segments():
Python> print("%08x %s" % (ea, idc.get_segm_name(ea)))
Python>
08000000 .isr_vector
080000c0 .text
08006f9c .rodata
08007a14 .init_array
08007a18 .fini_array
20000000 .data
200001f8 .bss
200006c8 ._user_heap_stack
200017f8 abs

Script File


File β€” Script file (Alt + F7) .


(Hex / Char / Decimal). op_, :


  • op_bin(ea, n) β€” ;
  • op_dec(ea, n) β€” ;
  • op_oct(ea, n) β€” ;
  • op_hex(ea, n) β€” hex-;
  • op_chr(ea, n) β€” ;
  • op_seg(ea, n) β€” ;
  • op_stkvar(ea, n) β€” ;
  • op_stroff(ea, n) β€” ;
  • op_enum(ea, n) β€” ENUM-;
  • op_plain_offset(ea, n, base) β€” .

:


  • ea β€” , ;
  • n β€” ( ); mov eax, 0x10:
    • eax β€” 0- ;
    • 0x10 β€” 1- ;
  • base β€” offset- () .

IDA 7.0 Python 2.7, ( ).
:


# coding: utf-8
""" 
File: transforms.py
   
"""

START = 0x08000038
END = 0x08000084

def make_offsets32(start_ea, end_ea):
    """     """
    for ea in xrange(start_ea, end_ea, 4):
        idc.op_plain_offset(ea, 0, 0)

def make_dwords(start_ea, end_ea):
    """   32-   hex-"""
    for ea in xrange(start_ea, end_ea, 4):
        idc.op_hex(ea, 0)

if __name__ == '__main__':
    make_dwords(START, END)

Python, IDA. make_dwords START END. , , IDA CLI.


IDA Recent scripts ( View β€” Recent scripts Alt + F9):



: IDAPython-, , IDA, Python 2 , IDA .


Script Command


File β€” Script command (Shift + F2) IDA. , , . , .


. Run.



IDA c -S


IDA Pro, , . ( F1) Command line switches.


, :


> "C:\Program Files\IDA 7.0\ida.exe" -A -Sscript_name.py rhino.idb


  • -A ,
  • -S script_name.py IDB-.

/


:


  • print Output window (Alt + 0);
  • Output window Disassembly- , IDA. Output window , Disassembly-.

Python>here()
134239060         # 1.    
Python>hex(here())
0x8005354L        # 2.    
Python>"%08x" % here()
08005354          # 3.   
Python>get_name(here())
aErrorWrongHead   # 4.   

  • input/raw_input ;
  • ask_- ida_kernwin idaapi.



IDAPython , "" IDA Pro. IDA 7- .


IDAPython- ( β€” " ").


IDAPyHelper


, , . IDAPython IDAPyHelper, .



IDAPython Cheatsheet


IDAPython . β€” .



0x02.


.


. , , (Xrefs X), .



, , . IDAPython.


memcpy. , 11 memcpy.



:


  • - memcpy;
  • memcpy ;
  • ;
  • .

:


  • idautils.CodeRefsTo(func_ea, flow) β€” , - . flow ( 0/1) , . flow = 0;
  • idc.prev_head(ea) β€” , ;
  • idc.get_operand_value(ea, n) β€” n- . , . ARM :
    • R0 β€” 0;
    • R1 β€” 1;
    • R2 β€” 2 ;
  • idc.get_operand_type(ea, n) β€” n- . :
    • o_void = 0 β€” (, NOP);
    • o_reg = 1 β€” ;
    • o_mem = 2 β€” ;
    • o_phrase = 3 β€” [Base Reg + Index Reg],
    • o_displ = 4 β€” [Base Reg + Index Reg + Displacement];
    • o_imm = 5 β€” -;
    • o_far = 6 β€” FAR-;
    • o_near = 7 β€” NEAR-;
    • ;
  • idc.print_operand(ea, n) β€” ;
  • idc.set_cmt(ea, comment, repeat) β€” (. ).


ARM (R0-R3), :


  • ;
  • , R0, R1, R2 ( memcpy 3 );
  • , hex- , .

IDA


IDA :


β€” , . idc.set_cmt(ea, comment, rpt) repeat = 0:



(repeatable) β€” , . idc.set_cmt(ea, comment, rpt) repeat = 1:



() β€” idc.update_extra_cmt(ea, n, comment):



.



# coding: utf-8
"""
File: funcargs.py
       
"""

import idautils

MEMCPY = 0x08006B26

def get_function_arg(ea, narg):
    """  n-   """
    while True:
        ea = idc.prev_head(ea)
        if idc.get_operand_value(ea, 0) == narg:
            break
    if idc.get_operand_type(ea, 1) in (idc.o_imm, idc.o_mem):
        res = "0x%x" % idc.get_operand_value(ea, 1)
    else:
        res = idc.print_operand(ea, 1)  
    return res

def set_comment_by_args(func_ea, nargs):
    """      """
    for ea in idautils.CodeRefsTo(func_ea, flow=0):
        func_args = []
        for i in range(0, nargs):
            arg = get_function_arg(ea, i)
            func_args.append(arg)
        args = ', '.join(a for a in func_args)  
        comment = "(%s)" % args
        idc.set_cmt(ea, comment, 0)

if __name__ == '__main__':
    set_comment_by_args(MEMCPY, 3)

-:



0x03.


, get_function_arg:


def get_function_arg(ea, narg):
    """ n-   (  )"""
    while True:
        ea = idc.prev_head(ea)
        if idc.get_operand_value(ea, 0) == narg:
            break

    if idc.get_operand_type(ea, 1) in (idc.o_imm, idc.o_mem):
        res = "0x%x" % idc.get_operand_value(ea, 1)
    else:        
        res = idc.print_operand(ea, 1)  

    return res

, , . x86, . n- push :


def get_function_arg_value(ea, narg):
    """ 
     n-   (  ).
       .
    """
    i = 0
    while True:
        ea = idc.prev_head(ea)
        if idc.print_insn_mnem(ea) == "push":
            if i == narg: break
            i += 1

    res = idc.get_operand_value(ea, 0)
    return res

0x04.


– ( , , assert). . "sendMsg error %s", "recvMsg error" "freeMsg error".



, , , . , .


, , sub_8006690:



x_printf.


0x08005034 R0 "sendMsg error %s\r\n". : , 0x08005040:


Python>"%08x" % get_operand_value(here(), 1)
08005040

ARM :


  • ( – 2 );
  • 32- , , (PC).

IDA , , .


, :


  1. x_printf idautils.CodeRefsTo
  2. ( R0) idc.get_operand_value ( get_function_arg, ).
  3. idc.get_wide_dword.
  4. idc.get_strlit_contents.
  5. , .
  6. "" , idc.set_name.

:


# coding: utf-8

import idautils

PRINTF = 0x08006690

def get_function_arg(ea, narg):
    """ n-  """
    while True:
        ea = idc.prev_head(ea)
        if idc.get_operand_value(ea, 0) == narg:
            break

    if idc.get_operand_type(ea, 1) == idc.o_mem:
        res = idc.get_operand_value(ea, 1)
    else:        
        res = idc.BADADDR

    return res

def get_func_name(str_log):
    """     """
    words = str_log.split(' ')
    if len(words) > 1 and words[1].startswith("error"):
        return words[0]
    else:
        return ""

def rename_by_log_str(log_func):
    """ ,   log_func   """
    for ea in idautils.CodeRefsTo(log_func, 0):
        arg = get_function_arg(ea, 0)
        if arg == idc.BADADDR:
            continue
        str_addr = idc.get_wide_dword(arg)
        str_log = idc.get_strlit_contents(str_addr)
        func_name = get_func_name(str_log)
        if func_name:
            print("0x%08x - 0x%08x - %s" % (arg, str_addr, func_name))

if __name__ == '__main__':
    rename_by_log_str(PRINTF)

, ( – get_func_name) .


0x05.


IDA . , , , . , , , .


– .


:


  • idc.get_color(ea, what) – ;
  • idc.set_color(ea, what, color) – ;
    • RGB hex- 0xBBGGRR (--)
    • what :
      • idc.CIC_ITEM = 1 – ;
      • idc.CIC_FUNC = 2 – ;
      • idc.CIC_SEGM = 3 – .

,


for i, ea in enumerate(xrange(0x08005196, 0x080051AE, 2)):
    idc.set_color(ea, CIC_ITEM, 0x0f << (2 * i))

0x08005196 0x080051AE :



, ARM- , , :



: .


:


  1. . idautils.Segments(), .
  2. . idc.get_segm_attr(segm, attr), . SEG_CODE ( β€” SEGATTR_TYPE) .
  3. . idautils.Heads(start, end), (, ) start end.
  4. idc.get_full_flags(ea) is_code(flags) , ea.
  5. .

:


BLUE = 0xF2D0AF
PINK = 0xAFD0F2

def colored_code():
    """        """

    code_segmnets = filter(lambda segm: \
                          idc.get_segm_attr(segm, SEGATTR_TYPE) == SEG_CODE,\
                          idautils.Segments())

    for segm in code_segmnets:
        end = idc.get_segm_end(segm)
        for ea in idautils.Heads(segm, end):
            flags = idc.get_full_flags(ea)
            if idc.is_code(flags):
                idc.set_color(ea, CIC_ITEM, BLUE)
            else:
                idc.set_color(ea, CIC_ITEM, PINK)


, is_code(flags) , . get_full_flags(ea).


colored_code :



, IDAPython , ( idautils.Segments idautils.Heads), (idc.set_color), (idc.get_strlit_contents) (idc.get_wide_dword).




All Articles