吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 37011|回复: 55
收起左侧

[系统底层] HOOK NtOpenProcess 保护指定进程

  [复制链接]
zzage 发表于 2009-8-9 16:43
hook NtOpenProcess.JPG
汇编写的一个简单的HOOK SSDT例子
;HOOK NtOpenProcess 保护指定进程
;Code:zzage
;From:[url]http://hi.baidu.com/zzage[/url]

.386
.model flat,stdcall
option casemap:none

include D:\RadASM\masm32\include\w2k\ntstatus.inc 
include D:\RadASM\masm32\include\w2k\ntddk.inc 
include D:\RadASM\masm32\include\w2k\ntoskrnl.inc 
includelib D:\RadASM\masm32\lib\w2k\ntoskrnl.lib 
include D:\RadASM\masm32\Macros\Strings.mac

_NTOPENPROCESS typedef proto :DWORD,:DWORD,:DWORD,:DWORD
NTOPENPROCESS  typedef ptr   _NTOPENPROCESS

.data

OldNtOpenProcess NTOPENPROCESS ?
dwNtOpenProcess_Addr dd ?
dwImageFileNameOffset dd ?
.code

GetImageFileNameOffset proc uses esi ebx ;获取EPROCESS结构的ImageFileName偏移量函数
invoke IoGetCurrentProcess
mov esi, eax

xor ebx, ebx
.while ebx < 1000h
  lea eax, [esi+ebx]
  invoke _strnicmp, eax, $CTA0("system"), 6
  .break .if eax == 0
  inc ebx
.endw
.if eax == 0
  mov eax, ebx
.else
  xor eax, eax
.endif
ret

GetImageFileNameOffset endp

MyNtOpenProcess proc hProcess,DesiredAccess,pObjectAttributes,pClientId

        local lpEPROCESS:PVOID 
        
        mov ecx,pClientId
        assume ecx:ptr CLIENT_ID
        invoke PsLookupProcessByProcessId,[ecx].UniqueProcess,addr lpEPROCESS ;获取打开的目标进程的EPROCESS结构
        assume ecx:nothing
        
        .if eax == STATUS_SUCCESS
        
            mov esi,lpEPROCESS
            add esi,dwImageFileNameOffset ;指向EPROCESS结构的ImageFileName地址
        
            invoke _strnicmp, esi, $CTA0("notepad.exe"),7 ;判断开打的目标进程是否为我们要保护的进程
        
            .if eax==0
                mov        eax,STATUS_ACCESS_DENIED  ;如果是打开我们保护的进程,就返回拒绝!
                ret
        
            .endif
        
        .endif
        invoke OldNtOpenProcess,hProcess,DesiredAccess,pObjectAttributes,pClientId ;如果不是打开我们保护的进程,就返回到原来的NtOpenProcess函数
        ret

MyNtOpenProcess endp

DriverUnload proc pDriverObject:PDRIVER_OBJECT
        
        pushad
        invoke DbgPrint,$CTA0("卸载成功\n")
        cli
        mov eax,cr0
        xor eax,10000h
        mov cr0,eax
        mov esi,dwNtOpenProcess_Addr
        mov eax,OldNtOpenProcess
        mov dword ptr[esi],eax ;还原旧的NtOpenProcess函数地址
        mov eax, cr0
        xor eax,10000h
        mov cr0, eax 
        sti
        popad
        ret

DriverUnload endp


DriverEntry proc pDriverObject:PDRIVER_OBJECT,pRegistryPath:PUNICODE_STRING
        
        pushad
        invoke DbgPrint,$CTA0("安装成功\n")
        invoke GetImageFileNameOffset
        mov dwImageFileNameOffset,eax  ;获取EPROCESS结构的ImageFileName偏移量        
        mov eax,KeServiceDescriptorTable ;获取KeServiceDescriptorTable的地址
        mov esi,[eax]
        mov esi,[esi]    ;获取KeServiceDescriptorTable->ServiceTableBase
        invoke MmGetSystemRoutineAddress,$CCOUNTED_UNICODE_STRING("ZwOpenProcess") ;获取ZwOpenProcess的地址
        inc eax
               movzx ecx,byte ptr[eax];取NtOpenProcess服务号
        sal ecx,2      
               add esi,ecx
        mov dwNtOpenProcess_Addr,esi 
        mov edi,dword ptr[esi]
              mov OldNtOpenProcess,edi ;保存旧NtOpenProcess函数地址
        invoke DbgPrint,$CTA0("OldNtOpenProcess: %X \n"),OldNtOpenProcess
             mov edi,offset MyNtOpenProcess
        cli
        mov eax,cr0
        xor eax,10000h
        mov cr0,eax
        mov dword ptr[esi],edi ;替换成我们自己的MyNtOpenProcess函数
        mov eax, cr0
        xor eax,10000h
        mov cr0, eax 
        sti 
        invoke DbgPrint,$CTA0("MyNtOpenProcess: %X \n"),offset MyNtOpenProcess
        mov esi,pDriverObject
        mov [esi+34h],offset DriverUnload ;设置卸载例程
        popad
        mov eax,STATUS_SUCCESS
        ret

DriverEntry endp

end DriverEntry

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

惜双双 发表于 2009-8-9 19:09
恩。。我不太懂汇编。。不过看着汇编的大致样子。。

好像是 PsLookUpProcessById拿EPROCESS。然后取名字。发现是需要保护的名字。则拒绝。。

不过楼主。。我建议可以省略一个步骤。。

PUCHAR
PsGetProcessImageFileName(
                                                  __in PEPROCESS Process
                                                  );
这是微软提供的现成的函数可以直接取名字。省的为了通用还要搜索一番。。

/*
使用这个函数注意有一个问题。这个函数取名字的时候。只取前16位。若一个进程名字长过16位。则不准确.

不过普通程序的进程还没那么长的。。^_^。。可以偷个懒。
*/
头像被屏蔽
阿顺 发表于 2013-12-9 17:17
lzfqq0 发表于 2013-12-7 14:37
 楼主| zzage 发表于 2009-8-9 21:19
恩。。我不太懂汇编。。不过看着汇编的大致样子。。

好像是 PsLookUpProcessById拿EPROCESS。然后取名字。发现是需要保护的名字。则拒绝。。

不过楼主。。我建议可以省略一个步骤。。

PUCHAR
PsGetProcess ...
惜双双 发表于 2009-8-9 19:09


用PsGetProcessImageFileName确实比自己实现找偏移省去一些麻烦!ImageFileName在EPROCESS结构里是16个字节的的uchar,所以取到的ImageFileName最多就只能16个字节了,又学到东西了...非常感谢你的指教!
 楼主| zzage 发表于 2009-8-9 16:54
[s:52]...歪歪斜斜的...真好看....
wgz001 发表于 2009-8-9 21:29
很强大   膜拜下   
Tale 发表于 2009-8-9 21:32
期待SEH HOOK
frozenrain 发表于 2009-8-11 14:19
牛X 用现成的不用考虑平台问题 ,SSDT HOOK 学习 :)
zapline 发表于 2009-8-12 01:35
经典啊
avzhongjiezhe 发表于 2010-3-5 17:33
学习一下
zq3334389 发表于 2010-3-6 21:42
厉害,汇编好强大
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-3-29 20:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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