我正在使用流行的带有漏洞的Capcom驱动程序研究计算机游戏中的反作弊机制。
您可以通过DeviceIoControl()调用将用户模式函数传递给Capcom驱动程序,然后在内核上下文中执行。
现在我面临一个奇怪的问题:
我运行DeviceIoControl()调用,因为它们也被许多其他人成功执行。 在我的虚拟机中,DeviceIoControl()调用也可以正常工作。 但是,当我在物理PC上执行代码时,出现蓝屏,并显示消息“ SYSTEM_SERVICE_EXCEPTION”。
以下是在VM中正常运行的代码,但在我的物理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 %08x\n", status);
}
由于我缺乏经验,我在故障转储方面仅取得了有限的进展。 每当执行以下指令时,崩溃就会发生:
mov cr4, rax
使用rax = 0000000000070678
异常代码为:c0000096
我在文章末尾挂起了WinDbg“!analyze -v”故障转储。
我主要关心的是找出现在如何解决该问题以便解决。因为完全相同的代码可以在VM中工作,但不能在我的物理PC上工作,这对我来说是全新的。
答案 0 :(得分:1)
CR4是x86 control registers之一,您显然在其中含糊不清,这会导致CPU异常。
该寄存器由here中所述的一组标志位组成,因此让我们看一下要设置的标志位:
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?我想不出为什么要在内核模式下执行 的单一原因,除非您是操作系统的一部分。 你不是。
无论如何,我希望这能给您带来帮助。不过,我不喜欢这个问题,因为那里没有足够的背景信息,因此投票决定关闭(尽管我没有否决它,因为它确实吸引了我一些兴趣)。
答案 1 :(得分:1)
事实证明,Hyper-V虚拟机管理程序禁止写入CR4寄存器,这导致了蓝屏。
我不知道这是否是专门因为我从Capcom驱动程序访问内核。其他内核模块也可能会访问CR4寄存器吗?如果是,则与Capcom驱动程序特别相关。因此,如果有人遇到相同的问题,则应检查是否已启用Hyper-V Hypervisor服务。