这篇文章是我对 ShadowGate 题目的完整复盘整理版。和我之前的阶段性记录不同,这一版的目标不是只写“我已经做到哪”,而是尽可能把整道题的分析链路整理完整,形成一篇可以单独阅读的文章。不过我想把边界说清楚:· 文中有一部分内容,是我自己本地逆向、写工具、验证协议后得到的结论;· 还有一部分,是我当时没有完全做出来,后面参考了吾爱破解上一篇公开 writeup 才补齐的内容;· 所以这篇文章不是“纯原创完整通关”,而是一篇以我的分析为主、并结合公开 writeup 补全后续步骤的复盘文。这样写的好处是比较诚实,也更接近真实的做题过程。题目样本主要包括三部分:· 驱动:ShadowGateSys.sys· IDA 数据库:ShadowGateSys.sys.i64· 用户态程序:ShadowGateApp.exe从题目行为来看,它表面上是一个“迷宫 + 驱动 + 最短路”的组合题,但真正核心并不是迷宫本身,而是:· 用户态如何与驱动通信;· 驱动如何把“移动结果”反馈回用户态;· 这些反馈中,哪些是正常返回,哪些是隐藏泄露通道。如果把题目拆开,其实就是:1. 加载驱动并正确通信;2. 找出所有隐匿通信方式;3. 还原迷宫地图;4. 求最短路;5. 到达终点并恢复最终 Flag。这题最先让我锁定方向的,不是驱动,而是用户态控制台程序。从 ShadowGateApp.exe 的字符串和控制逻辑里,可以直接得到:· 设备路径:\\.\ShadowGate· 两个全局事件:o Global\MazeMoveOKo Global\MazeMoveWall对应截图如下:这一步非常关键,因为它说明:· 这题并不是完全黑盒;· 用户态和驱动之间存在一个清晰可复现的通信入口;· 同时,“移动结果”很可能还通过命名事件额外传回用户态。回到 ShadowGateSys.sys 之后,我本地确认到:· DriverEntry 在 0x140008000· 很快会跳转到实际初始化例程初始化阶段至少做了这些事情:1. 分配一块大小为 0x1D8 的内存;2. 创建设备对象 \Device\ShadowGate;3. 创建符号链接 \??\ShadowGate;4. 注册分发函数。驱动侧对应设备路径与用户态完全对上:· 驱动:\Device\ShadowGate· 符号链接:\??\ShadowGate· 用户态:\\.\ShadowGate这意味着我后续完全可以围绕 CreateFileW + DeviceIoControl 来做实验。我本地确认到的主要分发表如下:· IRP_MJ_CREATE -> 0x1400014B0· IRP_MJ_CLOSE -> 0x140001410· IRP_MJ_DEVICE_CONTROL -> 0x140001540· DriverUnload -> 0x140001840所以这题真正要啃的核心函数,其实就是:· IRP_MJ_DEVICE_CONTROL也就是说,整道题的协议层本质上就是若干个 IOCTL。我当时本地最先恢复出来的三个控制码是:IOCTL功能输入输出0x8001200C查询迷宫几何信息无24 字节0x80012008重置迷宫状态无无0x80012004执行移动12 字节0x84 字节其中 0x8001200C 返回六个 DWORD:· width· height· entry_x· entry_y· exit_x· exit_y公开 writeup 里对这三个 IOCTL 的识别图如下:
这一部分我本地和公开 writeup 是能互相印证的。从 ShadowGateApp.exe 的命令跳转表中,我本地能恢复出一套应用层方向语义:· UP = 0x10· DOWN = 0x20· LEFT = 0x30· RIGHT = 0x40接受的按键分别是:· W / I· S / K· A / J· D / L程序还支持:· R:重置· T:查看日志· H:帮助· Q / ESC:退出到这里为止,我已经能比较稳定地还原“控制台程序怎么看待方向”的这一层。这是我当时最重视的一部分,因为我觉得这题的本质不在迷宫,而在“反馈机制”。已经明确存在:· Global\MazeMoveOK· Global\MazeMoveWall这组名字几乎已经把用途写脸上了:· 成功前进 -> MazeMoveOK· 撞墙失败 -> MazeMoveWall我本地还恢复出了两组混淆后的名字:· Global\{B8E2C3D0· Global\{A7F3B2C1结合驱动中出现的:· ObReferenceObjectByName· KeReleaseSemaphore· ObfDereferenceObject我能比较有把握地说:· 除了事件以外,驱动还会通过命名信号量额外传递状态。为了不让分析停留在“静态猜测”,我本地还写了一个工具:· tools/shadowgate_tool.py它现在已经能做:· 打开 \\.\ShadowGate· 调 query / reset / move· 监控命名事件· 监控命名信号量· 统计耗时· 读取返回缓冲区关键字段· 可选监控用户态内存变化也就是说,我当时虽然还没完整把题做完,但已经把后续实验框架搭起来了。这一节的内容,严格来说不属于“我当时已经独立做出来的结果”,而是我后面参考了吾爱破解那篇文章之后,重新整理并补进来的。我会尽量用自己的表达去写,但要明确说明来源。参考文章:
登录后可查看完整内容
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290915.htm
[原创]2026腾讯游戏安全PC初赛 新手使用IDAPRO+AI结合参赛 分析复盘
389 浏览
6 回复
感谢
这个题我现在觉得应该直接dump驱动内存来分析会好一点,直接把驱动内存读出来,迷宫地图和最短步数都是明文的,再反过来想办法写自动探索地图(因为时序泄漏探测起来很不可靠,写R3的DFS探索很容易误判)
最后于 2026-4-22 21:25
被XieCZ1337编辑
,原因:
最后于 2026-4-22 21:25
被XieCZ1337编辑
,原因:
佬,题目可以给一份吗
c1aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6$3q4D9L8q4)9J5k6h3I4S2L8Y4A6G2N6i4g2Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8h3&6%4c8o6y4F1P5Y4y4@1M7r3f1`.
mb_soqpzdaf
佬,题目可以给一份吗
babK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6$3q4D9L8q4)9J5k6h3I4S2L8Y4A6G2N6i4g2Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8h3&6%4c8o6y4F1P5Y4y4@1M7r3f1`.
佬,题目可以给一份吗
babK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6$3q4D9L8q4)9J5k6h3I4S2L8Y4A6G2N6i4g2Q4x3X3g2U0L8$3#2Q4x3V1k6A6L8h3&6%4c8o6y4F1P5Y4y4@1M7r3f1`.
谢谢