普通sysenter hook

从用户模式切换到内核模式的完整过程分析有讲到在用户态的代码执行了SYSENTER指令之后,处理器中的控制单元将寄存器MSR_IA32_SYSENTER_EIP的值装载到指令指针寄存器eip中。

从wrk中可以看到对它的初始化

VOID
KiLoadFastSyscallMachineSpecificRegisters(
    IN PLONG Context
    )

/*++

Routine Description:

    Load MSRs used to support Fast Syscall/return.  This routine is
    run on all processors.

Arguments:

    None.

Return Value:

    None.

–*/

{
    PKPRCB Prcb;

    UNREFERENCED_PARAMETER (Context);

    if (KiFastSystemCallIsIA32) {

        Prcb = KeGetCurrentPrcb();

        //
        // Use Intel defined way of doing this.
        //

        WRMSR(MSR_SYSENTER_CS,  KGDT_R0_CODE);
        WRMSR(MSR_SYSENTER_EIP, (ULONGLONG)(ULONG)KiFastCallEntry);
        WRMSR(MSR_SYSENTER_ESP, (ULONGLONG)(ULONG)Prcb->DpcStack);

    }
}

所以寄存器MSR_IA32_SYSENTER_EIP的值决定了sysenter后执行的下一条指令,所以我们只要修改该寄存器的值即可!

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <ntddk.h>

ULONG d_origKiFastCallEntry;

void onUnload (IN PDRIVER_OBJECT DriverObject)
{
    __asm{
        mov ecx, 0x176
        xor edx,edx
        mov eax, d_origKiFastCallEntry
        wrmsr
    }
}

ULONG i;

__declspec(naked) MyKiFastCallEntry()
{
    __asm{
        mov i , eax
        jmp [d_origKiFastCallEntry]
    }
}

NTSTATUS DriverEntry (IN PDRIVER_OBJECT theDriverObject , IN PUNICODE_STRING theRegisteryPath)
{
    theDriverObject->DriverUnload = onUnload;

    __asm{
        mov ecx, 0x176
        rdmsr
        mov d_origKiFastCallEntry,eax
        mov eax, MyKiFastCallEntry
        xor edx,edx
        wrmsr
    }

    return STATUS_SUCCESS;
}

编译加载后,我们再来看看MSR_IA32_SYSENTER_EIP的值:

kd> rdmsr 176
msr[176] = 00000000`905ae040
kd> u 905ae040
hooksysenter!MyKiFastCallEntry [d:\vs2012\hooksysenter\hooksysenter\hooksysenter.c @ 19]:
905ae040 a308005b90      mov     dword ptr [hooksysenter!i (905b0008)],eax
905ae045 ff250c005b90    jmp     dword ptr [hooksysenter!d_origKiFastCallEntry (905b000c)]

直接进入我自定义的方法中,然后jmp回原来的值。

kd> dd 905b000c  l 1
905b000c  8285e300

kd> u 8285e300
nt!KiFastCallEntry:
8285e300 b923000000      mov     ecx,23h
8285e305 6a30            push    30h
8285e307 0fa1            pop     fs
8285e309 8ed9            mov     ds,cx
8285e30b 8ec1            mov     es,cx
8285e30d 648b0d40000000  mov     ecx,dword ptr fs:[40h]
8285e314 8b6104          mov     esp,dword ptr [ecx+4]
8285e317 6a23            push    23h

本文链接:http://www.alonemonkey.com/sysenter-hook.html