基於python3.x IDAPython第二講 段 函數 匯編指令等操作


IDA Python 之 匯編指令丶 段丶 函數

一丶簡介

​ 在IDA中我們常見的就是匯編. 段. 交叉引用. 這一講我們就介紹一下匯編指令與段操作.
前面文章導航
[第一講地址操作字節操作][https://www.cnblogs.com/iBinary/p/14642662.html]

二丶匯編中的指令操作

首先如下圖所示:

我們現在要分別獲取 movups , xmmword ptr,xmm0 等類似匯編的操作.

那么看一下對應函數分別是那些吧.

指令 使用以及作用 高版本替代函數
idc.GetDisasm(addr) 獲取地址處的匯編語句 如: mov ebp,esp 無替代
idc.GetDisasmEx(addr,flags) 更高級的獲取.帶有標志. 一般是給一個0 高版本已經被替代 idc.generate_disasm_line(addr,flags)
idc.GetOpnd(addr,index) 獲取指定地址位置的操作數.參數1是地址.參數2是操作數索引.如 mov ebp,esp ebp是操作數1 esp是操作數2 mov則是匯編指令不是操作數 idc.print_operand(addr,index)
idc.GetMnem(addr) 操作匯編指令 mov ebp,esp 獲取mov idc.print_insn_mnem(addr)
idaapi.get_imagebase() 獲取基地址
idc.GetOpType(ea,index) 獲取操作數的類型 idc.get_operand_type(addr,index)
idc.GetOperandValue(addr,index) 獲取指定索引操作數中的值: 如 calll 0x00402004 對應匯編為: FF 15 04 20 40 00 FF15=Call 而操作數的值則為04 20 40 00 (小端) 使用函數之后獲取則為地址 00402004 get_operand_value(addr,index)
idc.NextHead 獲取下一行匯編 idc.next_head(ea)
idc.PrevHead 獲取上一行匯編 idc.PrevHead(ea)

實戰:

import idc
import idaapi
import idautils

ea = idc.here();
print("當前模塊基址為: {}".format(hex(idaapi.get_imagebase())))
print("當前的匯編語句為: {}".format(idc.GetDisasm(ea)))
print("當前的匯編指令為: {}".format(idc.print_insn_mnem(ea)))
print("當前的操作數為: {}".format(idc.print_operand(ea,0)))
print("當前的操作數值為: {}".format(idc.get_operand_value(ea,0)))

三丶IDA中的段操作

對於一個段最直觀的介紹就是他的名字 起始地址 結束地址等.

那么介紹一下段操作中的函數吧.

指令 作用 新函數
idc.SegName(addr) 獲取段的名字 idc.get_segm_name(addr)
idc.SegStart(addr) 獲取段的開始地址 idc.get_segm_start(addr)
idc.SegEnd(addr) 獲取段的結束地址 idc.get_segm_end(addr)
idautil.Segments() 返回一個列表記錄所有段的地址
idc.FirstSeg() 獲取第一個段 idc.get_first_seg(addr)
idc.NextSeg(addr) 獲取下一個段 參數是當前段的地址 返回的是下一個段的地址 idc.get_next_seg(addr)

上述返回值如果是獲取地址的函數 獲取不到都會返回 0xFFFFFFF 也就是 BADADDR

利用上述函數則可以遍歷一個段輸出其內容

腳本如下:

import idc
import idaapi
import idautils

for seg in idautils.Segments():
    segname = idc.get_segm_name(seg)
    segstart = idc.get_segm_start(seg)
    segend   = idc.get_segm_end(seg)
    print("段名 = {} 起始地址= {} 結束地址 = {} ".format(segname,hex(segstart),hex(segend)));
    

四丶IDA中的函數操作

IDA 關於函數也有很多常見功能. 比如可以獲取所有函數 函數參數 函數名.函數屬性 以及誰調用了函數.

老函數 作用 新函數
Functions(startaddr,endaddr) 獲取指定地址之間的所有函數
idc.GetFunctionName(addr) 獲取指定地址的函數名 idc.get_func_name(addr)
idc.GetFunctionCmt 獲取函數的注釋 get_func_cmt(ea, repeatable) 1是地址 2是0或1 1是獲取重復注釋 0是獲取常規注釋
idc.SetFunctionCmt 設置函數注釋 set_func_cmt(ea, cmt, repeatable)
idc.ChooseFunction(title) 彈出框框要求用戶進行選擇 參數則是信息 idc.choose_func(title)
idc.GetFuncOffset(addr) 返回: addr 距離函數的偏移形式 idc.get_func_off_str(addr)
idc.FindFuncEnd(addr) 尋找函數結尾,如果函數存在則返回結尾地址,否則返回BADADDR idc.find_func_end(addr)
idc.SetFunctionEnd(addr,newendaddr) 設置函數結尾 ida_funcs.set_func_end
ida_funcs.func_setstart(addr,newstartaddr) 設置函數開頭 ida_funcs.set_func_start(addr, newstart)
idc.MakeName(addr, name) 與之同名了還有Ex函數 設置地址處的名字 idc.set_name(ea, name, SN_CHECK) Ex函數也使用set_name
idc.PrevFunction 獲取首個函數 idc.get_prev_func
idc.NextFunction 獲取下一個函數 idc.get_next_func

下面請看函數使用例子:

腳本:

import idc
import idaapi
import idautils

for seg in idautils.Segments():
    segname = idc.get_segm_name(seg)
    segstart = idc.get_segm_start(seg)
    segend   = idc.get_segm_end(seg)
    print("段名 = {} 起始地址= {} 結束地址 = {} ".format(segname,hex(segstart),hex(segend)));
    if (segname == '.text'):
        for funcaddr in Functions(segstart,segend):
            funname = idc.get_func_name(funcaddr)
            funend =  idc.find_func_end(funcaddr)
            funnext = idc.get_next_func(funcaddr)
            funnextname = idc.get_func_name(funnext)
            print("當前函數名 = {} 當前結束地址 = {} 下一個函數地址 = {} 下一個函數名= {}  ".format(funname,hex(funend),hex(funnext),funnextname))
            

ea = idc.get_screen_ea()
funnextoffset = idc.get_func_off_str(ea)
print("當前選擇地址距離當前函數的偏移為: {} ".format(funnextoffset))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM