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

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

4小时前
587

图片描述

检测 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(<324K9s2c8@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_codeon_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
(<c32K9s2c8@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.cdisas_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.carm_cpu_reset(复位阶段,arm_rebuild_hflags 之前):

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

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

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


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

最后于 4小时前 被黑色渡鸦编辑 ,原因:
收藏
免费 53
打赏
分享
最新回复 (28)
雪    币: 0
活跃值: (595)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
66666
4小时前
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
666
4小时前
0
雪    币: 5807
活跃值: (3645)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
6
4小时前
0
雪    币: 411
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
牛逼 发财
4小时前
0
雪    币: 51
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
666
4小时前
0
雪    币: 2931
活跃值: (5857)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
666
4小时前
0
雪    币: 1786
活跃值: (2923)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
666
4小时前
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
666
4小时前
0
雪    币: 298
活跃值: (351)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
牛逼 发财
4小时前
0
雪    币: 5455
活跃值: (5759)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
牛逼 发财
4小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
666
4小时前
0
雪    币: 230
活跃值: (1631)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
????
4小时前
0
雪    币: 919
活跃值: (502)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
4334
4小时前
0
雪    币: 33
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15

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

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

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

最后于 3小时前 被黑色渡鸦编辑 ,原因:
4小时前
0
雪    币: 1877
活跃值: (7998)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
16
1
3小时前
0
雪    币: 9198
活跃值: (6048)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
看看
3小时前
0
雪    币: 1578
活跃值: (2746)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
18
牛逼 发财
3小时前
0
雪    币: 736
活跃值: (3490)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19
11
3小时前
0
雪    币: 1560
活跃值: (5723)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
20
666
3小时前
0
雪    币: 6623
活跃值: (11767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
3小时前
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
666
3小时前
0
雪    币: 2561
活跃值: (3150)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
d啊哒哒
3小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
看看
2小时前
0
雪    币: 271
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
其实现在unibdg大家都不用了都靠ai
2小时前
0
游客
登录 | 注册 方可回帖
返回