首页
社区
课程
招聘
[旧帖] [求助]恳请大家帮我看一下-inline hook ZwOpenProcess不起作用?真么回事呢? 0.00雪花
发表于: 2012-5-4 02:42 1783

[旧帖] [求助]恳请大家帮我看一下-inline hook ZwOpenProcess不起作用?真么回事呢? 0.00雪花

2012-5-4 02:42
1783
各位朋友好.

  请勿笑我问的低级,但小弟实属新手,最近,我想自己开发一个保护进程的小工具,便想到了利用修改ZwopenProcess函数的执行流程才实现.可是,我发现,为什么没有效果呢?->即修改后和没有修改前十一样的,但是,我在WinDebug中看见,我确确实实修改成功了的啊?

  我个人奋战几天后,是在没辙了,请各位勿笑我,麻烦给我看一下,感谢.

我起初是用汇编实现的:

Asm code:

.386
.model flat,stdcall
option casemap:none

include    \masm32\include\w2k\ntstatus.inc
include    \masm32\include\w2k\ntddk.inc
include    \masm32\include\w2k\hal.inc
include    \masm32\include\w2k\ntoskrnl.inc
includelib \masm32\lib\w2k\ntoskrnl.lib
includelib \masm32\lib\w2k\hal.lib
include    \masm32\Macros\Strings.mac

.data

OldNtOpenProcess proto :DWORD,:DWORD,:DWORD,:DWORD
RealAddr dd ?
oldIrql dd ?
MyPid dw 1424

.code

;unload
DriverUnload proc dobj:PDRIVER_OBJECT

pushad

cli ;clear interrupt

mov eax,cr0
and eax,0fffeffffh
mov cr0,eax

;raise level
invoke KeRaiseIrqlToDpcLevel
mov oldIrql,eax

mov ecx,5
mov edi,RealAddr
mov esi,offset OldNtOpenProcess
rep movsb

invoke KeLowerIrql,oldIrql

mov eax,cr0
or eax,10000h
mov cr0,eax

sti

popad

ret

DriverUnload endp

OldNtOpenProcess proc phandle,access,objattr,pid

nop  ;mov edi,edi  //Generaly speaking
nop  ;push ebp
nop  ;mov ebp,esp
mov eax,RealAddr
add eax,5
jmp eax

OldNtOpenProcess endp

MyNtOpenProcess proc phandle,access,objattr,pid

;mov eax,dword ptr MyPid
;assume eax:ptr CLIENT_ID

;.if [eax].UniqueProcess == eax
mov eax,STATUS_ACCESS_DENIED
ret
;.endif

;assume eax:nothing

invoke OldNtOpenProcess,phandle,access,objattr,pid
ret

MyNtOpenProcess endp

;DriverEntry
DriverEntry proc pDriverObject:PDRIVER_OBJECT,path:PUNICODE_STRING

pushad

cli
mov eax, cr0   
and eax,0fffeffffh
mov cr0, eax

invoke KeRaiseIrqlToDpcLevel
mov oldIrql,eax

;Get a system routine function address
invoke MmGetSystemRoutineAddress,$CCOUNTED_UNICODE_STRING("ZwOpenProcess")

;Save the real function address
mov RealAddr,eax

;save the first five bytes' instructions
mov ecx,5
mov esi,eax
mov edi,offset OldNtOpenProcess
rep movsb

;Just count the distance
mov edx,offset MyNtOpenProcess
sub edx,eax
sub edx,5

;jmp address
mov byte ptr [eax],0e9h
xchg [eax+1],edx

invoke KeLowerIrql,oldIrql

mov eax, cr0  
or eax,1000h
mov cr0,eax
sti

mov eax,pDriverObject

assume eax:ptr DRIVER_OBJECT

mov [eax].DriverUnload,offset DriverUnload
assume eax:nothing

popad

mov eax,STATUS_SUCCESS
ret

DriverEntry endp
end DriverEntry

  可是,我发现虚拟机中对我的hook没有任何反应,即打开任何进程都正常,丝毫没有收到hook的影响...

WinDebug:

nt!DbgBreakPointWithStatus+0x4:
80527da8 cc              int     3
kd> g
ERROR: DavReadRegistryValues/RegQueryValueExW(4). WStatus = 5
ERROR: DavReadRegistryValues/RegQueryValueExW(5). WStatus = 5
ERROR: DavReadRegistryValues/RegQueryValueExW(6). WStatus = 5
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run kd.exe) or,                                        *
*       CTRL+BREAK (if you run WinDBG),                                       *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
nt!DbgBreakPointWithStatus+0x4:
80527da8 cc              int     3
kd> u zwopenprocess
nt!ZwOpenProcess:
804febfc b87a000000      mov     eax,7Ah
804fec01 8d542404        lea     edx,[esp+4]
804fec05 9c              pushfd
804fec06 6a08            push    8
804fec08 e844ea0300      call    nt!KeReleaseInStackQueuedSpinLockFromDpcLevel+0x95d (8053d651)
804fec0d c21000          ret     10h
nt!ZwOpenProcessToken:
804fec10 b87b000000      mov     eax,7Bh
804fec15 8d542404        lea     edx,[esp+4]
kd> g
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run kd.exe) or,                                        *
*       CTRL+BREAK (if you run WinDBG),                                       *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
nt!DbgBreakPointWithStatus+0x4:
80527da8 cc              int     3
kd> u zwopenprocess
nt!ZwOpenProcess:
804febfc e9d7065778      jmp     f8a6f2d8   ;确确实实跳转了啊,......
804fec01 8d542404        lea     edx,[esp+4]
804fec05 9c              pushfd
804fec06 6a08            push    8
804fec08 e844ea0300      call    nt!KeReleaseInStackQueuedSpinLockFromDpcLevel+0x95d (8053d651)
804fec0d c21000          ret     10h
nt!ZwOpenProcessToken:
804fec10 b87b000000      mov     eax,7Bh
804fec15 8d542404        lea     edx,[esp+4]
kd> g
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run kd.exe) or,                                        *
*       CTRL+BREAK (if you run WinDBG),                                       *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
nt!DbgBreakPointWithStatus+0x4:
80527da8 cc              int     3
kd> u zwopenprocess
nt!ZwOpenProcess:
804febfc b87a000000      mov     eax,7Ah
804fec01 8d542404        lea     edx,[esp+4]
804fec05 9c              pushfd
804fec06 6a08            push    8
804fec08 e844ea0300      call    nt!KeReleaseInStackQueuedSpinLockFromDpcLevel+0x95d (8053d651)
804fec0d c21000          ret     10h
nt!ZwOpenProcessToken:
804fec10 b87b000000      mov     eax,7Bh
804fec15 8d542404        lea     edx,[esp+4]

  今天,我又换做C写试了一下,发现...还是不起作用......

C code:

#include <ntddk.h>
#include <windef.h>

BYTE OldCode[5]={0x8b,0xff,0x55,0x8b,0xec};  
BYTE NewCode[5]={0xe9,0x00,0x00,0x00,0x00};

//保存RealFuncAddr
ULONG RealFuncAddr=0;

NTSTATUS OriginalZwOpenProcess(HANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);

VOID WPON();
VOID WPOFF();
VOID InlineHook();
VOID UnLineHook();
NTSTATUS DriverUnload(PDRIVER_OBJECT DriverObject);

NTSTATUS Fake_ZwOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
        DbgPrint("Called...\n");
        if ((long)ClientId->UniqueProcess == 1480)
        {
                return STATUS_ACCESS_DENIED;
        }
        return OriginalZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
}

__declspec(naked) NTSTATUS OriginalZwOpenProcess(HANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId)
{
        __asm
        {

               
                /*********************/
          mov  edi,edi
                  push ebp          
          mov  ebp,esp
                /*********************/

                 
                  mov  eax, RealFuncAddr
                  add  eax,5
                  jmp  eax
        }
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING pRegPath)
{
        UNICODE_STRING FuncName=RTL_CONSTANT_STRING(L"ZwOpenProcess");
        RealFuncAddr=(ULONG)MmGetSystemRoutineAddress(&FuncName);

        DbgPrint("ZwOpenProcess的目前地址为: 0x%x \n",RealFuncAddr);

        DbgPrint("dsx:Driver loading...\n");
        DriverObject->DriverUnload=DriverUnload;
        InlineHook();

        return STATUS_SUCCESS;
}

NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
        DbgPrint("dsx:Driver unloading...\n");
        UnLineHook();
        return STATUS_SUCCESS;
}

VOID WPON()           //开启内存只读页写保护
{
        _asm{
        mov eax,cr0
        or  eax,10000h
                mov cr0,eax
        }
}
VOID WPOFF()              //关闭内存只读页写保护
{
        _asm{
        mov eax,cr0
                and eax,not 10000h
                mov cr0,eax
        }
}

VOID InlineHook()
{
  ULONG RelateSpace;
  KIRQL  oldIrql;

  RelateSpace=(BYTE*)Fake_ZwOpenProcess-(BYTE*)RealFuncAddr-5;
  RtlCopyMemory(NewCode+1,&RelateSpace,4);
  WPOFF();
  oldIrql=KeRaiseIrqlToDpcLevel();                                //提升中断级
  RtlCopyMemory((BYTE*)RealFuncAddr,NewCode,5);
  KeLowerIrql(oldIrql);

  KdPrint(("dsx ZwOpenProcess Hooked Success!\n"));
  return;

}

VOID UnLineHook()                                 //恢复inlinehook的地方
{
  KIRQL  oldIrql;

  oldIrql=KeRaiseIrqlToDpcLevel();
  RtlCopyMemory((BYTE*)RealFuncAddr,OldCode,5);
  KeLowerIrql(oldIrql);
  WPON();
  KdPrint(("dsx ZwOpenProcess UnHooked Success!\n"));
  return;   
}

  唉,小弟确实没辙了,承望各位朋友帮助我一下.

  感谢!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 36
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
小弟就只是想通过挂钩ZwOpenProcess来简单的保护一下进程,麻烦各位朋友了.
2012-5-4 02:44
0
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
3
应用层调用OpenProcess不经过内核的ZwOpenProcess,直接NtOpenProcess了
2012-5-4 09:43
0
雪    币: 36
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
  那请问: 为什么挂钩SSDT来hookZwOpenProcess就可以呢(保护进程)?
2012-5-4 12:26
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
5
LZ有必要区分一下ZwOpenProcess和NtOpenProcess

ZwOpenProcess会提供一个id用于通过SSDT寻址NtOpenProcess。在应用层,我们可以自写一个ZwOprnProcess,只要提供正确的id能在SSDT中索引到NtOpenProcess即可。所以,你拦系统指定的ZwOprnProcess可能就不是稳定的了。

SSDT hook为啥可行,我想现在你应该明白了。

还有种方法是通过SSDT搞到NtOpenProcess的地址,直接inline hook 这个地址将更深入些。

至于再深入,我也不会了,努力学习中
2012-5-4 14:05
0
游客
登录 | 注册 方可回帖
返回
//