首页
社区
课程
招聘
[原创]unicorn有效的检测方案,以及魔改的对抗方案(unidbg为什么补好了环境却还是不能用)
发表于: 2026-9-7 14:46 4336

[原创]unicorn有效的检测方案,以及魔改的对抗方案(unidbg为什么补好了环境却还是不能用)

2026-9-7 14:46
4336

图片描述

检测 Unicorn 的差异点与消除方法

本文写确定能杀的差异:真机行为由架构固定或
时间源完全受我们掌控,模拟器可 100% 对齐消除。真机自身就因设备/微架构而异的编码(写回寄存器重叠、
LDP 同目标,都是 CONSTRAINED UNPREDICTABLE)不当检测点处理(末尾附背景)。

结构:先给检测方的全部探测片段(app 怎么探 Unicorn),再讲统一的信号注入回调机制,最后逐点消除
(改哪里、加什么回调、代码片段)。

app 一侧常用这几类探测。先注册 SIGILL/SIGSEGV handler + sigsetjmp 兜住会 fault 的编码,再逐条对比结果。

差异分两类,处理方式不同:

信号类检测点不逐条改引擎译码,而是用魔改 unicorn 新增的两个 API 把 SIGILL 投给 guest,复刻真机信号行为。

第一步:增加"信号处理回调"(UC_HOOK_SIGNAL)——整套的核心。 uc_signal_request() 请求信号后,引擎
停下当前 TB、在 uc_emu_start() 返回前回调它,由你决定把信号投给谁:

第二步:注册指令回调抓可疑指令(UC_HOOK_INSN)。 魔改 unicorn 的 UC_HOOK_INSN 支持按指令类型注册
MRS/MSR/SYS/SYSL,回调能拿到系统寄存器编码 op0/op1/crn/crm/op2:

第三步:回调里判真机行为,命中就 uc_signal_request。 uc_err uc_signal_request(uc_engine *uc, int signo)
请求信号——引擎停下、回到 on_signal;命中"真机会 SIGILL"就调它,不命中 return 0 交回引擎。

信号语义、时序、寄存器上下文都跟真机一致,探测方分不出信号由谁处理。改寄存器/PC 必须走 uc_reg_write /
uc_signal_request,回调返回值是"是否已处理"而非结果值。

为什么百分百:guest 能读到的所有时间源——CNTVCT_EL0/CNTPCT_EL0/CNTFRQ_EL0、
clock_gettime/gettimeofday——全部经过我们的回调。让它们返回一个"随已执行指令数单调递增"的虚拟时钟,
两次采样的差值就正比于"做了多少工作"、而不是逐指令翻译的真实墙钟开销,时序检测彻底失效。检测方拿不到任何
不受控的设备时间源。(前提:虚拟时钟必须单调、跨所有源自洽,否则不同源交叉比对会露馅。)

怎么处理——CNTVCT/CNTPCT 走 MRS 回调返回虚拟计数器(on_sysreg 里加一个分支):

clock_gettime/gettimeofday 走外部调用/SVC 回调拦截,用同一个虚拟时钟换算,和 CNTVCT 同源:

引用:Rethinking anti-emulation techniques(<ddcK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3N6$3&6D9j5h3u0Q4x3X3g2C8M7W2)9J5c8X3c8G2N6$3&6D9L8$3q4V1M7#2)9J5c8Y4q4W2L8i4g2Q4x3X3g2H3k6r3k6Q4x3U0k6Y4N6q4)9K6b7W2)9J5z5g2!0q4y4g2)9^5c8W2)9^5c8q4!0q4y4W2!0m8z5q4!0m8x3g2!0q4y4W2)9^5b7W2)9&6c8W2!0q4y4q4!0n7z5q4)9^5z5g2!0q4y4g2)9^5z5q4)9^5y4W2!0q4y4#2!0n7x3g2!0n7b7W2!0q4y4q4!0n7z5g2)9^5b7R3`.`.
"时序差异(timing)";ARM DDI 0487 的 CNTVCT_EL0/CNTFRQ_EL0 语义。

为什么百分百:EL0 访问 EL1-only 系统寄存器/系统指令是架构强制 UNDEF(访问权限由架构定义,非
UNPREDICTABLE),所有真机一致 SIGILL;未分配编码也一律 UNDEF。原版 QEMU 因 guest 以过高特权运行而照常执行,
未分配 MRS 甚至返回一个内核态地址(信息泄漏)。检测片段见 §一.2。

怎么处理——MRS/MSR 回调(on_sysreg)按编码判 EL0 是否禁访;si_code 由 on_signal 投递时构造:

SYS/SYSL 回调(on_sys)按 op0/op1 判缓存/地址翻译类:

EL0 合法程序不会碰这些编码,SIGILL 不误伤正常执行。

遗留:msr daifset,#2(MSR 立即数写 PSTATE.DAIF,不经系统寄存器回调)。默认 SCTLR_EL1.UMA=0 时 EL0 写
DAIF 真机 UNDEF→SIGILL,同类、也可杀,但走 MSR 立即数编码,要在引擎译码或 CODE 回调里另处理,当前未做。

引用:INSDET(arxiv 2105.14273)"行为差异"类;Rethinking anti-emulation techniques
(<24bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3N6$3&6D9j5h3u0Q4x3X3g2C8M7W2)9J5c8X3c8G2N6$3&6D9L8$3q4V1M7#2)9J5c8Y4q4W2L8i4g2Q4x3X3g2H3k6r3k6Q4x3U0k6Y4N6q4)9K6b7W2)9J5z5g2)9K6b7V1q4d9e0b7`.`. DDI 0487 系统寄存器 EL 访问约束。

真机对某些编码 UNDEF→SIGILL,原版 QEMU 照常执行。两处 load/原子指令,一个在引擎译码修、一个在回调修。
检测片段见 §一.3。

为什么百分百:ldp x9,x9,[x10](同一寄存器被加载两次)架构上是 CONSTRAINED UNPREDICTABLE,但实测
三台真机(Pixel8/ARMv9、Pixel6a/Cortex-X1、Pixel4XL/Cortex-A76)一致 SIGILL
——不像"写回重叠"那样 ARMv8/v9
分歧,所以作为可靠检测点收录。这是普通可解码 load、不 trap,只能在引擎译码阶段判定。

怎么处理——translate-a64.c 的 disas_ldst_pair(load pair 译码):

为什么百分百:CASP 要求 Rs、Rt 为偶数寄存器对;Rs<0>==1 || Rt<0>==1 时架构定义为 UNDEFINED(强制,
非 UNPREDICTABLE),所有真机一致 SIGILL。CASP 引擎不支持、走非法指令回调软件模拟,原版模拟时不校验奇偶。

怎么处理——中断回调(UC_HOOK_INTR,intno==1 非法指令分支)模拟 CASP 前先校验奇偶,奇数直接 SIGILL:

引用:INSDET(2105.14273)"QEMU UNDEFINED-check bug"类;ARM DDI 0487(CASP 奇寄存器 UNDEFINED、
LDP 同目标 CONSTRAINED UNPREDICTABLE);LDP 同目标跨设备一致 SIGILL 为本项目多设备实测(见 024)。

为什么百分百:PAC 能力随设备而变(旧机没有、新机有、有的带 FPAC),按 host-gated 做——读宿主真机的
PAC 特性镜像进 VM,VM 行为始终等于"这台真机应有的行为",任意宿主都对齐。检测片段见 §一.4;往返
(pacia;autia 同 modifier / pacia;xpaci)两边都还原,不能用作检测。

PAC 的应对在引擎(QEMU fork)里改,分四处:

(a) host-gated 使能 —— cpu.c 的 arm_cpu_reset(复位阶段,arm_rebuild_hflags 之前):

(b) 去掉容器不该有的陷入 —— pauth_helper.c 的 pauth_check_trap(改按执行档位判):

(c) 加位(值类):使能后引擎 pacia 用自己的密钥真算 PAC 位写回——真机加位、VM 也加位。单签的具体位值
不必跟真机一致:签名密钥每进程随机、EL0 不可读,探测方无法预测正确值、只能查"有没有变化",而 VM 已加位,
这条探测就堵死。(使能后引擎既有行为,无需额外改。)

(d) 坏认证触发信号(FEAT_FPAC) —— pauth_helper.c 的 pauth_auth(认证失败分支):


冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 2026-9-7 14:47 被黑色渡鸦编辑 ,原因:
收藏
点赞 ・121
打赏
分享
最新回复 (53)
雪    币: 0
活跃值: (600)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2 楼
66666
2026-9-7 14:48
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3 楼
666
2026-9-7 14:49
0
雪    币: 5990
活跃值: (3876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4 楼
6
2026-9-7 14:49
0
雪    币: 411
活跃值: (1036)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5 楼
牛逼 发财
2026-9-7 14:49
0
雪    币: 51
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6 楼
666
2026-9-7 14:50
0
雪    币: 2994
活跃值: (5967)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7 楼
666
2026-9-7 14:50
0
雪    币: 1867
活跃值: (3033)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8 楼
666
2026-9-7 14:50
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9 楼
666
2026-9-7 14:51
0
雪    币: 366
活跃值: (441)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10 楼
牛逼 发财
2026-9-7 14:53
0
雪    币: 5520
活跃值: (5854)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11 楼
牛逼 发财
2026-9-7 14:53
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12 楼
666
2026-9-7 14:54
0
雪    币: 230
活跃值: (1681)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13 楼
????
2026-9-7 14:55
0
雪    币: 919
活跃值: (522)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14 楼
4334
2026-9-7 14:57
0
雪    币: 75
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15 楼

unidbg均无处理文章里面的内容,大家可以借鉴魔改优化,实际上unicorn默认的很多hook回调,和功能没开启,比如

SYS,和SYSL类型的回调,可以直接在里面处理el1越权访问陷阱的问题,真机上应该是直接触发信号而不是继续往下执行

1.el1越权访问陷阱
2.测信道类,cpu缓存访问探测是否是真实cpu
3.与真实armv8指令的加载,存储行为有差异,指令在unicorn中可以正常执行但是真机触发信号

最后于 2026-9-7 15:02 被黑色渡鸦编辑 ,原因:
2026-9-7 14:59
0
雪    币: 2007
活跃值: (8223)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
16 楼
1
2026-9-7 15:09
0
雪    币: 9380
活跃值: (6283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17 楼
看看
2026-9-7 15:10
0
雪    币: 2651
活跃值: (3334)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
18 楼
牛逼 发财
2026-9-7 15:16
0
雪    币: 778
活跃值: (3702)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19 楼
11
2026-9-7 15:18
0
雪    币: 1901
活跃值: (5983)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
20 楼
666
2026-9-7 15:26
0
雪    币: 6787
活跃值: (12012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21 楼
2026-9-7 15:28
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22 楼
666
2026-9-7 15:40
0
雪    币: 2781
活跃值: (3559)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23 楼
d啊哒哒
2026-9-7 15:56
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24 楼
看看
2026-9-7 16:12
0
雪    币: 319
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25 楼
其实现在unibdg大家都不用了都靠ai
2026-9-7 16:33
0
游客
登录 | 注册 方可回帖
返回