Frida Stalker 是什么?

简介: Frida Stalker 是什么?

一、目标


在分析so中的算法时,Trace和Debug是常用的手段。


了解一些调试器原理的同学都知道,Trace和Debug需要修改原始代码加上个int 3,来激活调试器。


这样有些App可以依赖检测关键代码来判断是否被调试。


也许你会说,我们可以patch掉检测代码,上次飞哥遇到一个狠人app,B去检测A处的代码,C去检测B处的代码,D去检测C处的代码,…… 反正套娃了 5-6次,我就崩溃了。


还好有 Stalker


Stalker是基于动态重新编译的代码跟踪器。 它将代码指令复制到内存中的另一个位置,在该位置对其进行调整以适应新位置并包括其他跟踪指令。 如果应用程序在原始位置检查其代码,则会发现该代码是完整无缺的,因为它是被篡改的代码的副本。


二、步骤

Stalker Trace Code


我们还是以上次分析的某小说App来演示 Stalker 的用法,


91fans.com.cn/post/readbo…


Stalker在ARM32下貌似不大好使,这里我们在ARM64下做的测试

function trace_entry(baseAddr,tatgetAddr){
    Interceptor.attach(tatgetAddr, {
        onEnter: function(args){
            console.log("enter tatgetAddr====================================================================");
            this.pid = Process.getCurrentThreadId();
            Stalker.follow(this.pid,{
                events:{
                                                        // 暂时不需要这些 events
                    call:false,
                    ret:false,
                    exec:false,
                    block:false,
                    compile:false
                },
                onReceive:function(events){
                },
                transform: function (iterator) {
                    var instruction = iterator.next();
                    const startAddress = instruction.address;
                                        // 从ida里面 找到 Java_com_baidu_searchbox_NativeBds_dae1 函数的 代码 在 0xE84 和 0x126C 之间
                    var isModule = startAddress.compare(baseAddr.add(0xE84)) >= 0 && startAddress.compare(baseAddr.add(0x126C)) < 0;
                    do{
                        if (isModule){
                                console.log(instruction.address.sub(baseAddr) + "\t:\t" + instruction);
                        }
                        iterator.keep();
                    } while ((instruction = iterator.next()) !== null);
                },
                onCallSummary:function(summary){
                }
            });
        },onLeave: function(retval){
            Stalker.unfollow(this.pid);
            console.log("retval:"+retval);
            console.log("leave tatgetAddr====================================================================");
        }
    });
}


需要解释的是 transform 函数, 其他的 events、 onReceive 和 onCallSummary 目前我们还用不到,它们可以做block 和 call之类的跟踪分析。


transform 遍历执行了当前的每一行汇编指令,默认显示的地址是实际内存地址,我们 instruction.address.sub(baseAddr) 减去了一个so的基地址,得到的就和ida中显示的地址一致了557.png


加Hook


光显示指令没啥意思,指令看上去还没有ida好看呢。


但是这个是活的执行,我们可以加个hook,通过ida分析,感觉差不多 0xFB8的时候是计算key的长度。779.png


所以我们在这里加个打印

do{
    if (isModule){
        console.log(instruction.address.sub(baseAddr) + "\t:\t" + instruction);
        if(instruction.address.sub(baseAddr) == 0xfb8){
            iterator.putCallout((context) => {
            var string = Memory.readCString(context["x21"]);
            console.log("####  key = " + string)
            })
        }
    }
    iterator.keep();
} while ((instruction = iterator.next()) !== null);


这样就可以顺利的打印出本次aes算法中用的key了

0xfb4        :        add x21, x21, x0, lsr #1
0xfb8        :        mov x0, x21
0xfbc        :        ldr x22, [x8, #0x580]
0xfc0        :        bl #0x7a751c55f0
####  key = D0CD8B760CE07BC3
0xfc4        :        mov x1, x0
0xfc8        :        mov x0, x20
0xfcc        :        blr x22
0xfd0        :        ldr x8, [x20]


更帅的Trace


我们现在掌握了打印指令和寄存器值的方法。不过这样打出来太不帅了,IDA的Trace只会打印被修改的寄存器的值。


还好有大佬已经写好了


github.com/bmax121/skt…


先 把我们代码中 Stalker 部分注释掉,因为要干掉登录和vip,所以先启动我们的js

frida -U -l bqgst.js -f com.bqg.ddnoverl --no-pause


然后启动 sktrace

python sktrace.py -m attach -l libTxtFormatter.so -i Java_com_baidu_searchbox_NativeBds_dae1 com.bqg.ddnoverl


-l 指定so名称


-i 指定要Trace的函数名


最后跟的是包名或者app名称

0x7a2e289e9c        add        x29, sp, #0x50        ; x29=0x7a7bdb9d48->0x7a7bdb9c50
0x7a2e289ea0        mov        x20, x0        ; x20=0x0->0x7c02192b70
0x7a2e289ea4        ldr        x8, [x20]        ; x8=0x79a1c49061b6ff43->0x7b3fe0e198
0x7a2e289ea8        mov        x1, x2        ; x1=0x9e30a688->0x7a7bdb9d18
0x7a2e289eac        mov        x2, xzr        ; x2=0x7a7bdb9d18->0x0
0x7a2e289eb0        mov        x19, x3        ; x19=0x7cb23102a0->0x7a7bdb9d1c
0x7a2e289eb4        ldr        x8, [x8, #0x548]        ; x8=0x7b3fe0e198->0x7b3fbe20e0
0x7a2e289ebc        ldr        x8, [x20]        ; x0=0x7c02192b70->0x7b522130f0, x1=0x7a7bdb9d18->0x7dee5ef7cc, x3=0x7a7bdb9d1c->0x10, x4=0x7a7bdb9d58->0x0, x8=0x7b3fbe20e0->0x7b3fe0e198, x11=0x40->0x522130f7, x12=0xb->0xffff00000eff, x13=0x380->0xafba2fb8, x16=0x7a2e289e94->0x7dd27ad7f8, x17=0x7cb23102a0->0x7dee554c78, x30=0x7deaefdc0c->0x7a2e289ebc
0x7a2e289ec0        mov        x21, x0        ; x21=0x0->0x7b522130f0
0x7a2e289ec4        ldr        x22, [x8, #0x580]        ; x22=0x7abbab01b8->0x7b3fbe5504
0x7a2e2895f0        adrp        x16, #0x7a2e29a000        ; x16=0x7dd27ad7f8->0x7a2e29a000, x30=0x7a2e289ebc->0x7a2e289ecc
0x7a2e2895f4        ldr        x17, [x16, #0xfe8]        ; x17=0x7dee554c78->0x7dee561980
0x7a2e2895f8        add        x16, x16, #0xfe8        ; x16=0x7a2e29a000->0x7a2e29afe8


现在打出来的,就有ida Trace内味了。


同学们还可以模仿下sktrace的代码,搞个更趁手的兵刃出来。


三、总结


矛与盾的战斗是永不停息的,无痛hook,硬件断点应该是趋势。


一个趁手的调试器非常难得,一个能被Debug的App是藏不住秘密的。997.png


万事纷纷一笑中,渊明把菊对秋风

Tip:

: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一起学习探讨技术。有问题可以加我wx: fenfei331 讨论下。


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

相关文章
|
Cloud Native IDE Go
Protobuf在IDEA中的插件安装教程
Protobuf在IDEA中的插件安装教程
1218 0
|
4月前
|
缓存 JavaScript 前端开发
《代码沙盒深度实战:iframe安全隔离与实时双向通信的架构设计与落地策略》
本文聚焦代码沙盒网站(类似CodePen)的核心技术难点,深度拆解前端领域的iframe安全隔离与实时双向通信实现方案。首先讲解基于“最小权限原则”的iframe沙箱配置与环境净化,结合CSP形成双重安全防护;再详解postMessage API的标准化协议设计、身份验证与消息可靠性保障,解决隔离环境下的通信难题。还涵盖代码有序执行、增量更新、Web Worker优化,以及错误捕获、恶意行为监测等稳定性策略,同时从资源加载、通信链路、iframe池机制做性能优化,并结合编辑、反馈、扩展体验设计落地。为前端开发者提供从架构到实践的完整沙盒开发指南,助力平衡安全与用户体验。
262 27
|
9月前
|
关系型数据库 MySQL 应用服务中间件
Linux 手动安装快速部署 LNMP 环境实战
本文详细记录了在阿里云ECS上手动搭建LNMP环境的过程,系统选用Ubuntu 24.04。主要内容包括:1) 使用`apt`安装Nginx和MySQL,并更新软件源;2) 编译安装PHP 8.4.5,配置PHP-FPM及环境路径;3) 配置MySQL root用户密码;4) 调整Nginx支持PHP解析并测试整体环境。通过此过程,重现手动配置服务器的细节,帮助熟悉各组件的安装与协同工作。
663 23
|
网络协议 网络安全
【网络安全】Wireshark过滤数据包&分析TCP三次握手(下)
【网络安全】Wireshark过滤数据包&分析TCP三次握手
497 1
|
Java 调度 Android开发
Android面试题之Kotlin中async 和 await实现并发的原理和面试总结
本文首发于公众号“AntDream”,详细解析了Kotlin协程中`async`与`await`的原理及其非阻塞特性,并提供了相关面试题及答案。协程作为轻量级线程,由Kotlin运行时库管理,`async`用于启动协程并返回`Deferred`对象,`await`则用于等待该对象完成并获取结果。文章还探讨了协程与传统线程的区别,并展示了如何取消协程任务及正确释放资源。
381 0
|
机器学习/深度学习 算法框架/工具
详细探讨跨域学习与迁移学习在图像识别中的应用
详细探讨跨域学习与迁移学习在图像识别中的应用
|
安全 网络安全 数据安全/隐私保护
什么是2FA?如何在公共网站上实现2FA?
【8月更文挑战第31天】
2905 0
|
人工智能 算法 安全
软考的好处 拥有软考证书的8大作用
这篇文章列举了拥有软考证书的8大好处,包括证书的高度认可、对应高级工程师职称、帮助积分落户、升职加薪、领取补贴、个税抵扣、在校生考证加分以及个人能力提升。
软考的好处 拥有软考证书的8大作用
|
存储 JSON JavaScript
protobuf抓包,读包
protobuf抓包,读包
443 4
|
Go
Go 语言中如何表示枚举值(enums)?
【2月更文挑战第22天】
1025 3