因為網上對於IDApython的介紹太少,所以在這裡列舉了一些常用函數: ScreenEA() 獲取 IDA 調試視窗中,游標指向代碼的地址。通過這個函數,我們就能夠從一個已知 的點運行我們的腳本。 GetInputFileMD5() 返回 IDA 載入的二進位文件的 MD5 值,通過這個值能夠判斷 ...
因為網上對於IDApython的介紹太少,所以在這裡列舉了一些常用函數:
ScreenEA()
獲取 IDA 調試視窗中,游標指向代碼的地址。通過這個函數,我們就能夠從一個已知 的點運行我們的腳本。
GetInputFileMD5()
返回 IDA 載入的二進位文件的 MD5 值,通過這個值能夠判斷一個文件的不同版本是否 有改變。
FirstSeg()
訪問程式中的第一個段。
NextSeg()
訪問下一個段,如果沒有就返回 BADADDR。
SegByName( string SegmentName )
通過段名字返回段基址,舉個例子,如果調用.text 作為參數,就會返回程式中代碼段的開始位置。
SegEnd( long Address )
通過段內的某個地址,獲得段尾的地址。
SegStart( long Address )
通過段內的某個地址,獲得段頭的地址。
SegName( long Address )
通過段內的某個地址,獲得段名。
Segments()
返回目標程式中的所有段的開始地址。
Functions( long StartAddress, long EndAddress )
返回一個列表,包含了從 StartAddress 到 EndAddress 之間的所有函數。
Chunks( long FunctionAddress )
返回一個列表,包含了函數片段。每個列表項都是一個元組(chunk start, chunk end)
LocByName( string FunctionName )
通過函數名返回函數的地址。
GetFuncOffset( long Address )
通過任意一個地址,然後得到這個地址所屬的函數名,以及給定地址和函數的相對位移。 然後把這些信息組成字元串以"名字+位移"的形式返回。
GetFunctionName( long Address )
通過一個地址,返回這個地址所屬的函數。
CodeRefsTo( long Address, bool Flow )
返回一個列表,告訴我們 Address 處代碼被什麼地方引用了,Flow 告訴 IDAPython 是否要 跟蹤這些代碼。
CodeRefsFrom( long Address, bool Flow )
返回一個列表,告訴我們 Address 地址上的代碼引用何處的代碼。
DataRefsTo( long Address )
返回一個列表,告訴我們 Address 處數據被什麼地方引用了。常用於跟蹤全局變數。
DataRefsFrom( long Address )
返回一個列表,告訴我們 Address 地址上的代碼引用何處的數據。
Heads(start=None, end=None)
得到兩個地址之間所有的元素
GetDisasm(addr)
得到addr的反彙編語句
GetMnem(addr)
得到addr地址的操作碼
BADADDR
驗證是不是錯誤地址
GetOpnd(addr,long n)
第一個參數是地址,第二個long n是操作數索引。第一個操作數是0和第二個是1。
idaapi.decode_insn(ea)
得到當前地址指令的長度
idc.FindFuncEnd(ea)
找到當前地址的函數結束地址
Entries()
入口點信息
Structs()
遍歷結構體
StructMembers(sid)
遍歷結構體成員
DecodePrecedingInstruction(ea) 獲取指令結構
DecodePreviousInstruction(ea)
DecodeInstruction(ea)
Strings(object) 獲取字元串
GetIdbDir() 獲取idb目錄
GetRegisterList() 獲取寄存器名錶
GetInstructionList 獲取彙編指令表
atoa(ea) 獲取所在段
Jump(ea) 移動游標
Eval(expr) 計算表達式
Exec(command) 執行命令行
MakeCode(ea) 分析代碼區
MakeNameEx(ea, name, flags) 重命名地址
MakeArray(ea, nitems) 創建數組
MakeStr(ea, endea) 創建字元串
MakeData(ea, flags, size, tid) 創建數據
MakeByte(ea)
MakeWord(ea)
MakeDWord(ea)
MakeQWord(ea)
MakeOWord(ea)
MakeYWord(ea)
MakeFlot(ea)
MakeDouble(ea)
MakePackReal(ea)
MakeTbyte(ea)
MakeStructEx(ea)
MakeCustomDataEx(ea)
PatchByte(ea, value) 修改程式位元組
PatchWord(ea, value)
PatchDword(ea, value)
PatchByte(ea, value)
PatchByte(ea, value)
Byte(ea) 將地址解釋為Byte
Word(ea)
DWord(ea)
QWord(ea)
GetFloat(ea)
GetDouble(ea)
GetString(ea, length = -1, strtype = ASCSTR_C) 獲取字元串
GetCurrentLine() 獲取游標所在行反彙編
ItemSize(ea) 獲取指令或數據長度
FindText(ea, flag, y, x, searchstr)查找文本
FindBinary(ea, flag, searchstr, radix=16) 查找16進位
GetEntryPointQty() 獲取入口點個數
GetEntryOrdinal(index) 獲取入口點地址
GetEntryName(ordinal) 入口名
idc.GetFunctionAttr(ea, attr) //得到當前地址所在函數的數據
(
FUNCATTR_START = 0 # function start address
FUNCATTR_END = 4 # function end address
FUNCATTR_FLAGS = 8 # function flags
FUNCATTR_FRAME = 10 # function frame id
FUNCATTR_FRSIZE = 14 # size of local variables
FUNCATTR_FRREGS = 18 # size of saved registers area
FUNCATTR_ARGSIZE = 20 # number of bytes purged from the stack
FUNCATTR_FPD = 24 # frame pointer delta
FUNCATTR_COLOR = 28 # function color code
FUNCATTR_OWNER = 10 # chunk owner (valid only for tail chunks)
FUNCATTR_REFQTY = 14 # number of chunk parents (valid only for tail chunks)
)
class DbgHook(DBG_Hooks):
# Event handler for when the process starts
def dbg_process_start(self, pid, tid, ea, name, base, size)
return
# Event handler for process exit
def dbg_process_exit(self, pid, tid, ea, code):
return
# Event handler for when a shared library gets loaded def
dbg_library_load(self, pid, tid, ea, name, base, size):
return
# Breakpoint handler
def dbg_bpt(self, tid, ea):
return
這個類包含了我們在創建調試腳本時,會經常用到的幾個調試事件處理函數。安裝 hook 的方式如下:
debugger = DbgHook()
debugger.hook()
現在運行調試器,hook 會捕捉所有的調試事件,這樣就能非常精確的控制 IDA 調試器。 下麵的函數在調試的時候非常有用:
AddBpt( long Address )
在指定的地點設置軟體斷點。
GetBptQty()
返回當前設置的斷點數量。
GetRegValue( string Register )
通過寄存器名獲得寄存器值。
SetRegValue( long Value, string Register )
這個是用IDApytohon編寫的查找strcpy函數以及他的參數是否在棧區域
1 def is_stack_buffer(addr, idx): 2 inst = DecodeInstruction(addr) 3 4 # IDA < 7.0 5 try: 6 ret = get_stkvar(inst[idx], inst[idx].addr) != None 7 # IDA >= 7.0 8 except: 9 from ida_frame import * 10 v = inst[idx].addr 11 if sys.maxint < v: 12 v = twos_compl(v) 13 ret = get_stkvar(inst, inst[idx], v) 14 return ret 15 16 def find_arg(addr,arg_num): ##This is x86 17 function_h=LocByName(GetFunctionName(addr)) 18 step=0 19 arg_cou=0 20 while step<0 : 21 step=step+1 22 addr=idc.PrevHead(addr) 23 op=GetMnem(addr).lower() 24 if op in ("ret","jmp","retn","b") or addr<function_h: 25 return 26 if op =="push": 27 arg_count=arg_count+1 28 if arg_count==arg_num: 29 return GetOpnd(addr,0) 30 31 for functionaddr in Functions(): 32 if "strcpy" in GetFunctionName(functionaddr): 33 xref=CodeRefsTo(functionaddr,0) 34 for xxx in xref: 35 if GetMnem(xxx).lower()=="call": 36 oped= find_arg(xxx,1) 37 function_h=LocByName(GetFunctionName(xxx)) 38 addr_=xxx 39 lalal=xxx 40 while True: 41 __add=idc.PrevHead(addr_) 42 __op=GetMnem(__add).lower() 43 44 if __op in ("ret", "retn", "jmp", "b") or __add < function_h: 45 break 46 if __op == "lea" and GetOpnd(__add,0)==oped: 47 if is_stack_buffer(addr_,1): 48 prinf "STACK at 0x%X"%lalal 49 break 50 if __op == "mov" and GetOpnd(addr_,0)==oped: 51 op_type = GetOpType(addr_, 1) 52 if op_type == o_reg: 53 oped = GetOpnd(addr_, 1) 54 lalal = addr_ 55 else: 56 break