一份IDA Python的學習與使用記錄


0x00 常見的遍歷

函數的遍歷

for fn in idautils.Functions():
    print hex(fn), idc.get_func_name(fn)

除此之外,還可以使用idc.get_next_func(ea)idc.get_prev_func(ea)獲取下一個和上一個函數

block的遍歷

ida_gdl.py中定義了FlowChart和BasicBlock兩個類
idaapi.FlowChart()可針對函數或者一段區域生成圖
函數內block的遍歷

f_blocks = idaapi.FlowChart(idaapi.get_func(fn), flags=idaapi.FC_PREDS)
for block in f_blocks:
    print hex(block.start_ea)

其中指定FC_PREDS,可用來查看block的前驅節點
block后繼節點的遍歷

for succ in block.succs():
    print hex(succ.start_ea)

block前驅節點的遍歷

for pred in block.preds():
    print hex(pred.start_ea)

如果preds()返回的是空集,檢查flags是否被設置成FC_PREDS,更詳細的flag資料見[https://www.hex-rays.com/products/ida/support/sdkdoc/group___f_c__.html]
查看指定的block

id = 0x1
f_blocks = idaapi.FlowChart(idaapi.get_func(fn), flags=idaapi.FC_PREDS)
block = f_blocks[id]
print block.id

匯編指令的遍歷

BasicBlock類中這樣定義的block:[start_ea, end_ea)
遍歷block中的所有匯編指令

curr_addr = block.start_ea
while curr_addr < block.end_ea:
    print idc.GetDisasm(curr_addr)
    curr_addr = idc.NextHead(curr_addr, block.end_ea)

如果需要獲得block的最后一條指令,可以這樣寫:

addr = idc.PrevHead(block.end_ea)
print idc.GetDisasm(addr)

0x01 數據的訪問

函數與函數地址

  • 獲取函數名稱 idc.get_func_name(ea),ea在函數內部即可
  • 獲取函數屬性 idc.get_func_attr(ea, attr),這可以用來查看函數的首位地址,函數的FLAG等
idc.get_func_attr(ea, FUNCATTR_START)
idc.get_func_attr(ea, FUNCATTR_END)
idc.get_func_attr(ea, FUNCATTR_FLAGS)

指令

  • 獲取助記符 idc.print_insn_mnem(ea)
  • 獲取操作數 print_operand(ea, n)
  • 獲取操作數類型 get_operand_type(ea, n)

0x02 Tips

為了方便在ida中直接輸入使用,可以對Python代碼整理成一行,下面是兩個例子
查看當前函數的所有block

for block in idaapi.FlowChart(idaapi.get_func(idc.get_screen_ea())) : print "%d: [0x%x, 0x%x)" % ( block.id, block.startEA, block.endEA)

查看指定block的后繼節點

id=0x1;successors=idaapi.FlowChart(idaapi.get_func(idc.get_screen_ea()))[id].succs()
for block in successors: print "%d: [0x%x, 0x%x)" % ( block.id, block.startEA, block.endEA)

0x03 相關的學習資料


免責聲明!

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



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