combojiang
驱动牛犊
驱动牛犊
  • 注册日期2007-06-20
  • 最后登录2008-11-20
  • 粉丝1
  • 关注0
  • 积分3分
  • 威望9点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:2157回复:1

内核API Inline hook引发BSOD,大家看看是什么原因

楼主#
更多 发布于:2008-01-20 23:40
目前在写一个inline hook api的demo,采用在NtQuerySystemInformation前10个字节写入跳转指令,跳转到自己定义的函数中,等执行完hook函数后,再恢复NtQuerySystemInformation前10字节的内容,继续程序执行,可是在调试的过程中出现BSOD,反馈的错误是:
Break Due to KeBugCheckEx(UnHandled kernel mode exception) Error = 7f (UNEXPECTED_KERNEL_MODE_TRAP) P1 = 8  P2= 80042000 P3=0 P4 = 0

完整代码如下:
.386
.model flat, stdcall
option casemap:none

include w2k\ntstatus.inc
include w2k\ntddk.inc

include w2k\native.inc
include w2k\ntoskrnl.inc
include w2k\hal.inc
includelib C:\RadASM\masm32\lib\w2k\ntoskrnl.lib
includelib C:\RadASM\masm32\lib\w2k\hal.lib
include C:\RadASM\masm32\macros\strings.mac  hooksysapi.rar hooksysapi.rar  
;----------------------------------------------------------------------------------------------------
; D A T A
;----------------------------------------------------------------------------------------------------
.data
;保存地址

szcommand db 0EAh, 0AAh, 0AAh ,0AAh, 0AAh, 08h, 0h ,090h ,090h, 090h
szOldCmd  db 10 dup(0)

NewNtQuerySystemInformationAddr dd ?

;----------------------------------------------------------------------------------------------------
; C O N S T A N T S
;----------------------------------------------------------------------------------------------------
.const
CCOUNTED_UNICODE_STRING "\\Device\\devHideprocess", g_usDeviceName,       4
CCOUNTED_UNICODE_STRING "\\??\\slHideprocess",      g_usSymbolicLinkName, 4
CCOUNTED_UNICODE_STRING "explorer.exe",             processname,          4

SetHookOn  proto
SetHookOff proto
WpOn proto
WpOff proto
;----------------------------------------------------------------------------------------------------
; C O D E
;----------------------------------------------------------------------------------------------------
.code

;本例从第二个块开始遍历,因为第一个块通常是System Idle Process.
NewNtQuerySystemInformation proc SysInfoClass,lpSysInfo,SysInfoL,Return
    pushad
        invoke SetHookOff
    invoke NtQuerySystemInformation,SysInfoClass,lpSysInfo,SysInfoL,Return  ;调用原函数
    
    test eax,eax ;判断调用是否成功
    jnz exit
    .if SysInfoClass == SystemProcessesAndThreadsInformation  ;5
        mov esi,lpSysInfo
        mov ebx,esi       ;ebx指向前一个块
        add esi,[esi]     ;esi指向后一个块
        @@:
        add esi,38h       ;在38h偏移处取得进程名字。
        invoke RtlCompareUnicodeString,addr processname, esi, 1
        
        .if eax== 0 ;找到进程块
            invoke DbgPrint, $CTA0("\nsuccessful \n")
            .if dword ptr[esi-38h] == 0     ;是最后一个块
                mov dword ptr[ebx],0    ;让前一个块作为最后的块
                jmp exit                ;退出循环
            .else
                sub esi,38h      ;回到块首
                mov edx,[esi]    ;edx --->NextEntryDelta
                add [ebx],edx    ;让前一个块指向当前块的下一个块
                
                add esi,[esi]    ;遍历当前块的下一个块,继续查找下一个隐藏的进程
                jmp @B           ;继续循环
            .endif
        .else
            sub esi,38h             ;回到块首
            cmp dword ptr[esi],0    ;判断是否到了最后一个块
            jz exit                 ;是,退出循环
            mov ebx,esi             ;否则前一个块指针指向当前块
            add esi,[esi]           ;当前块指针指向下一个结构块
            jmp @B                  ;继续循环
        .endif
    .endif
    
exit:
       invoke SetHookOn
       popad
       ret

NewNtQuerySystemInformation endp

;----------------------------------------------------------------------------------------------------
; H O O K F U N C
;----------------------------------------------------------------------------------------------------
SetHookOn proc

        ;保存原来NtQuerySystemInformation的开头10字节
        pushad
        cld
        mov esi, 08060798Ah ;NtQuerySystemInformation的地址
        lea edi, szOldCmd
        mov ecx, 10
        rep movsb
        
        ;申请非分页内存,将新函数拷贝到其中。
        invoke ExAllocatePool,NonPagedPool,256
        mov NewNtQuerySystemInformationAddr,eax
        cld
        lea esi,NewNtQuerySystemInformation
        lea edi,NewNtQuerySystemInformationAddr
        mov ecx,081h
        rep movsb
        
        ;得到将非分页内存的首地址,添加到szcommand中
        lea eax,NewNtQuerySystemInformationAddr
        lea edi,szcommand+1
        stosd
        
        ;将szcommand写入原函数开头字节
        invoke WpOff
        cld
        lea esi,szcommand
        mov edi,08060798Ah ;NtQuerySystemInformation
        mov ecx,10
        rep movsb
        invoke WpOn
        
        popad
    ret

SetHookOn endp

SetHookOff proc
       pushad
       ;恢复原函数开头字节
       invoke WpOff
       cld
       mov edi,08060798Ah;NtQuerySystemInformation
       lea esi,szOldCmd
       mov ecx,10
       rep movsb
       invoke WpOn
       popad
       ret

SetHookOff endp

WpOn proc
        mov eax,cr0             ;move CR0 register into EAX
        or  eax,10000H          ;enable WP bit    
        mov cr0, eax            ;write register back        
        sti                     ;enable interrupt
WpOn endp

WpOff proc
        cli                    ;dissable interrupt
        mov    eax, cr0        ;move CR0 register into EAX
        and eax, not 10000H    ;disable WP bit
        mov    cr0, eax        ;write register back
WpOff endp


;----------------------------------------------------------------------------------------------------
; DriverUnload
;----------------------------------------------------------------------------------------------------
DriverUnload proc pDriverObject:PDRIVER_OBJECT
    ;必须保存环境,否则后果很严重。在这个函数中恢复被修改的地址。
    
    pushad

    invoke DbgPrint, $CTA0("\nEntry into DriverUnload \n")

        invoke SetHookOff
        invoke ExFreePool,NewNtQuerySystemInformationAddr
    invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
    mov eax,pDriverObject
    invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
    popad
    
    ret

DriverUnload endp


DriverEntry proc pDriverObject:PDRIVER_OBJECT,pusRegistryPath:PUNICODE_STRING

    LOCAL status:NTSTATUS
    local pDeviceObject:PDEVICE_OBJECT
    
    invoke DbgPrint, $CTA0("\nEntry into DriverEntry\n")
    mov status, STATUS_DEVICE_CONFIGURATION_ERROR
    invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
    .if eax == STATUS_SUCCESS
        mov eax, pDriverObject
        assume eax:ptr DRIVER_OBJECT
        mov [eax].DriverUnload, offset DriverUnload
        assume eax:nothing
        invoke SetHookOn
        mov status, STATUS_SUCCESS
    .endif
    mov eax, status
    
    ret
DriverEntry endp

end DriverEntry
achillis
驱动牛犊
驱动牛犊
  • 注册日期2008-04-14
  • 最后登录2009-01-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望17点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-10-02 20:22
建议在调用原函数时不要这么搞,改来改去,调用又频繁,不蓝才怪~
游客

返回顶部