2022游戏安全技术竞赛-决赛
- PlaneJun ・2022-4-29 15:59
运行效果
原程序运行后显示ACE,并且许秒后绘制消失。原题则要求如下:
程序分为SYS与EXE,EXE中只有一个与驱动通讯,即运行后让驱动执行绘制。
因此着重分析SYS。
详细分析
很明显将初赛的部分代码通过驱动来写。首先是获取DWM的EPROCESS。
然后获取D3DCompile函数地址用作后面修复,获取dxgi.dll后面用作HOOK。
紧接着开始在dxgi.dll中搜索特征码48 8B C4 55 56 57 41 54 41 55 41 56 41 57 48 81 ?? ?? 00,该特征码经过pdb关联可知为PresentMultiplaneOverlay头部。
调用ZwAllocateVirtualMemory对dwm申请可执行内存。
并将shellcode拷贝至新内存中,并解密。
然后会生成inline hook跳转代码,push xxxx ret
MDL映射Hook点内存并对其修改,即跳转到shellcode入口。
然后延迟5秒后,还原hook,并且1.5秒后将shellcode清空。
所有过程与初赛基本一致,包括绘制函数、初始化Shader、虚拟机代码,只不过虚拟机代码略有变动,因此不做详细分析。
实现方法
实现之前,为了防止驱动清空shellcode和还原HOOK(让绘制一直显示),需要对sys进行patch。
将红框代码进行nop填充后,得到如下代码。
然后再将sys签名后加载。
一、修复表
原指令集存在加密,故直接dump解密好的。
同样,直接将指令集进行模拟操作,并输出流程。
运行后发现问题与初赛一致,首先是坐标被污染成了一个负值,然后就是key被互换,按照初赛的操作方式对表修复。
然后写入表,获取表的地址也很简单,直接在HOOK头部拿到硬编码后进行跳转偏移计算即可。
运行效果。
二、Hook绘制
因为与初赛题一样,所以直接HOOK绘制。在初赛中获取旗帜的每个坐标和Key后写注入代码注入。
X | Y | Key (k1,k2) | Col |
---|---|---|---|
0x32 | 0x32 | k1=0x130BD0,k2=0xF814B4 | 0xFF2DDBE7 |
0x32 | 0x6E | k1=0x1BCD69,k2=0x7515C9 | 0xFF2DDBE7 |
0x32 | 0xAA | k1=0xD91997,k2=0x87A34B | 0xFF2DDBE7 |
0x32 | 0xE6 | k1=0xE82B18,k2=0x1CF400 | 0xFF2DDBE7 |
0x32 | 0x122 | k1=0x391FAA,k2=0x520EFE | 0xFF2DDBE7 |
0x32 | 0x15E | k1=0xD77DE2,k2=0xEBE72 | 0xFF2DDBE7 |
0x6E | 0x6E | k1=0xD9E5F1,k2=0xD1B52D | 0xFF2DDBE7 |
0xAA | 0xAA | k1=0xC42D8B,k2=0xB36FDF | 0xFF2DDBE7 |
0xE6 | 0xE6 | k1=0x34CF2B,k2=0x5B8FE7 | 0xFF2DDBE7 |
0x6E | 0xE6 | k1=0x71150,k2=0x788404 | 0xFF2DDBE7 |
0xAA | 0xE6 | k1=0xC42E8B,k2=0xC7371B | 0xFF2DDBE7 |
同样在HOOK头部拿到硬编码后进行跳转偏移计算拿到Draw地址,并在Draw函数执行前,用VEH进行HOOK调用。
注入后效果如下:
截图
因为题目要求为截图,不可拍照。又因为是dwm的绘制,因此普通截图无法截图。
一、GetBuffer
直接通过SwapChain获取 Buffer保存。运行后会在E盘生成DDS文件,用VS打开直接是图片显示。
注入之后会在绘制前自动截图一次。
二、shellcode注入截图
项目地址:https://github.com/lainswork/dwm-screen-shot
但是存在一个问题,就是PresentMultiplaneOverlay的会存在HOOK失败,解决方法为直接将4个HOOK的函数Hash全部改成PresentMultiplaneOverlay的Hash即可。
截图效果: