首页
社区
课程
招聘
[原创]一种Object hook的思路和实现过程
发表于: 2008-8-8 20:34 19174

[原创]一种Object hook的思路和实现过程

2008-8-8 20:34
19174

<一种Object hook的思路和实现过程>

作者:sudami [sudami@163.com]
时间:2008/08/08
主题:NtClose相关逆向
关键词:Object/type/hook/OkayToCloseProcedure

------------------------------------------------------
    本来不准备写出来污染眼球的,因为最终没有完全实现.但觉得思路可行,之前也没人具分析过,于是匆匆的写点儿文章,给大家提供些资料参考,也许有兴趣的同学能够进一步的深入...
写的很菜,老鸟飘过 . =.=|

    今天上午在坛子看到一帖,关于"抹掉所有进程中自己的Handle",来防止炉子的LzOpenProcess,防dump等作用.主要思路就是NtClose;其实那个古老的RK--FUTO_enhanced的code中已经实现的更加完善. 抽点儿时间想了想,于是就有了下面的一些分析:

lkd> u NtClose
nt!NtClose:
8056f9e9 8bff mov edi,edi
8056f9eb 55 push ebp
8056f9ec 8bec mov ebp,esp
8056f9ee 64a124010000 mov eax,dword ptr fs:[00000124h]
8056f9f4 0fbe8040010000 movsx eax,byte ptr [eax+140h]
8056f9fb 6a00 push 0 ;比WRK中多一个参数
8056f9fd 50 push eax
8056f9fe ff7508 push dword ptr [ebp+8]
8056fa01 e85bffffff call nt!ObpCloseHandle (8056f961)
;ObpCloseHandle(Handle, KeGetCurrentThread()->PreviousMode, 0);

8056fa06 5d pop ebp
8056fa07 c20400 ret 4
8056fa0a 90 nop
8056fa0b 90 nop
8056fa0c 90 nop
8056fa0d 90 nop
8056fa0e 90 nop
-------------------------------------------------------------------
lkd> u ObpCloseHandle l 20
nt!ObpCloseHandle:
8056f96c c645ff00 mov byte ptr [ebp-1],0
8056f970 64a124010000 mov eax,dword ptr fs:[00000124h]
8056f976 8b4d08 mov ecx,dword ptr [ebp+8] ;ecx = Handle
8056f979 8bf0 mov esi,eax
8056f97b 8b5e44 mov ebx,dword ptr [esi+44h] ;ebx = PsGetCurrentProcess();
8056f97e b800000080 mov eax,80000000h
8056f983 23c8 and ecx,eax
8056f985 3bc8 cmp ecx,eax
;/* Check if we're dealing with a kernel handle */
;#define KERNEL_HANDLE_FLAG (1 << ((sizeof(HANDLE) * 8) - 1))
; return (BOOLEAN)((ULONG_PTR)Handle & KERNEL_HANDLE_FLAG);

8056f987 0f84ccf00000 je nt!ObpCloseHandle+0x28 (8057ea59) ; -->Is a kernel handle
8056f98d 8bbbc4000000 mov edi,dword ptr [ebx+0C4h]
;edi = HandleTable = Process->ObjectTable;
;其他的判断会跳到这里

8056f993 ff7508 push dword ptr [ebp+8] ;
8056f996 ff8ed4000000 dec dword ptr [esi+0D4h];/* Disable Kernel APCs */
;Thread->KernelApcDisable--;
8056f99c 57 push edi
8056f99d e88bf6ffff call nt!ExMapHandleToPointer (8056f02d)
;eax = HandleTableEntry = ExMapHandleToPointer(HandleTable, Handle);
8056f9a2 85c0 test eax,eax
8056f9a4 0f844e210200 je nt!ObpCloseHandle+0xbc (80591af8) ;-->failed,很多处理...
8056f9aa ff7510 push dword ptr [ebp+10h] ;比WRK中多一个参数
8056f9ad 6a00 push 0
8056f9af ff750c push dword ptr [ebp+0Ch]
8056f9b2 ff7508 push dword ptr [ebp+8]
8056f9b5 50 push eax
8056f9b6 57 push edi
8056f9b7 e853000000 call nt!ObpCloseHandleTableEntry (8056fa0f)
; /* Now close the entry */
;ObpCloseHandleTableEntry( HandleTable,HandleTableEntry,Handle,
; AccessMode,FALSE,0 );
8056f9bc ff86d4000000 inc dword ptr [esi+0D4h];/* Enable Kernel APCs */
;Thread->KernelApcDisable++;

-------------------------------------------------------------------
lkd> u 8057ea59 l 20 ;-->Is a kernel handle
nt!ObpCloseHandle+0x28:
8057ea59 807d0c00 cmp byte ptr [ebp+0Ch],0
8057ea5d 0f852a0fffff jne nt!ObpCloseHandle+0x5c (8056f98d)
8057ea63 837d08fe cmp dword ptr [ebp+8],0FFFFFFFEh
8057ea67 0f84200fffff je nt!ObpCloseHandle+0x5c (8056f98d)
8057ea6d 837d08ff cmp dword ptr [ebp+8],0FFFFFFFFh
8057ea71 0f84160fffff je nt!ObpCloseHandle+0x5c (8056f98d)
8057ea77 314508 xor dword ptr [ebp+8],eax
;#define ObKernelHandleToHandle(Handle) \
; (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
;Handle = ObKernelHandleToHandle(Handle);

8057ea7a a154965680 mov eax,dword ptr [nt!PsInitialSystemProcess (80569654)]
8057ea7f 3bd8 cmp ebx,eax
;/* Check if we're not in the system process */
8057ea81 8b3d388c5680 mov edi,dword ptr [nt!ObpKernelHandleTable (80568c38)]
8057ea87 0f84060fffff je nt!ObpCloseHandle+0x62 (8056f993)
8057ea8d 8d4de4 lea ecx,[ebp-1Ch]
8057ea90 51 push ecx
8057ea91 50 push eax
8057ea92 e8fe8af7ff call nt!KeStackAttachProcess (804f7595)
8057ea97 c645ff01 mov byte ptr [ebp-1],1
8057ea9b e9f30effff jmp nt!ObpCloseHandle+0x62 (8056f993);attach到system进程后跳回去
--------------------------------------------------------------

;继续进到ObpCloseHandleTableEntry函数中:
nt!ObpCloseHandleTableEntry:
8056fa17 8b7d0c mov edi,dword ptr [ebp+0Ch]
8056fa1a 8b37 mov esi,dword ptr [edi]
8056fa1c 83e6f8 and esi,0FFFFFFF8h
;esi = ObjectHeader = ObpGetHandleObject(HandleEntry);
;#define ObpGetHandleObject(x) \
; ((POBJECT_HEADER)((ULONG_PTR)x->Object & ~OBJ_HANDLE_ATTRIBUTES))

8056fa1f 8b4e08 mov ecx,dword ptr [esi+8]
;nt!_OBJECT_HEADER +0x008 Type : Ptr32 _OBJECT_TYPE
;ecx = ObjectType = ObjectHeader->Type;
8056fa22 83b9a800000000 cmp dword ptr [ecx+0A8h],0
; nt!_OBJECT_TYPE +0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
; nt!_OBJECT_TYPE_INITIALIZER +0x048 OkayToCloseProcedure
;
8056fa29 8d5618 lea edx,[esi+18h] ; edx=Body=&ObjectHeader->Body;
8056fa2c 894dfc mov dword ptr [ebp-4],ecx
8056fa2f 89550c mov dword ptr [ebp+0Ch],edx
8056fa32 0f85e4ab0100 jne nt!ObpCloseHandleTableEntry+0x25 (8058a61c)
;-->正是跳到我们关心的地方.

------------------------------------------------------------------------
lkd> u 8058a61c
nt!ObpCloseHandleTableEntry+0x25:
8058a61c 64a124010000 mov eax,dword ptr fs:[00000124h]
8058a622 ff7514 push dword ptr [ebp+14h] ;AccessMode
8058a625 ff7510 push dword ptr [ebp+10h] ;Handle
8058a628 52 push edx ;Body
8058a629 ff7044 push dword ptr [eax+44h] ;PsGetCurrentProcess()
8058a62c ff91a8000000 call dword ptr [ecx+0A8h]
; if (!ObjectType->TypeInfo.OkayToCloseProcedure(
; PsGetCurrentProcess(),Body,Handle,AccessMode)) {
; /* 让其返回denny,直接拒绝关我们的句柄 */
; return STATUS_HANDLE_NOT_CLOSABLE;
; }
;
; ---- 要做手脚 ----
;典型的Object hook(MJ0011以前写过一篇文章,即是关于这个的[干涉注册表的hook];
;想必MJ跟踪了这些类似函数的流程,发现了这种隐蔽的hook)
;替换掉这个函数,在我们的fake函数中做处理,是我们自己要保护的handle,就拒绝之
; sudami[sudami@163.com] 2008/08/08
;
8058a632 84c0 test al,al
8058a634 0f85fe53feff jne nt!ObpCloseHandleTableEntry+0x52 (8056fa38)
8058a63a e929490700 jmp nt!ObpCloseHandleTableEntry+0x3f (805fef68) ; --->
8058a63f c3 ret
--------------------------------------------------------------------
lkd> u 805fef68 l 10
nt!ObpCloseHandleTableEntry+0x3f:
805fef68 57 push edi
805fef69 ff7508 push dword ptr [ebp+8]
805fef6c e802d7f6ff call nt!ExUnlockHandleTableEntry (8056c673)
805fef71 b8350200c0 mov eax,0C0000235h
; #define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS)0xC0000235)
805fef76 e9260bf7ff jmp nt!ObpCloseHandleTableEntry+0x158 (8056faa1)

lkd> u 8056faa1 l 10
nt!ObpCloseHandleTableEntry+0x158:
8056faa1 5f pop edi
8056faa2 5e pop esi
8056faa3 c9 leave
8056faa4 c21800 ret 18h

---------------------------------------------------------------------
ps:或者你可以进到ExDestroyHandle函数中,从这里思考其他思路
-->ExpLookupHandleTableEntry-->InterlockedExchangePointer(&HandleTableEntry->Object, NULL);

/////////////////////////////////////////////////////////////////////
继续原来的话题;关键就是patch掉那个函数,看看它的原型:

typedef NTSTATUS
(NTAPI *OB_OKAYTOCLOSE_METHOD)(
IN PEPROCESS Process OPTIONAL,
IN PVOID Object,
IN HANDLE Handle,
IN KPROCESSOR_MODE AccessMode
);

在fake函数中:


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (16)
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
看着很好看
可惜不懂。
2008-8-8 20:52
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
一直对object hook都不大明白
占位学习
2008-8-8 23:07
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
4
他是0,你指定一个给他不行么? 用WRK,搜索对应的变量名,找到赋值得地方,再挂个钩监控,我个人估计,系统会先检测那个位置是不是0,如果已经是非0了,就不赋值了
2008-8-9 00:02
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
5
不行.
可以给它指定一个地址,但此时会进入你的fake函数,要么全部放行,要么全部拒绝.等同于没有效果啊.

用WRK搜了之后,你会发现,系统初始化的时候没有给这个OkayToCloseProcedure安装回调函数.
我想应该是动态赋值....

所以啊...
2008-8-9 00:13
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
6
。。。。。。。。。。。。
2008-8-9 00:44
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
7
附酷图一张,某XXer'k牛的



不可当真。。。
上传的附件:
  • 1.jpg (94.76kb,1253次下载)
2008-8-9 09:12
0
雪    币: 107
活跃值: (1693)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
8
驱动怎么老看不懂, 又那么难学
2008-8-9 09:23
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
很强大··不懂··
2008-8-9 09:24
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
10
我是进来学习的
2008-8-9 12:57
0
雪    币: 311
活跃值: (124)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
收藏了,顶一个!
2008-8-11 22:58
0
雪    币: 105
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
进来找死的我是
2008-8-18 23:34
0
雪    币: 147
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
问大米个弱智的问题,你的代码中HOOK那个OkayToCloseProcedure的函数原型是什么得到的?
原来不是为NULL没有给出函数原型吗?,那你怎么知道
NTSTATUS
fake_OkayToCloseProcedure(       
        PEPROCESS Process OPTIONAL,
        PVOID Object,
        HANDLE Handle,
        KPROCESSOR_MODE AccessCheckMode
        )
参数的?
2008-9-3 18:38
0
雪    币: 147
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
还有这种HOOK怎么检查呢?
2008-9-3 18:38
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
无聊1234
2008-11-16 16:15
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
我也是来学习的,很多看不懂
2009-4-6 22:51
0
雪    币: 177
活跃值: (278)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
能否直接hook DeleteProcedure 或者SecurityProcedure,这个ok例程只是一个判断把,最终不是要调用别的码
2009-6-1 10:49
0
游客
登录 | 注册 方可回帖
返回
//