首页
社区
课程
招聘
[原创] c-sktrace:基于 C 实现的 sktrace 性能优化 demo
发表于: 2025-10-26 12:52 2854

[原创] c-sktrace:基于 C 实现的 sktrace 性能优化 demo

2025-10-26 12:52
2854

这是一个学习性质的项目,研究如何通过 Frida 的 CModule 实现高性能指令追踪。虽然 Frida 官方已经有了 frida-itrace 这个成熟方案,但直接用 CModule 手写可以更深入理解 Stalker 的工作原理和性能优化思路。

项目地址:445K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6$3N6%4N6%4i4K6u0V1k6s2u0G2K9h3c8Q4x3V1k6U0i4K6u0V1M7$3E0@1M7X3q4U0k6b7`.`.

原始的 JavaScript 实现在进行密集指令追踪时存在严重的卡顿问题,主要体现在:

通过 C 实现后,性能提升约两三个数量级(没细测,不过提升明显),实现了无卡顿的实时追踪。

示例:追踪一个执行 10,000 次的循环

每次切换需要:

还是很大的性能消耗

既然无法消除所有 JS 交互,那就:

通过不同的分隔符区分两种消息:

指令信息(tab 分隔):

寄存器信息(管道分隔,34 个字段):

性能提升:约两三个数量级(没细测,不过提升明显)

为什么慢?

怎么改?

效果?

function stalkerTraceRange(tid, base, size) {
    Stalker.follow(tid, {
        transform: (iterator) => {
            do {
                iterator.keep();
                if (isModuleCode) {
                    // ! 性能问题:每条指令都注册 JS 回调
                    iterator.putCallout((context) => {
                        send({...})  // Native → JS 切换
                    })
                }
            } while (iterator.next() !== null);
        }
    })
}
function stalkerTraceRange(tid, base, size) {
    Stalker.follow(tid, {
        transform: (iterator) => {
            do {
                iterator.keep();
                if (isModuleCode) {
                    // ! 性能问题:每条指令都注册 JS 回调
                    iterator.putCallout((context) => {
                        send({...})  // Native → JS 切换
                    })
                }
            } while (iterator.next() !== null);
        }
    })
}
目标代码执行到被 trace 的指令
    
Callout 触发:Native 代码暂停
    ↓ 切换到 JS 引擎
执行 JS 回调函数
    ↓ JSON 序列化 context
调用 send()(进程间通信)
    ↓ 切回 Native
恢复目标代码执行
目标代码执行到被 trace 的指令
    
Callout 触发:Native 代码暂停
    ↓ 切换到 JS 引擎
执行 JS 回调函数
    ↓ JSON 序列化 context
调用 send()(进程间通信)
    ↓ 切回 Native
恢复目标代码执行
void transform(GumStalkerIterator *iterator,
               GumStalkerOutput *output,
               gpointer user_data)
{
    cs_insn *insn;
    gpointer base = *(gpointer*)user_data;
    gpointer end = *(gpointer*)(user_data + sizeof(gpointer));
     
    while (gum_stalker_iterator_next(iterator, &insn))
    {
        gboolean in_target = (gpointer)insn->address >= base &&
                             (gpointer)insn->address < end;
         
        if(in_target)
        {
            // 输出指令信息(tab 分隔)
            log("%p\t%s\t%s", (gpointer)insn->address,
                insn->mnemonic, insn->op_str);
             
            // 注册 before callout
            gum_stalker_iterator_put_callout(iterator,
                on_arm64_before,
                (gpointer)insn->address,
                NULL);
        }
         
        gum_stalker_iterator_keep(iterator);
         
        if(in_target)
        {
            // 注册 after callout
            gum_stalker_iterator_put_callout(iterator,
                on_arm64_after,
                (gpointer)insn->address,
                NULL);
        }
    }
}
void transform(GumStalkerIterator *iterator,
               GumStalkerOutput *output,
               gpointer user_data)
{
    cs_insn *insn;
    gpointer base = *(gpointer*)user_data;
    gpointer end = *(gpointer*)(user_data + sizeof(gpointer));
     
    while (gum_stalker_iterator_next(iterator, &insn))
    {
        gboolean in_target = (gpointer)insn->address >= base &&
                             (gpointer)insn->address < end;
         
        if(in_target)
        {
            // 输出指令信息(tab 分隔)
            log("%p\t%s\t%s", (gpointer)insn->address,
                insn->mnemonic, insn->op_str);
             
            // 注册 before callout
            gum_stalker_iterator_put_callout(iterator,
                on_arm64_before,
                (gpointer)insn->address,
                NULL);
        }
         
        gum_stalker_iterator_keep(iterator);
         
        if(in_target)
        {
            // 注册 after callout
            gum_stalker_iterator_put_callout(iterator,
                on_arm64_after,
                (gpointer)insn->address,
                NULL);
        }
    }
}
static void
on_arm64_before(GumCpuContext *cpu_context, gpointer user_data)
{
    // 空 - 不做任何操作
}
 
static void
on_arm64_after(GumCpuContext *cpu_context, gpointer user_data)
{
    // 输出所有寄存器,Python 端做比较
    // 格式: addr|x0|x1|x2|...|x28|fp|lr|sp|pc
    if (cpu_context) {
        log("%p|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|"
            "%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|"
            "%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|"
            "%llx|%llx|%llx|%llx",
            user_data,
            cpu_context->x[0], cpu_context->x[1], cpu_context->x[2], cpu_context->x[3],
            cpu_context->x[4], cpu_context->x[5], cpu_context->x[6], cpu_context->x[7],
            cpu_context->x[8], cpu_context->x[9], cpu_context->x[10], cpu_context->x[11],
            cpu_context->x[12], cpu_context->x[13], cpu_context->x[14], cpu_context->x[15],
            cpu_context->x[16], cpu_context->x[17], cpu_context->x[18], cpu_context->x[19],
            cpu_context->x[20], cpu_context->x[21], cpu_context->x[22], cpu_context->x[23],
            cpu_context->x[24], cpu_context->x[25], cpu_context->x[26], cpu_context->x[27],
            cpu_context->x[28],
            cpu_context->fp, cpu_context->lr, cpu_context->sp, cpu_context->pc);
    }
}
static void
on_arm64_before(GumCpuContext *cpu_context, gpointer user_data)
{
    // 空 - 不做任何操作
}
 
static void
on_arm64_after(GumCpuContext *cpu_context, gpointer user_data)
{
    // 输出所有寄存器,Python 端做比较
    // 格式: addr|x0|x1|x2|...|x28|fp|lr|sp|pc
    if (cpu_context) {
        log("%p|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|"
            "%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|%llx|"

传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 112
支持
分享
最新回复 (57)
雪    币: 361
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
学习学习
2025-10-26 20:40
0
雪    币: 8637
活跃值: (6392)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2025-10-26 21:35
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
区别是什么
2025-10-26 21:47
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
感谢分享
2025-10-26 23:39
0
雪    币: 222
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
学习学习
2025-10-27 05:35
0
雪    币: 2365
活跃值: (2926)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
666
2025-10-27 09:21
0
雪    币: 1265
活跃值: (2227)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习徐诶
2025-10-27 09:22
0
雪    币: 23
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
1
2025-10-27 09:38
0
雪    币: 268
活跃值: (1323)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
666
2025-10-27 09:49
0
雪    币: 1495
活跃值: (3698)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
11
看看
2025-10-27 09:50
0
雪    币: 5
活跃值: (3615)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
原理还是没改变,跟踪的指令pc指向的地址都变成new出来的了
2025-10-27 10:14
0
雪    币: 104
活跃值: (7159)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
6
2025-10-27 10:17
0
雪    币: 293
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
6666666666666
2025-10-27 10:42
0
雪    币: 439
活跃值: (964)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
666
2025-10-27 10:42
0
雪    币: 2432
活跃值: (4693)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
666
2025-10-27 13:04
0
雪    币: 3781
活跃值: (4075)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
6
2025-10-27 13:08
0
雪    币: 570
活跃值: (3795)
能力值: ( LV3,RANK:37 )
在线值:
发帖
回帖
粉丝
18
看看
2025-10-27 13:47
0
雪    币: 8230
活跃值: (4763)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
学习,感谢分享
2025-10-27 13:52
0
雪    币: 24
活跃值: (402)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
hh
2025-10-27 15:37
0
雪    币: 7242
活跃值: (23739)
能力值: ( LV12,RANK:550 )
在线值:
发帖
回帖
粉丝
21
看看
2025-10-27 15:55
0
雪    币: 217
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
看看
2025-10-27 16:04
0
雪    币: 228
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
看看
2025-10-27 17:52
0
雪    币: 5611
活跃值: (3919)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
看看
2025-10-28 09:05
0
雪    币: 5627
活跃值: (9427)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
66666
2025-10-28 09:13
0
游客
登录 | 注册 方可回帖
返回