我正在调查电脑游戏中的反作弊机制,该机制使用了流行的Capcom驱动程序,但存在漏洞。
您可以通过DeviceIoControl((调用将用户模式函数传递给Capcom驱动程序,然后在内核上下文中执行这些调用。
现在我面临一个奇怪的问题:
我运行DeviceIoControl((调用,因为它们也被许多其他调用成功执行。在我的虚拟机中,DeviceIoControl((调用也可以正常工作。但是,当我在物理PC上执行代码时,我会看到一个蓝色屏幕,显示消息"SYSTEM_SERVICE_EXCEPTION"。
以下是在虚拟机中正常工作的代码,但在我的物理PC上不正常:
void __stdcall EmptyTestFunction(MmGetSystemRoutineAddress_t pMmGetSystemRoutineAddress, PVOID userData) {
}
DriverLoadingTest() {
HANDLE device = OpenDevice("Htsysm72FB");
CapcomCodePayload* codePayload = (CapcomCodePayload*)VirtualAlloc(nullptr, sizeof(CapcomCodePayload), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
BYTE codePayloadBuf[] = {
0xE8, 0x08, 0x00, 0x00, 0x00, // CALL $+8 ; Skip 8 bytes, this puts the UserFunction into RAX
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // UserFunction address will be here
0x48, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MOV RDX, userData
0x58, // POP RAX
0xFF, 0x20 // JMP [RAX]
};
*(ULONGLONG*)(codePayloadBuf + 5) = (ULONGLONG)EmptyTestFunction;
*(ULONGLONG*)(codePayloadBuf + 15) = (ULONGLONG)0;
codePayload->pointerToPayload = codePayload->payload;
ZeroMemory(codePayload->payload, PAYLOAD_BUFFER_SIZE);
CopyMemory(codePayload->payload, codePayloadBuf, sizeof(codePayloadBuf));
status = 0x0;
DWORD bytesReturned = 0x0;
DeviceIoControl(device, IOCTL_RunPayload64, &codePayload->pointerToPayload, sizeof(ULONG_PTR), &status, sizeof(status), &bytesReturned, 0);
printf("DeviceIoControl returned %08xn", status);
}
我只是在崩溃转储方面取得了有限的进展,因为我缺乏经验。每次执行以下指令时都会发生崩溃:
mov cr4, rax
其中rax=0000000000070678
异常代码为:c0000096
我把WinDbg"!analyze-v"崩溃转储挂在帖子的末尾。
我主要关心的是找出我现在如何解决这个问题。因为完全相同的代码在VM中工作,但在我的物理PC上不工作的情况对我来说是全新的。
链接到崩溃转储
CR4是x86控制寄存器之一,您显然在其中填充了导致CPU异常的东西。
该寄存器由一组标志位组成,如本文所述,所以让我们看看您正在设置哪些标志位:
0x70678=1110000011001111000b,因此我们有以下内容:
0 VME Virtual 8086 Mode Extensions - OFF (sounds OK)
1 PVI Protected-mode Virtual Interrupts - OFF
2 TSD Time Stamp Disable - OFF
3 DE Debugging Extensions - ON
4 PSE Page Size Extension - ON
5 PAE Physical Address Extension - ON
6 MCE Machine Check Exception- ON
7 PGE Page Global Enabled - OFF
8 PCE Performance-Monitoring Counter enable - OFF
9 OSFXSR Operating system support for FXSAVE and FXRSTOR instructions - ON
10 OSXMMEXCPT Operating System Support for Unmasked SIMD Floating-Point Exceptions - ON
11 UMIP User-Mode Instruction Prevention - OFF
12 LA57 (none specified) - OFF
13 VMXE Virtual Machine Extensions Enable - OFF
14 SMXE Safer Mode Extensions Enable - OFF
16 FSGSBASE Enables the instructions RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE - ON
17 PCIDE PCID Enable - ON
18 OSXSAVE XSAVE and Processor Extended States Enable - ON
20 SMEP[4] Supervisor Mode Execution Protection Enable - OFF
21 SMAP Supervisor Mode Access Prevention Enable - OFF
22 PKE Protection Key Enable - OFF
因此,其中一个会打乱苹果车,我的钱会花在第4位和/或第5位。
然而。为什么代码试图设置CR4?除非你是操作系统的一部分,否则我想不出你想在内核模式中这样做的任何原因你不是。
无论如何,我希望这能给你一些继续的东西。不过,我不喜欢这个问题,因为没有足够的背景,因此我投票决定结束(尽管我没有否决它,因为它确实对我有一些兴趣(。
事实证明,Hyper-V系统管理程序禁止写入寄存器CR4,这导致了蓝屏。
我不知道这是否是因为我从Capcom驱动程序访问内核。其他内核模块可能也会访问CR4寄存器?如果是,那么它与Capcom驱动程序具体相关。因此,如果有人遇到同样的问题,他们应该检查是否已启用Hyper-V虚拟机监控程序服务。