首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
CTF对抗
发新帖
0
0
[原创]午时·永数囚笼 WriteUp
发表于: 2026-8-14 13:10
727
[原创]午时·永数囚笼 WriteUp
mako233
2026-8-14 13:10
727
# 午时·永数囚笼 WriteUp ## 确定 verifier 主函数链中的重要函数: ```text sub_14000306c outer verifier sub_14000330c VM worker sub_140002880 deterministic seed sub_140002ba0 26-byte -> 8 x uint32 preprocessing sub_140002940 worker-record aggregator sub_1400025ec integrity sub_140002588 anti-debug sub_140002b3c VM word decoder ``` 该题目最坑点:`sub_14000330c` 的返回值不决定是否校验成功,其运行 4 个 worker,保存四个 60-byte record 后全部送入 `sub_140002940`。因此不能将: ```text worker.err != 0 ``` 看作失败,最终正确链路应当是: ```text worker0 fail worker1 fail worker2 clean success worker3 fail ``` ## Seed / integrity `sub_140002880` 的 clean 输出通过独立 Unicorn 执行确认是固定值: ```text seed1 = 0xb0adeff3 seed2 = 0x03db2dd2 ``` `.vseal` 导出的 integrity clean values: ```text 0x06998aa7 ^ 0x9e3779b9 = 0x98aef31e 0x86d10683 ^ 0xd1b54a35 = 0x57644cb6 ``` 最终全链机器码验证里,对 OS/debug helper 只模拟已独立验证过的 clean 环境返回,没有 patch compare / worker state / outer result。 ## 可逆 preprocessing `sub_140002ba0` 26-byte 输入先构造成 8 个 32-bit word: ```text w0..w5 = LE32(input[0:24]) w6 = bytes(input[24], input[25], 0x5a, 0xa5) w7 = 0xc3d2e1f0 ``` 所以逆 preprocessing 后必有固定 sentinel: ```text pre_state[26:32] = 5a a5 f0 e1 d2 c3 ``` 之后是 whitening + 8 轮 ARX,核心操作只有: ```text ADD/SUB mod 2^32 XOR ROL/ROR odd multiplication ``` 全部可逆。实现 `mix/unmix` 后做了随机 round-trip 验证。 worker 实际消费的 transformed state 记为: ```text S[32] ``` 另有 12-bit: ```text V = fold(S) ``` 最终解: ```text V = 0x110 ``` --- ## 先逆 outer `sub_140002940` 的最终四 word 在 compare 前必须为: ```text 892a48af b45dcd47 006c5ac3 b0b1062a ``` 继续逆其 128-bit aggregator,只留下 4 个 32-bit worker digest `h_i`,Z3 得到唯一解: ```text h0 = 0x1f1cc1bc h1 = 0x1b7d21a2 h2 = 0x47d3d751 h3 = 0x27ff56e7 ``` 这样问题从“找 26-byte 输入”降成“让四个 worker record 分别给出这些 fingerprint”。 ## 单 worker record digest worker record 为 15 个 dword: ```text s0..s14 ``` 机器码确认 `sub_140002940` 的 tail fold 使用真实的 `s7..s14`。 单 worker digest: ```c h = ROL(s2, (a&3)+9) ^ ROL((0xb5297a4d-a*0x4ad685b3) ^ s6, (a&7)+13) ^ ROL(s1, (a&7)+5) ^ s0 ^ (s5*0x045d9f3b + 0x045d9f3b) ^ (s4 << 17) ^ s3; for (j=0; j<8; j++) h = ROL(((j+1)*0x7f4a7c15) ^ s[7+j] ^ h, ((a*3+j)&7)+5) + 0x6d2b79f5; ``` ## 真正的 clean worker 直接构造四个 worker 的 clean-success record: - 使用各自 expected final `v5/v66`; - `v211=0`; - tail 使用各自 8-word local success target; - 其它计数采用真实 clean 值。 送入真实 record digest: ```text worker0 clean q = e96e1ddb worker1 clean q = d8c82cae worker2 clean q = 47d3d751 worker3 clean q = 5dc50e75 ``` 与 outer target: ```text required h0 = 1f1cc1bc required h1 = 1b7d21a2 required h2 = 47d3d751 required h3 = 27ff56e7 ``` 比较后只有: ```text worker2 clean q == required h2 ``` 精确相等。 因此 `a3=2` / variant2 是真实 clean-validation core;其它三路只是 fail/error fingerprint。 ## worker2 clean target 机器 `pre-v211` compare 给出 worker2 clean expected keys: ```text final v66 = 0xe6a68d04 final v5 = 0x2e8c989c ``` 逆 local tail permutation,并撤销 final-key correction,得到 worker2 的 32-byte raw output target: ```text 40e086d0ceff2d270de6e28bd49f57af beb5316bd8322983820999bccb16ab1d ``` ## VM 压成高层 block model VM 实际逻辑结构: ```text 257 = 32*8 + 1 ``` 也就是 32 个逻辑轮,每轮 8 条 VM instruction,最后终止。 真正跨轮的数据状态只保留: ```text acc : uint8 v66 : uint32 v5 : uint32 v20 : 1 bit S[32] iter ``` 建立两套模型: ```text Model A: 原 x86 / Unicorn Model B: 高层 logical block VM ``` 修正 opcode6 的真实机器语义后,对: ```text 4 workers × 100 random (S,V) ``` 逐组比较: ```text raw[32] final v66 final v5 ``` 结果: ```text 400 / 400 matched ``` 随后真实 digest / v211 也分别做了随机机器码对拍。 ## clean worker2 的可逆搜索结构 只有这些 iter 含 opcode22: ```text 2,3, 12,13,14,15, 22,23,24,25,26,27 ``` 其余 20 轮没有 secondary read。 ### 无 opcode22 的轮 给定当前 `v66` 与目标 raw byte,可以逆 accumulator ARX,**唯一恢复 primary S byte**,不需要 256 枚举。 ### opcode22 的轮 primary / secondary byte 与目标 output 存在可逆 8-bit relation。 搜索始终维护: ```text primary mask known[index] = byte ``` 若同一 index 被推出两个不同 byte:立即剪枝。 clean path 又要求 32 次 primary index 覆盖 0..31,所以: ```text primary_mask == 0xffffffff ``` 重复 primary index 可安全剪枝。 ## 12–15 的 qk 分层 节点统计显示真正 heavy subtree 集中在: ```text iter 12..15 ``` 这四次 opcode22 的 secondary index 正好覆盖: ```text S12,S13,S14,S15 ``` 各一次。 定义: ```text qk = 进入 iter12 时 S12..S15 已知几个 ``` 于是复杂度按: ```text qk=4 -> 基本确定 qk=3 -> 1-byte 分支 qk=2 -> 2-byte 搜索 qk=1 -> heavy qk=0 -> 最重 ``` 因此按: ```text Q4 -> Q3 -> Q2 -> Q1 -> Q0 ``` 分层搜索。这只是完备搜索顺序优化,不改变 verifier。 ## 搜索命中 先完整扫描全部: ```text V = 0x000 .. 0xfff ``` ### qk >= 3 4096 个 V 全部自然 DEAD。 ### qk = 2 层 在: ```text V = 0x110 ``` 命中: ```text FLAG26HEX = 666c61677b76345f6f70617175655f74726163655f323032367d ``` 即: ```text flag{v4_opaque_trace_2026} ``` 对应 transformed S: ```text f1b4801d0d18245b437c05da5b354020 262485099321b50a6615bbd15e601d3f ```
登录后可查看完整内容
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
上传的附件:
AntiAi_Exp.zip
(14.41kb,9次下载)
收藏
・
0
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
mako233
3
发帖
1
回帖
30
RANK
关注
私信
他的文章
[原创]午时·永数囚笼 WriteUp
727
[原创] iOS App的商业级环境检测手段 - 基于某讯A<E Framework 详解
3212
[原创] AIDA64 8.25.8200 Business 逆向工程与Keygen实战
21704
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
谁下载
×
huangyalei
pzhxbz
yuzhouheike
Zhuliyong
ONewTach
mb_rgyepcsx
eappple
Fering11
mb_lthgjpwj
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部