Operands(操作數)
- 獲取操作數的助記符我們可以調用 idc.GetOpnd(ea,long n)。 第一個參數是地址,第二個 long n
是操作數索引。第一個操作數是 0 和第二個是 1。 - idc.GetOpType(ea,n)得到的操作數的類型。ea 是地址,n 是索引
idc.o_void
如果一個指令沒有任何操作數它將返回 0。
idc.o_reg
如果一個操作數是一個普遍的寄存器將返回此類型。這個值在內部表示爲 1。
idc.o_mem
如果一個操作數是直接內存引用它將返回這個類型。這個值在內部表示爲 2。這種類型
是有用的在 DATA 段查找引用。
idc.o_phrase
這個操作數被返回則這個操作數包含一個基本的寄存器或一個索引寄存器。這個值在內
部表示爲 3。
idc.o_displ
這個操作數被返回則操作數包含寄存器和一個位移值,這個爲位移值是一個整數,例如
0x18。這是常見的當一條指令訪問值在一個結構中。在內部,它表示爲 4 的值。
idc.o_imm
操作數是這樣一個爲整數的 0xc 的值的類型。它在內部表示爲 5。
idc.o_far
這個操作數不是很常,見當逆向 x86 或 x86_64
時。它是用來尋找操作數的訪問立即數遠 地址的。它在內部表示爲 6。
idc.o_near
這個操作數不是很常見,當逆向 x86 或 x86_64
時。它是用來尋找操作數的訪問立即數近 地址的。它在內部表示爲 7。
Instructions(指令)
- idautils.Functions()將返回一個已知函數列表。這個列表將包含起始地址的每一個函數。idautils.Functions()可傳遞的參數範圍內搜索。如果我們想要搜索可以通過開始地址和結束地址 idautils.Funtions(start_addr, end_addr) 。
- idc.GetFunctionName(func_ea),返回函數名稱
- idc.GetMnem(ea):獲取指令名稱
- 鄰近指令:
獲得下一條指令地址: idc.NextHead(ea)
獲得前一條指令地址idc.PrevHead(ea)。
這些功能將得到下一個指令的開始而不是下一個地址
- 鄰近地址
得到下一個地址我們使用idc.NextAddr(ea)
得到前一個地址我們使用 idc.PrevAddr(ea)
Xrefs(交叉引用)
- 通過調用idautils.CodeRefsTo(ea, flow)。它能通過遍歷將返回一個迭代器。ea是我們想要得到 的交叉引用的地址。參數流是一個 bool類型。它被用來指定是否要遵照正常的代碼流。然後顯示每一個交叉引用的地址。
獲得內存值
- 整形:idc.Byte(ea)/idc.Word(ea)/idc.Dword(ea)/idc.Qword(ea)
- 浮點數:idc.GetFloat(ea)/idc.GetDouble(ea)
Patch
- 按字節patch:idc.PatchByte(ea, value)
示例
addr = 0x401500
for i in range(0xBA):
PatchByte(addr+i, Byte(addr+i)^0x41)
-
按字:idc.PatchWord(ea, value)
-
按雙字:idc.PatchDword(ea, value)
命令行
有時我們需要使用IDA對大量二進制文件進行分析,這個時候我們就需要使用IDA的命令行模式來進行批量操作
命令行指令
基礎命令如下:
ida(ida64) input-file (Start graphical interface)
idat input-file (Start text interface)
我們還需要添加一下參數,常用參數如下:
-h幫助界面
-L表示輸出的日誌路徑
-c表示對二進制文件進行反彙編(刪除舊的數據庫)
-A表示自動模式,IDA不會提示一些信息,會自動處理
-S後面的路徑是分析腳本的路徑
注意!!其中,-L和-S與後面的路徑之間是沒有空格的。
所有參數請見官網:IDA Help: Command line switches
分析腳本
def analysis():
# 這裏是分析的代碼
pass
def main():
"""
控制器
"""
idc.Wait() # 等IDA分析完後才執行
analysis()
idc.Exit(0) # 關閉IDA
if __name__ == "__main__":
main()
因爲我們要批量分析,就需要重複執行指令,寫一個調用腳本來自動執行:
# -*- coding:utf-8 -*-
# =======Import =======
import os
import subprocess
dir_path = "D://transfer/" # 原始數據的文件夾
ida64_path = "D://ProgramFiles/IDA/ida64.exe" # ida64的路徑
ana_file = "D://listFunc/analysis.py" # 分析文件的路徑
def run():
for root, dirs, files in os.walk(dir_path):
for file_name in files:
file_path = os.path.join(root, file_name)
cmd = "{0} -LD:/mylog.log -c -A -S{1} {2}".format(ida64_path, ana_file, file_path)
p = subprocess.Popen(cmd)
p.wait()
if __name__ == "__main__":
run()
遇到的問題
- unknown file extension
可能是因爲ida python的解釋器沒有正常執行,這裏因爲我用的是免安裝版的IDA,猜測可能路徑沒有配置對,後面換了一個安裝版的就解決了