免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

MSR 寄存器

读写方法:
MSR 是CPU 的一组64 位寄存器,可以分别通过RDMSR 和WRMSR 两条指令进行读和写的操作,前提要在ECX 中写入MSR 的地址。对于RDMSR 指令,将会返回相应的MSR 中64bit 信息到(EDX:EAX)寄存器中;对于WRMSR 指令,把要写入的信息存入(EDX:EAX)中,执行写指令后,即可将相应的信息存入ECX 指定的MSR 中。MSR 的指令必须执行在level 0 或实模式下。

SYSENTER_CS_MSR: New code segment selector   0x174
SYSENTER_ESP_MSR: New Stack Pointer               0x175
SYSENTER_EIP_MSR: New Instruction Pointer        0x176

我们在windbg中可以看看这个三个寄存器的情况,这个是我机器里的情况。
lkd> rdmsr 176
msr[176] = 00000000`8053dad0
lkd> rdmsr 175
msr[175] = 00000000`ba4e0000
lkd> rdmsr 174
msr[174] = 00000000`00000008

我们在微软公开的内核WRK中发现关于这三个寄存器的设置,其中SYSENTER_EIP_MSR设置的值是KiFastCallEntry。
代码如下:

#define MSR_SYSENTER_CS             0x00000174
#define MSR_SYSENTER_ESP            0x00000175
#define MSR_SYSENTER_EIP            0x00000176

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);

     }
}


要获得 KiFastCallEntry 地址:

ULONG uKiFastCallEntryAddr = 0;
__asm
        {
                mov ecx, 0x176
                rdmsr
                mov uKiFastCallEntryAddr, eax
        }

返回列表