首页
社区
课程
招聘
[原创]一种古老的保护进程
发表于: 2009-9-12 05:48 13832

[原创]一种古老的保护进程

2009-9-12 05:48
13832
第二次鼓起勇气发帖子,不知道算不算原创,在这篇文章里,唯一算得上是我想出来的,就是这个思路了,其他代码都是从其他地方A过来的  ^.^

    一直都在沿着大哥哥的脚步前进,每当看到哥哥们精湛的代码,总是激动万分。今天在瞧着一篇文章“简单inline hook ObReferenceObjectByHandle保护进程和屏蔽文件执行 地址为:http://bbs.pediy.com/showthread.php?t=65731”的时候,突发灵感,得到以下思路:( 如果此思路已经被牛人提过的话,那么纯属巧合了 ^.^ )不管是在结束进程也好,读取写入进程内容也罢,在调用ObReferenceObjectByHandle后,会返回被操作的进程的一个PEPROCESS结构,如果挂钩ObReferenceObjectByHandle函数,把返回的PEPROCESS替换为其他进程的PEPROCESS,那么不就相当于操作其他进程了吗?进一步的假设,如果替换为IS的进程,那么就等于对IS进程进行操作了,当要结束被操作的进程,也就等于要结束IS进程,于是就有了下面的保护进程的办法:

NTSTATUS _stdcall MyObReferenceObjectByHandle(HANDLE Handle,ACCESS_MASK DesiredAccess,POBJECT_TYPE ObjectType,KPROCESSOR_MODE AccessMode,PVOID *Object,POBJECT_HANDLE_INFORMATION HandleInformation)
{
        NTSTATUS Status;
        PVOID TempPtr;
        PVOID ReferencedObject;

        Status = RealObReferenceObjectByHandle(Handle, DesiredAccess, ObjectType, AccessMode, &ReferencedObject, HandleInformation);     //先调用原始函数
        if (NT_SUCCESS(Status))
        {

                if (ReferencedObject==(PVOID)MyEPROCESS)     //MyEPROCESS为自己关心的进程的一个结构,这里是不是自己关心的进程
                {
                        if (Object)
                        {
                                ReferencedObject = (PVOID)AvpEPROCESS;  //AvpEPROCESS是要替换的其他进程的PEPROCESS  
                                *Object = ReferencedObject;        //返回的结果已经不是被操作的进程的PEPROCESS,而是另外被替换的结果 - -!
                                DbgPrint("ReferencedObject :%X  (PVOID)AvpEPROCESS : %X",ReferencedObject,(PVOID)AvpEPROCESS);
                        }
                }
                else              //如果不是自己关系你的进程,那么一切正常
                {
                        if (Object)
                        {
                                //DbgPrint("ReferencedObject :%X",ReferencedObject);
                                *Object = ReferencedObject;
                        }
                }
        }
return Status;
}

上面代码执行后,显示结果说明已经被hook了:

lkd> u ObReferenceObjectByHandle
nt!ObReferenceObjectByHandle:
8056d559 8bff            mov     edi,edi
8056d55b 55              push    ebp
8056d55c 8bec            mov     ebp,esp
8056d55e 51              push    ecx
8056d55f 53              push    ebx
8056d560 56              push    esi
8056d561 57              push    edi
8056d562 64a124010000    mov     eax,dword ptr fs:[00000124h]

lkd> u ObReferenceObjectByHandle
nt!ObReferenceObjectByHandle:
8056d559 eafc38ff880800  jmp     0008:88FF38FC
8056d560 56              push    esi
8056d561 57              push    edi
8056d562 64a124010000    mov     eax,dword ptr fs:[00000124h]
8056d568 8b5d18          mov     ebx,dword ptr [ebp+18h]
8056d56b 33d2            xor     edx,edx
8056d56d 395508          cmp     dword ptr [ebp+8],edx
8056d570 8bf0            mov     esi,eax

lkd> u 88FF38FC
88ff38fc ea633e55b20800  jmp     0008:B2553E63
88ff3903 8bff            mov     edi,edi
88ff3905 55              push    ebp
88ff3906 8bec            mov     ebp,esp
88ff3908 51              push    ecx
88ff3909 53              push    ebx
88ff390a ea60d556800800  jmp     0008:8056D560
88ff3911 006f00          add     byte ptr [edi],ch

bin和代码都在压缩包。好了,丑俺献完了,下面问几个我碰到的,却又无法解决的问题:

代码执行过程中,并没有产生任何蓝屏现象,在虚拟机里,提示:

*** Virtual machine kernel stack fault (hardware reset) ***
The virtual machine just suffered a stack fault in kernel mode. On a real computer, this would amount to a reset of the processor. It can be caused by an incorrect configuration of the virtual machine, a bug in the operating system, or a problem in the VMware Workstation software. Press OK to reboot virtual machine or Cancel to shut it down.

在真机里,也没有蓝屏,但是自动重启,不知道哪位哥哥帮俺指出原因呢?

最后附上效果图:


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (20)
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
2
突然想起来,跟张无忌的“乾坤大挪移”很像。。。
2009-9-12 06:06
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
没看出任何地方的另类. ***********?

虚拟机上栈溢出了吧, 主机上你需要设置kernelDump
2009-9-12 08:19
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
我只找到了3个问题
#define IOCTL_CODE(index) (ULONG)CTL_CODE( FILE_DRIVER_MYUNKNOW, index, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA )
inBuf = Irp->AssociatedIrp.SystemBuffer;


1.应该用METHOD_BUFFERED,奇怪的是你用METHOD_NEITHER居然能正常

2.Hook时,EPROCESS还没有初始化

3.没有为EPROCESS保留引用计数
2009-9-12 08:59
0
雪    币: 225
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
有源码,自己拿windbg调试下呀
2009-9-12 11:20
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
6
我是刚入行的,请原谅我对这行的无知,虽然是几百万年前,但是对我来说,还是很新鲜。。。。
2009-9-12 13:14
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
替换操作对象 的确很早了
代码的流程有严重的问题  实机你没看见蓝屏 是因为你设置了自动重启 在你的电脑属性里取消就可以看见蓝屏了。
2009-9-12 13:46
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
8
阁下可能没有认真看代码吧?

ReferencedObject = (PVOID)AvpEPROCESS;  //AvpEPROCESS是要替换的其他进程的PEPROCESS  

上面那句是蓝,换成下面这句是正常:

ReferencedObject = (PVOID)MyEPROCESS;

所以我认为代码的流程不存在问题,原因可能因为替换成其他进程的EPROCESS结构体之后,会产生另外莫名其妙的后遗症,那才是问题的所在吧 - -!
2009-9-12 17:00
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
9
EPROCESS已经初始化了的,从应用层传递进来的pid,然后:

AvpPID = 0;
                        AvpPID =(HANDLE)atoi(inBuf);         //得到要转移到的傀儡进程pid
                        DbgPrint("AvpPID :%d",AvpPID);
                        //memset(&AvpEPROCESS,0,sizeof(PEPROCESS));
                        PsLookupProcessByProcessId(AvpPID,&AvpEPROCESS);
                        ObDereferenceObject(AvpEPROCESS);
2009-9-12 17:03
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
10
蓝屏的原因其实很简单~
提示一下:ObReferenceObjectByHandle会增加引用计数
2009-9-12 17:50
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我记得你把安装Hook放在了DriverEntry里
2009-9-12 17:56
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
12
我一直以为现在我在ObReferenceObjectByHandle的函数里不需要调用ObDereferenceObject来减少引数,等函数返回之后,引数的减少是由调用ObReferenceObjectByHandle的这个进程来完成的。。。。
2009-9-12 18:14
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
13
弱弱的问下,把hook放在DriverEntry里,会出现什么后果呢?
2009-9-12 18:15
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
再想了想,问题不是特别严重,静态变量初始值是0,所以开始时不替换。
但是还是有点问题,如果在IOCTL_HELLOWORD之后 IOCTL_SETHOOKOPENPROCESS之前调用被HOOK的函数呢

多了引用计数不是特别大问题,关键是另一边少了,
估计会导致某个EPROCESS被提前删除
2009-9-12 18:33
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
15
“如果在IOCTL_HELLOWORD之后 IOCTL_SETHOOKOPENPROCESS之前调用被HOOK的函数”

总的来说,在IOCTL_SETHOOKOPENPROCESS之前,那么ReferencedObject一定不等于(PVOID)MyEPROCESS,代码执行就会正常,蓝的关键在于替换EPROCESS结构体之后: *Object = (PVOID)AvpEPROCESS;   并且它不是马上就蓝,而是正常运行几十秒钟之后才蓝的。。这就是我不解的地方了
2009-9-12 18:52
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
16
  另外按照老V的提示,调用ObDereferenceObject(ReferencedObject); 减小计数,马上就蓝了。。。。。
2009-9-12 18:55
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
额,没看仔细
问题是该加引用计数的你没加上,别人关闭Handle的时候就会提前删除进程对象了
应该加上ObReferenceObject(AvpEPROCESS);
2009-9-12 20:02
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
18
加上ObReferenceObject(AvpEPROCESS); 之后,不蓝屏,直接卡死在那里了  - -#
2009-9-12 20:35
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
你这样做的后果
不是引用记数不释放的问题  
而是 系统实际上增加了ReferenceObject的引用记数  
因为你的修改 系统却认为是增加了Avpeprocess的引用
时间一长 肯定要出问题
2009-9-12 20:51
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
20
看了dump,错误的PROCESS_NAME 是System  汗。。。。
2009-9-13 03:27
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
大概是进程对象被删除了,所以系统访问的时候出错了
导致蓝屏虽然是系统进程,但是罪魁祸首其实是你
2009-9-13 07:45
0
游客
登录 | 注册 方可回帖
返回
//