[讨论]IDA Pro 在动态调试中,大家都是如何追踪函数的?
在用 IDA Pro 调试安桌应用时,想知道应用调用函数的流程,希望把执行过的函数打印出来,但用 IDA 的函数追踪与指令追踪都追不到,每次一开始追踪就会中断导致退出调试!用 idc 脚本虽然不会退出,但还是追踪不到函数与指令!比如我追踪应用里一个函数用下面的代码:
AddBpt(0xE3D444BC)
AddBpt(0xE3D44AD2)
GetDebuggerEvent(WFNE_SUSP, -1)
RunTo(0xE3D444BC)
EnableTracing(1, 1)
RunTo(0xE3D44AD2)
上面的代码追不到指令流程,函数只追到当前的函数,当前函数内执行的很多函数追不到!
后来通过脚本对所有函数下断点并将断点设置为追踪,当断点发生时打印函数名与地址,此方法虽然可行,但也只能对一部分函数设置断点,因为应用比较大,全部函数有4万多个,全部下断点会耗时过长导致退出!所以只能对应用内的某个模块的函数下断点,但该模块外的其它函数执行时追不到!所以不知道该模块运行时还调用了哪些外部的函数!
在 IDA 调试过程中能不能获取堆栈的数据?或者动态监视堆栈与内存的改变从而获取内存的内容?尝试过用 pyEMU,但总是提示缺少 pydasm 模块名的错误,试过2.5,2.6,2.7三个版都不行,不知什么原因!另外这个 pyEMU 是不是只能用于x86的汇编?我调试的应用是 arm 的汇编指令。为了追踪应用的函数执行流程,我试了几个 IDA 的版本都不行,在 win 下用过 6.4,6.8,7.0,现在在 linux 下用 6.4版的 IDA 也不行!
附函数断点代码:
# funcFlow.py
from idaapi import *
from idc import *
bs = {}
class funcFlow(DBG_Hooks):
# breakpoint handler
def dbg_bpt(self, tid, ea):
global bs
n = Name(ea)
k = "k_%x" % ea
bs.setdefault(k, 0)
bs[k] += 1
if(bs[k] > 10):
DelBpt(ea)
r = []
z = 0
while(z < 13):
v = "r%d" % z
r.append(GetRegValue(v))
z += 1
#r13 = GetRegValue("r13")
#r14 = GetRegValue("r14")
#r15 = GetRegValue("r15")
s = "addr= 0x%x ; name= %s ; count= %d; R0=%x; R1=%x; R2=%x; R3=%x; R4=%x; R5=%x; R6=%x; R7=%x; R8=%x; R9=%x; R10=%x; R11=%x; R12=%x" % (ea, n, bs[k], r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12])
print(s)
f = open("/home/oem/apk/blist.txt", "a")
f.write(s+"\n\n")
f.close()
return
try:
if funcflow:
print("Removing previous hook ...")
funcflow.unhook()
except:
pass
# add hook
funcflow = funcFlow()
funcflow.hook()
# add breakpoint
f = open("/home/oem/apk/flist.txt", "r")
n = AskStr("0x2", "addr: ")
n = int(n, 16)
y = 0
z = 0
while z < 40000:
z += 1
a = f.readline()
b = a.find("RedB")
if b < 0: continue
b = a.find("addr=")
if b != -1:
y += 1
c = a[b+5:b+13]
c = int(c, 16)
c += n
AddBpt(c)
SetBptAttr(c, BPTATTR_FLAGS, BPT_ENABLED|BPT_TRACE)
print("num=%d; addr=%x" % (y, c))
f.close()