首页
社区
课程
招聘
[原创]谈谈NP和HS的通用unhook
发表于: 2008-2-4 20:59 46749

[原创]谈谈NP和HS的通用unhook

zhuwg 活跃值
11
2008-2-4 20:59
46749

祝各位新年快乐
一边听音乐一边写代码真的很舒服阿很舒服

先简单说以下,NP和HS都hook了以下一些SSDT
什么是SSDT?我不想说那些复杂的理论,希望以简单的事实帮助介绍
先向大S道歉,下文如有冒犯,还请大S原谅

怎么说呢,SSDT本身就是一个地址表,我们当他是个地址簿,也就是写了每个人的地址的记录表
今天,偶想给大S送新年礼物,怎么送到大S家里呢?就得查看地址簿了
上面是这样写的  大S: 游戏达人,外挂高人,破解牛人,脱壳圣人;分身有如月,堀北真希,花泽类,猪的理想;实际上是个阳光宝宝,吃的的白白胖胖的,每天都很开心;家住上海市X区X路X楼,进门左转、左转、再左转,敲门说找S.H.E就行了。
标准SSDT hook的方式就是改变这个地址,HS就是八地址改写成abnlab实验室,如果你照着走就到abnlab实验室了
他们就要检查你了,这么大一箱礼物?是不是带了炸弹阿,识别你的身份阿,但是这样怎么能行呢,经过他们一审核
我的新年礼物岂不是要过年以后才能到了?不行不行
只能先联系大S,大S说家在上海X别墅区X,偶于是就上门了,到了别墅,门卫不让偶进去阿,理由是偶没有邀请函

                         ; MmDeleteTeb(x,x)+Ep ...
.text:004129B3
.text:004129B3 BugCheckParameter1= dword ptr  8
.text:004129B3 arg_4           = dword ptr  0Ch
.text:004129B3
.text:004129B3 ; FUNCTION CHUNK AT .text:00445DD6 SIZE 00000049 BYTES
.text:004129B3
.text:004129B3                 mov     edi, edi
.text:004129B5                 push    ebp
.text:004129B6                 mov     ebp, esp
.text:004129B8                 push    esi
.text:004129B9                 push    edi
.text:004129BA                 mov     eax, large fs:124h
.text:004129C0                 mov     edi, [ebp+BugCheckParameter1]
.text:004129C3                 mov     esi, eax
.text:004129C5                 cmp     [esi+44h], edi
.text:004129C8                 jz      short loc_4129FF
.text:004129CA                 cmp     byte ptr [esi+165h], 0
.text:004129D1                 jnz     loc_445DD6
.text:004129D7                 mov     eax, large fs:994h
.text:004129DD                 test    eax, eax
.text:004129DF                 jnz     loc_445DD6
.text:004129E5                 call    ds:__imp__KeRaiseIrqlToDpcLevel@0 ; KeRaiseIrqlToDpcLevel()
.text:004129EB                 mov     byte ptr [ebp+BugCheckParameter1], al
.text:004129EE                 lea     eax, [esi+14Ch]
.text:004129F4                 push    eax
.text:004129F5                 push    [ebp+BugCheckParameter1]
.text:004129F8                 push    edi
.text:004129F9                 push    esi
.text:004129FA                 call    _KiAttachProcess@16 ; KiAttachProcess(x,x,x,x)
.text:004129FF
.text:004129FF loc_4129FF:                             ; CODE XREF: KeAttachProcess(x)+15j
.text:004129FF                 pop     edi
.text:00412A00                 pop     esi
.text:00412A01                 pop     ebp
.text:00412A02                 retn    4
.text:00412A02 _KeAttachProcess@4 endp

.text:004189DB ; __stdcall KeStackAttachProcess(x, x)
.text:004189DB                 public _KeStackAttachProcess@8
.text:004189DB _KeStackAttachProcess@8 proc near       ; CODE XREF: MmAttachSession(x,x)+58p
.text:004189DB                                         ; MiAttachToSecureProcessInSession(x)+43p ...
.text:004189DB
.text:004189DB arg_0           = dword ptr  8
.text:004189DB arg_4           = dword ptr  0Ch
.text:004189DB
.text:004189DB                 mov     edi, edi
.text:004189DD                 push    ebp
.text:004189DE                 mov     ebp, esp
.text:004189E0                 push    esi
.text:004189E1                 push    edi
.text:004189E2                 mov     eax, large fs:124h
.text:004189E8                 mov     esi, eax
.text:004189EA                 mov     eax, large fs:994h
.text:004189F0                 test    eax, eax
.text:004189F2                 jnz     loc_445DF1
.text:004189F8                 mov     edi, [ebp+arg_0]
.text:004189FB                 cmp     [esi+44h], edi
.text:004189FE                 jz      short loc_418A34
.text:00418A00                 call    ds:__imp__KeRaiseIrqlToDpcLevel@0 ; KeRaiseIrqlToDpcLevel()
.text:00418A06                 cmp     byte ptr [esi+165h], 0
.text:00418A0D                 mov     byte ptr [ebp+arg_0], al
.text:00418A10                 jnz     loc_445E0D
.text:00418A16                 lea     eax, [esi+14Ch]
.text:00418A1C                 push    eax
.text:00418A1D                 push    [ebp+arg_0]
.text:00418A20                 push    edi
.text:00418A21                 push    esi
.text:00418A22                 call    _KiAttachProcess@16 ; KiAttachProcess(x,x,x,x)
.text:00418A27                 mov     eax, [ebp+arg_4]
.text:00418A2A                 and     dword ptr [eax+10h], 0
.text:00418A2E
.text:00418A2E loc_418A2E:                             ; CODE XREF: KeStackAttachProcess(x,x)+63j
.text:00418A2E                                         ; KeAttachProcess(x)+33467j
.text:00418A2E                 pop     edi
.text:00418A2F                 pop     esi
.text:00418A30                 pop     ebp
.text:00418A31                 retn    8

我们有以下办法
1.直接执行函数+5字节处
这样可以,但是有其他问题,如果NP把函数hook改到函数中间或者末尾,我们很难定位
2.执行底层函数KiAttachProcess
KiAttachProcess(EPROCESS *Process,Irql)

.text:00412855 ; __stdcall KiAttachProcess(x, x, x, x)
.text:00412855 _KiAttachProcess@16 proc near           ; CODE XREF: KeAttachProcess(x)+47p
.text:00412855                                         ; KeStackAttachProcess(x,x)+47p ...
.text:00412855
.text:00412855 arg_0           = dword ptr  8
.text:00412855 arg_4           = dword ptr  0Ch
.text:00412855 arg_8           = byte ptr  10h
.text:00412855 arg_C           = dword ptr  14h
.text:00412855
.text:00412855 ; FUNCTION CHUNK AT .text:00445D4F SIZE 0000001E BYTES
.text:00412855 ; FUNCTION CHUNK AT .text:00445D72 SIZE 00000064 BYTES
.text:00412855
.text:00412855                 mov     edi, edi
.text:00412857                 push    ebp
.text:00412858                 mov     ebp, esp
.text:0041285A                 push    ebx
.text:0041285B                 mov     ebx, [ebp+arg_4]
.text:0041285E                 inc     word ptr [ebx+60h]
.text:00412862                 push    esi
.text:00412863                 mov     esi, [ebp+arg_0]
.text:00412866                 push    edi
.text:00412867                 push    [ebp+arg_C]
.text:0041286A                 lea     edi, [esi+34h]
.text:0041286D                 push    edi
.text:0041286E                 call    _KiMoveApcState@8 ; KiMoveApcState(x,x)
.text:00412873                 mov     [edi+4], edi
.text:00412876                 mov     [edi], edi
.text:00412878                 lea     eax, [esi+3Ch]
.text:0041287B                 mov     [eax+4], eax
.text:0041287E                 mov     [eax], eax
.text:00412880                 lea     eax, [esi+14Ch]
.text:00412886                 cmp     [ebp+arg_C], eax
.text:00412889                 mov     [esi+44h], ebx
.text:0041288C                 mov     byte ptr [esi+48h], 0
.text:00412890                 mov     byte ptr [esi+49h], 0
.text:00412894                 mov     byte ptr [esi+4Ah], 0
.text:00412898                 jnz     short loc_4128AD
.text:0041289A                 mov     [esi+138h], eax
.text:004128A0                 mov     [esi+13Ch], edi
.text:004128A6                 mov     byte ptr [esi+165h], 1
.text:004128AD
.text:004128AD loc_4128AD:                             ; CODE XREF: KiAttachProcess(x,x,x,x)+43j
.text:004128AD                 cmp     byte ptr [ebx+65h], 0
.text:004128B1                 jnz     loc_445D72
.text:004128B7                 lea     esi, [ebx+40h]
.text:004128BA
.text:004128BA loc_4128BA:                             ; CODE XREF: KiAttachProcess(x,x,x,x)+33513j
.text:004128BA                 mov     eax, [esi]
.text:004128BC                 cmp     eax, esi
.text:004128BE                 jnz     loc_445D4F
.text:004128C4                 mov     eax, [ebp+arg_C]
.text:004128C7                 push    dword ptr [eax+10h]
.text:004128CA                 push    ebx
.text:004128CB                 call    _KiSwapProcess@8 ; KiSwapProcess(x,x)
.text:004128D0                 mov     cl, [ebp+arg_8]
.text:004128D3                 call    @KiUnlockDispatcherDatabase@4 ; KiUnlockDispatcherDatabase(x)
.text:004128D8
.text:004128D8 loc_4128D8:                             ; CODE XREF: .text:00445D6Dj
.text:004128D8                                         ; KiAttachProcess(x,x,x,x)+3357Cj
.text:004128D8                 pop     edi
.text:004128D9                 pop     esi
.text:004128DA                 pop     ebx
.text:004128DB                 pop     ebp
.text:004128DC                 retn    10h
.text:004128DC _KiAttachProcess@16 endp
.text:004128DC

或者执行更加底层函数KiSwapProcess
.text:00404AC4 ; __stdcall KiSwapProcess(x, x)
.text:00404AC4 _KiSwapProcess@8 proc near              ; CODE XREF: KiAttachProcess(x,x,x,x)+76p
.text:00404AC4                                         ; KeDetachProcess()+73p ...
.text:00404AC4
.text:00404AC4 arg_0           = dword ptr  4
.text:00404AC4
.text:00404AC4                 mov     edx, [esp+arg_0]
.text:00404AC8                 xor     eax, eax
.text:00404ACA                 cmp     [edx+20h], ax
.text:00404ACE                 jz      short loc_404AFF
.text:00404AD0                 mov     ecx, ds:0FFDFF03Ch
.text:00404AD6                 mov     eax, [edx+20h]
.text:00404AD9                 mov     [ecx+48h], eax
.text:00404ADC                 mov     eax, [edx+24h]
.text:00404ADF                 mov     [ecx+4Ch], eax
.text:00404AE2                 mov     ecx, ds:0FFDFF038h
.text:00404AE8                 mov     eax, [edx+28h]
.text:00404AEB                 mov     [ecx+108h], eax
.text:00404AF1                 mov     eax, [edx+2Ch]
.text:00404AF4                 mov     [ecx+10Ch], eax
.text:00404AFA                 mov     eax, 48h
.text:00404AFF
.text:00404AFF loc_404AFF:                             ; CODE XREF: KiSwapProcess(x,x)+Aj
.text:00404AFF                 lldt    ax
.text:00404B02                 mov     ecx, ds:0FFDFF040h
.text:00404B08                 mov     edx, [esp+arg_0]
.text:00404B0C                 xor     eax, eax
.text:00404B0E                 mov     gs, ax
.text:00404B10                 mov     eax, [edx+18h]
.text:00404B13                 mov     [ecx+1Ch], eax
.text:00404B16                 mov     cr3, eax
.text:00404B19                 mov     ax, [edx+30h]
.text:00404B1D                 mov     [ecx+66h], ax
.text:00404B21                 retn    8
.text:00404B21 _KiSwapProcess@8 endp
.text:00404B21

我们仔细看代码,就是更改cr3
我们自己用代码完成-以下代码参考sinister

KiAttachProcess(EPROCESS *Process,Irql){

//CurThread=fs:124h
//CurProcess=CurThread->ApcState.Process;

if(CurProcess!=Process){
     if(CurProcess->ApcStateIndex || KPCR->DpcRoutineActive)KeBugCheckEx...
     }

//if we already in process's context
if(CurProcess==Process){KiUnlockDispatcherDatabase(Irql);return;}

Process->StackCount++;
KiMoveApcState(&CurThread->ApcState,&CurThread->SavedApcState);

// init lists
CurThread->ApcState.ApcListHead[0].Blink=&CurThread->ApcState.ApcListHead[0];
CurThread->ApcState.ApcListHead[0].Flink=&CurThread->ApcState.ApcListHead[0];
CurThread->ApcState.ApcListHead[1].Blink=&CurThread->ApcState.ApcListHead[1];
CurThread->ApcState.ApcListHead[1].Flink=&CurThread->ApcState.ApcListHead[1];;

//fill curtheads's fields
CurThread->ApcState.Process=Process;

CurThread->ApcState.KernelApcInProgress=0;
CurThread->ApcState.KernelApcPending=0;
CurThread->ApcState.UserApcPending=0;

CurThread->ApcState.ApcStatePointer.SavedApcState=&CurThread->SavedApcState;
CurThread->ApcState.ApcStatePointer.ApcState=&CurThread->ApcState;

CurThread->ApcStateIndex=1;

//if process ready, just swap it...
if(!Process->State)//state==0, ready
     {
     KiSwapProcess(Process,CurThread->SavedApcState.Process);
     KiUnlockDispatcherDatabase(Irql);
     return;
     }

CurThread->State=1; //ready?
CurThread->ProcessReadyQueue=1;

//put Process in Thread's waitlist
CurThread->WaitListEntry.Flink=&Process->ReadyListHead.Flink;
CurThread->WaitListEntry.Blink=Process->ReadyListHead.Blink;

Process->ReadyListHead.Flink->Flink=&CurThread->WaitListEntry.Flink;
Process->ReadyListHead.Blink=&CurThread->WaitListEntry.Flink;

// else, move process to swap list and wait
if(Process->State==1){//idle?
     Process->State=2; //trans
     Process->SwapListEntry.Flink=&KiProcessInSwapListHead.Flink;
     Process->SwapListEntry.Blink=KiProcessInSwapListHead.Blink;
        KiProcessInSwapListHead.Blink=&Process->SwapListEntry.Flink;
     KiSwapEvent.Header.SignalState=1;
     if(KiSwapEvent.Header.WaitListHead.Flink!=&KiSwapEvent.Header.WaitListHead.
Flink)
                    KiWaitTest(&KiSwapEvent,0xa); //fastcall
     }

CurThread->WaitIrql=Irql;
KiSwapThread();
return;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (57)
雪    币: 47147
活跃值: (20410)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
春节期间,礼物不断,感谢zhuwg 好文分享!
2008-2-4 21:13
0
雪    币: 208
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
恩 这个还可以
2008-2-4 21:24
0
雪    币: 134
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
文章写的很乱,没心思看了都,估计你听的是周杰伦的垃圾音乐吧,哈哈。
2008-2-4 22:12
0
雪    币: 184
活跃值: (65)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
这个裁判够狠,NP HS比武完毕,还要把击破他们的方法公布出来.
2008-2-4 22:16
0
雪    币: 437
活跃值: (273)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
6
什么是  HS
2008-2-4 22:17
0
雪    币: 8196
活跃值: (2691)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
强人!要顶!
2008-2-4 22:23
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
8
顶一下,虽然好多看不懂。。。
2008-2-4 22:27
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢 我水平有限,慢慢学习
2008-2-4 22:41
0
雪    币: 97697
活跃值: (200759)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
10
Thanks again for sharing your efforts zhuwg!
2008-2-5 02:10
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
11
感谢zhuwg的好文章.
2008-2-5 09:40
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
12
留名,顶了再看
2008-2-5 09:49
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
写的很棒 但是作为裁判身份 这样8和谐-_-!
2008-2-5 14:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢楼主分享精彩文章
2008-2-5 14:59
0
雪    币: 241
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
哇,居然不在DEBUGMAN 的主场先放出来。。。。。。。害我在那边还虾讨论。。。晕倒。。。

感谢楼主。。。。。祝楼主新年大发。。。。。。

先顶再看。。。。收藏之。。。。
2008-2-5 16:04
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
16
哈,这里也不是首发,首发地是邪恶八进制论坛。
2008-2-5 16:16
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
17
没有吧,,难道论坛时间不对?
偶贴子是在word里面写的,然后发各大坛子..
DEBUG和UNPACK几乎同时发
看雪一直打开比较慢,,米办法,
邪恶八进制是在看雪之后..
因为.邪恶八进制那里贴子反正没人回,发慢点米影响

米办法..大牛多地地方可以给点批评给偶啊.
2008-2-6 22:11
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
18
注意,,小说结局不在这里,在那个水贴里面
2008-2-6 22:12
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
19
如果加入应答机制,unhook会有难度。
能不能自己构造一套调试的框架呢?不依赖于操作系统的提供的机制。比如调试事件。
2008-2-8 19:16
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
20
调试事件不清楚具体流程怎么进行的.大牛指点
2008-2-8 21:23
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
21
我也不清楚细节。所以才问
2008-2-8 21:32
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
呵呵!太長了吧?
2008-2-9 16:08
0
雪    币: 277
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
好麻烦。。收藏备用。。。感谢了
2008-2-13 09:02
0
雪    币: 356
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
呵呵,有启发。但是有个现象我一直没办法解释。对于np较新的版本,r3的邪恶注入已经被我过掉了,保证调试器绝对没有被注入和hook,r0的相关hook也被我修改了,楼主说的那些hook都没有起作用了,但是只要np保护的目标进程处于调试状态,目标进程很快就会自动结束。包括创建目标进程的父进程也是一样的现象---不能处于attach状态.

我是用自己写的启动器来启动的目标进程,目标进程起起来以后已经可以正常的被远程读写,open等,sendinput,getdc等操作都一切正常,但是只要目标进程被调试器附加了就会出现上面说的这些现象。不仅是目标进程,包括我自己写的启动器也不能attach----先于np启动就attach上也不行,np起起来之前没任何问题,但是np启动起来以后过几秒钟被调试的进程就结束。但是对除了目标进程和目标进程的父进程之外的其他进程进行调试却没有任何问题。

大家能讨论一下是什么原因吗?
2008-2-13 15:25
0
雪    币: 356
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
还有一点,楼主大人所说的禁止邪恶线程被远程创建的方法似乎不能一概而论。现在新版本的NP似乎对保护目标进程中是否被NP正常创建了远程线程有所校验,除了被保护目标进程外其余的进程都可以禁止远程线程的创建,但是目标进程如果也禁止了,NP将会启动失败。
2008-2-14 09:43
0
游客
登录 | 注册 方可回帖
返回
//