关掉 ACE 预启动,随便签一个泄露签名,即可加载驱动,稳定性极高,就蓝屏了两次。 每次 move 前先调用 SetHandleInformation(h, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)进行清零,在move 后调用GetHandleInformation(h, &flags)函数会通过 KUSER_SHARED_DATA 访问 TickCountLowDeprecated,并且在异或后被编码进入返回缓冲,可以在用户层恢复被驱动使用的这个 Tick 值然后计算就是理论上这个线路被延时的毫秒数,然后我们可以计算一个 IO 请求的耗时如果 predicted_ms 和 time_ms 很接近,就能说明本次触发到了该泄漏点,但是无法判断具体的结果。在二进制文件中放了大量的小混淆,导致不管是正向分析还是逆向分析,都不舒服,比如发现了某一个函数,发现 xref 不可用,因为上游的调用点有花指令,混淆等,导致了 IDA 不能正确分析,在驱动分析中尤其明显,但是由于驱动导入表暴露了大量的信息,所以都可以通过导入表入手,不完整的分析全流程,也能得到相关结论,如果赛题在导入函数上做手脚,比如动态解析,难度会更大。很好本来都要提交了,感觉这个寻路脚本咋会这么慢,时间还不稳定,又重新用IDA看了一眼驱动,发现有随机的 Sleep 感觉大概率是没找齐全,然后就找到了之前没找到的两个泄漏点(但是他们没有影响我得到flag....)从上述文本能够判断是迷宫题目,但是应该不是简单的迷宫,应该无法通过传统的迷宫分析方法分析,需要完整的逆向,至少要找到文档中提到的:并未发现有保护壳,直接运行得到可以有一个基本的了解 13*13 的迷宫,“The palace gives NO feedback on whether your moves succeed or hit a wall.” 表面不会有反馈,“Five hidden flaws betray the result of every move ” 要通过五个侧信道得到迷宫的反馈,**“after each reset, the first five successful moves reveal each flaw exactly once, in a fixed order. ”**每次你按 R 重置后,前 5 次成功移动会依次触发五种不同的泄露机制,顺序是固定的。(这里其实还是有一点疑惑的,最终只找到了三类泄露方式,但也可以算作五个泄漏点) 字符串没有做混淆,在字符串表暴露了很多信息。结合字符串的交叉引用,有如下分析:虽然还没有分析驱动,但是应用创建了两个全局命名事件,名称强烈暗示它们分别对应移动成功和撞墙,即失败。通信方面使用了最基本的 IO 通讯,分析 DeviceIoControl 的交叉引用可以得到所有的 IO 码显然 0x8001200C 用于查询迷宫信息,接下来就能发现 main 函数有大量的花指令了,因为正常的 R 等逻辑的处理代码都不存在只需要把 改为伪代码就重建好了,然后依旧是出题人的小礼物啊这里会有垂落,处理的是大小写 R 的情况显然 0x80012008 用于重新开始,那剩下的操作码肯定是操作迷宫了的紧接着还要详细分析,相关的按键被映射为了十六进制整数,如下TryMove 对于路径的打包如下其中,具体的加密逻辑是这样足够我们重建结构体了,但是伪代码有一个问题,驱动如何校验 v17 的正确性呢?切换到汇编,根据 DeviceIoControl 的参数可以知道然后看汇编层面是如何写入 [r11-30h] 的统一成 buf 的偏移就是也就能重建结构体为接下来是输入 T 的问题 命令 T的作用并不是显示当前位置,而是输出应用层维护的成功移动日志。主循环中,每当一次移动被认为成功时,程序都会将对应方向字符 L R U D 追加到缓冲区 v22 中,而 T/t分支则负责打印当前操作计数及该字符串,也就是这里只能打印成功的路径。先玩一下,也就是可以借助前五个正确路径找到五个泄漏点,因为提到了前五次成功顺次泄露,会在后边起关键作用也是见到没有壳子轻松达到 4 MB 的驱动文件了,混淆或者花指令估计是跑不了了,先迎接出题人的小礼物,重建 sub_140003208patch 为伪代码重建成功接下来寻5个泄漏点,刚才在应用层找到的事件,先看字符串定位过去,找到第一个泄漏点该函数根据传入状态参数,选择 **\BaseNamedObjects\MazeMoveOK **或 \BaseNamedObjects\MazeMoveWall随后通过 ZwOpenEvent 打开对应命名事件,并调用 ZwSetEvent 将其置位,最后关闭句柄。由于应用层事先创建了同名全局事件 Global\MazeMoveOK 与 Global\MazeMoveWall因此用户态可在每次发送移动请求后轮询这两个事件,从而判断本次移动是成功推进还是撞墙失败。然后在导入表发现了函数 KeReleaseSemaphore 和 ObReferenceObjectByName 跟到,sub_140319A37,有明显的选择和解密流程就要看看 unk_1400041E0 和 unk_140004160 对应的到底是什么字符串了得到输出,也就找到了第二个泄漏点,但是暂时不能确定哪个是撞墙,哪个是成功,要具体测试一下测试 DDDDD 得到那么路径正确时候会触发 Global\{A7F3B2C1-9E4D-4C8A-B5D6-1F2E3A4B5C6D}还是要看导入表首先想到的可能是调试状态,或者 LastError,对于 LastError 的话,尝试找找有没有类似的写入逻辑显然可以看到那么 LastError 应该是下一个泄漏点了刚才我们提到 qword_140005080 是 PsGetThreadTeb ,相关的交叉引用还有一个函数通过汇编可以分析出,这还说啥了,如果不动态调试的话估计是没戏了,然后问 GPT 能不能猜测一下这是哪个函数?查阅相关资料然后需要确定 ZwSetInformationObject 提供的什么信号墙,什么信号是通路?可以先创建一个事件句柄 slot4_probe,把这个句柄值写到当前线程 TEB + 0x1748,每次 move 前先调用 SetHandleInformation(h, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0)进行清零,在move 后调用GetHandleInformation(h, &flags),因为题目提到,reset 后前五次成功步按顺序泄露并且稳定观测到(我们测试到了前几步都是D,并且可以通过回环 DAD 走法来增加正确步骤的次数) 这个的发现要归功于提交之前的几次测试,我感觉这个寻路没有道理这么慢,内核很可能有随机的,甚至是故意的延时,发现导入了函数 KeDelayExecutionThread函数会通过 KUSER_SHARED_DATA 访问 TickCountLowDeprecated,并且在异或后被编码进入返回缓冲,可以在用户层恢复被驱动使用的这个 Tick 值然后
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290786.htm
[原创]2026 年腾讯游戏安全初赛 PC方向
203 浏览
11 回复
厉害厉害
太强了
最后于 2026-4-13 09:58
被Saileaxh编辑
,原因:
最后于 2026-4-13 09:58
被Saileaxh编辑
,原因:
太厉害了,学习学习
第五种泄漏应该是ZwProtectVirtualMemory函数修改页属性
h1111
第五种泄漏应该是ZwProtectVirtualMemory函数修改页属性
好的大佬 我看看 因为当时把这个sleep patch掉了之后,发现迷宫不能正常工作,就以为是泄漏点呢
第五种泄漏应该是ZwProtectVirtualMemory函数修改页属性
好的大佬 我看看 因为当时把这个sleep patch掉了之后,发现迷宫不能正常工作,就以为是泄漏点呢
江树
好的大佬 我看看[em_031] 因为当时把这个sleep patch掉了之后,发现迷宫不能正常工作,就以为是泄漏点呢
我发了文章,你可以参考一下
好的大佬 我看看[em_031] 因为当时把这个sleep patch掉了之后,发现迷宫不能正常工作,就以为是泄漏点呢
我发了文章,你可以参考一下
这是啥呀,老兄。
看不懂,技术又更新了么
我直接跑的模拟执行因为以往动态调试蓝屏都是虚拟机 今年图方便直接跑的模拟 但是忘记题目要求了
tql
想知道你总共花了多长时间?