Capcom驱动程序漏洞:物理PC上的蓝屏,但虚拟机中没有蓝屏

时间:2018-08-01 15:37:25

标签: windows winapi kernel exploit windows-kernel

我正在使用流行的带有漏洞的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上工作,这对我来说是全新的。

link to crash dump

2 个答案:

答案 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服务。