首页
社区
课程
招聘
未解决 [讨论]IDA Pro 在动态调试中,大家都是如何追踪函数的?
发表于: 2018-12-29 19:17 8756

未解决 [讨论]IDA Pro 在动态调试中,大家都是如何追踪函数的?

2018-12-29 19:17
8756

[讨论]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()


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (8)
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
r13,r14,r15 三个寄存器为什么取不到?用 GetRegValue() 会报错:
File "/home/oem/apk/funcFlow.py", line 21, in dbg_bpt
    r.append(GetRegValue(v))
  File "/file/linux/soft/idapro64/python/idc.py", line 7718, in GetRegValue
    assert res, "get_reg_val() failed, bogus register name ('%s') perhaps?" % name
AssertionError: get_reg_val() failed, bogus register name ('r13') perhaps?
E3D3358A: used software breakpoint instead of temporary hardware breakpoint
Exception in DBG Hook function: Swig director method error. Error detected when calling 'DBG_Hooks.dbg_bpt'
Traceback (most recent call last):
2018-12-29 19:20
1
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
看了一下 IDA Pro 的帮助文档,发现有这个函数:
// Return the address of the specified event
//   tev - event number
long GetTevEa(long tev);

#define TEV_NONE  0 // no event
#define TEV_INSN  1 // an instruction trace
#define TEV_CALL  2 // a function call trace
#define TEV_RET   3 // a function return trace
#define TEV_BPT   4 // write, read/write, execution trace
#define TEV_MEM   5 // memory layout changed
#define TEV_EVENT 6 // debug event

谁知道这个怎么用?
2018-12-29 19:22
0
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
对于获取到的寄存器的值,怎么判断是十六进制值还是整数值,如果是十六进制值我想把这个地址的内存数据读一部分出来
2018-12-29 19:25
0
雪    币: 73
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
兄弟  脚本有没有兴趣写    是DNF脚本    不需修改内存模拟真人鼠标键盘操作即可!!如有兴趣  请加Q6287813  备注看雪  详谈!
2018-12-31 16:29
0
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
DNF现在还火吗?
2018-12-31 23:11
0
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
关读取r13,r14,r15寄存器错误的原因我找到了,原来是用别名读取的,对应的别名是:SP, LR, PC
2019-1-3 19:18
0
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
想到一个方法:通过休眠函数定时读取一个内存地址获取内存数据改变。

z = 0
while(z < 100):
    z += 1
    Sleep(200)
    d = DbgRead(0xe42afc1b, 16)
    h = ''
    m = []
    for y in d:
        h += ' %02x' % ord(y)
        m.append('%02x' % ord(y))
    h = h.upper()
    if(m[0]=='68' and m[5]=='64'):
        print('num=%d, mem=%s' % (z, h))
2019-1-9 19:16
0
雪    币: 244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
然而当我想定时获取ip寄存器的数据时却又出现了伪寄存器的错误:

z = 0
while(z < 100):
    z += 1
    Sleep(200)
    a = GetRegValue('R12')
    f = GetFunctionName(a)
    print('num= %d, addr= %x, func= %s' % (z, a, f))

经查后发现只有事件发生的时候才可以获取寄存器的数据:

AddBpt(0xE3984160)
GetDebuggerEvent(WFNE_SUSP, -1)
DelBpt(0xE3984160)
a = GetRegValue('R12')
RunTo(0xE3984160)
print('0x%x' % a)

如果能定时获取ip寄存器的数据就可以根据那个地址来获取下一个执行的函数,可惜没有事件就无法获取寄存器值,这个ip寄存器的值是不是保存在内存的某个地方?如果是的话定时读那个内存地址也可以实现我想要的功能。
2019-1-9 19:24
0
游客
登录 | 注册 方可回帖
返回
//