借你一双慧眼, Frida Native Trace

1、目标

李老板: 奋飞呀,最近没怎么更新呀?python

奋飞: 最近的KPI定的合不合理你内心没点AC数?我如今内卷到周三就开始写周报了,否则被新来的就给卷失业了。ios

遥想在古典PC互联网时代,咱也是 OD、IDA 玩的很溜的。git

一日饮酒乐甚,突发奇想,IDA识别出全部函数,而后导出来给OD,给这些函数下断点,触发以后先打日志,再自动取消断点。这样程序运行的流程不就出来了?github

实际跑起来发现,有些函数会频繁被调用,这样致使程序容易假死或者崩溃,因此还须要有个方便的过滤措施,过滤掉频繁调用的函数。安全

pestalker.png

搞出了PEStalker以后,程序的运行流程就无所遁形了。微信

不过期代变了,移动互联网时代的AppStalker怎么搞?markdown

2、步骤

frida-trace

大胡子其实和咱们想到一块去了,他搞了个frida-trace,能够一次性监控一堆函数地址。python2.7

而后还能打印出比较漂亮的树状图,不只能够显示调用流程,还能显示调用层次。而且贴心的把不一样线程调用结果用不一样的颜色区分开了。函数

如今就缺个数据源,把IDA的识别结果导出来了。oop

trace_natives

github.com/Pr0214/trac… 是的,大佬已经写好了,咱们又能够白嫖了。

bp.png

跑起来

  • 下载traceNatives.py 放到ida的 plugins路径下, 我是mac放在了 /Applications/IDA Pro 7.0/idabin/plugins 目录

  • Pr0214可能用的是IDA 7.x+ 和 python 3.x 的环境, 在个人 IDA7.0和python2下须要微调下代码

# search_result = [f"-a '{so_name}!{offset}'" for offset in search_result]
search_result = ["-a '{}!{}'".format(so_name,offset) for offset in search_result]

# with open(save_path, "w", encoding="utf-8")as F:
with open(save_path, "w")as F:

# print(f"frida-trace -UF -O {save_path}")
print("frida-trace -UF -O {} !".format(save_path))

复制代码
  • IDA打开以前91fans.com.cn/post/ldqsig… 里的 libxxbitmapkit.so, Edit -> Plugins -> traceNatives 。 而后在分析目录下面会生成 libxxbitmapkit_16250177xx.txt 这就是frida-trace要导入的数据了

  • 先把某电商程序的App跑起来,而后命令

frida-trace -UF -O /Users/fenfei/Desktop/xx/armeabi-v7a_9_4_6/libjdbitmapkit_1625017920.txt
复制代码

跑起来便可,请注意 这里不要出现中文路径, 可能个人 frida-trace 是在python2.7下跑的,出现中文路径就会载入失败。

最后 随便点个商品详情页

rc.png

结果仍是很漂亮的。

加强一下

李老板: Android的so Trace没问题,ios的App咋不行?

奋飞: RTFS

Android so的代码段name是 .text, ios的代码段name是 __text ,因此咱们在 getSegAddr 里加个判断

...
if (idc.get_segm_name(seg)).lower() == '.text' or (
        idc.get_segm_name(seg)).lower() == 'text' or (
        idc.get_segm_name(seg)).lower() == '__text' :
...
复制代码

李老板: 吾有一函数,第一个入参一定是2,可是不知道是哪一个?能够Trace出来吗?

奋飞: ……&*%¥%……)(%$

咱们能够修改 handlers/libxxbitmapkit.so/xxx.js下面的脚原本完成一些特别的操做,好比在Trace的时候把第一个参数是2的函数挑出来。

onEnter(log, args, state) {
    log('sub_10d71()');
  },

// 改为

  onEnter(log, args, state) {
	if(args[0] == 2){
		log(" ======== I am here! ========");
	}
    log('sub_10d71()');
  },
复制代码

固然成千上万个函数,手工去改,李老板会笑话我很二的。

def alter(file,old_str,new_str):
    """
    替换文件中的字符串
    :param file:文件名
    :param old_str:就字符串
    :param new_str:新字符串
    :return:
    
    """
    file_data = ""
    with open(file, "r", encoding="utf-8") as f:
        for line in f:
            if old_str in line:
                line = line.replace(old_str,new_str)
            file_data += line
    with open(file,"w",encoding="utf-8") as f:
        f.write(file_data)

def findAllFile(base):
    for root, ds, fs in os.walk(base):
        for f in fs:
            yield f

def main():
    strPath = '/Users/fenfei/Desktop/work/blogCode/trace/__handlers__/libxxbitmapkit.so'
    
    for i in findAllFile(strPath):
        print(i)
        alter(strPath +"/" + i, "onEnter(log, args, state) {", 'onEnter(log, args, state) { if(args[0] == 2){ log(" ======== I am here! ========");}')

复制代码

人生苦短,快用Python。 收工。

3、总结

和PEStalker的遇到的问题是同样的,hook的函数太多,App很容易崩溃,必须有个方便的过滤措施,把一些频繁调用的,不重要的函数过滤掉。 这个还没想好怎么搞。

大胡子还有个玩具叫 github.com/oleavr/art-… 听说比较牛叉,能够研究下。

不说了,写周报去了。

ffshow.png

我平生开车最恨两种人,一种是随意加塞的,另外一种是不让我加塞的。[吃瓜]

TIP: 本文的目的只有一个就是学习更多的逆向技巧和思路,若是有人利用本文技术去进行非法商业获取利益带来的法律责任都是操做者本身承担,和本文以及做者不要紧,本文涉及到的代码项目能够去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一块儿学习探讨技术。有问题能够加我wx: fenfei331 讨论下。

关注微信公众号: 奋飞安全,最新技术干货实时推送

相关文章
相关标签/搜索