`
jinghuainfo
  • 浏览: 1524001 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

pjf获得SwapContext地址方法的解析

 
阅读更多

pjf获得SwapContext地址方法的解析<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

在用hook SwapContext法来检查隐藏进程时,首要条件是获得SwapContext的地址。Pjf在博文 ([1]) 中提出了使用线程KernelStack中保存的地址来获得SwapContext地址的方法。本文主要来解析此法。注意本文中正在运行的、即将被换出的线程我们称为旧线程;即将换进的线程称为新线程。

SwapContextKiSwapContext中调用。下面先来看看XPSP2KiSwapContext的汇编代码:

nt!KiSwapContext:

8086dbbc 83ec10 sub esp,10h

8086dbbf 895c240c mov dword ptr [esp+0Ch],ebx

8086dbc3 89742408 mov dword ptr [esp+8],esi

8086dbc7 897c2404 mov dword ptr [esp+4],edi

8086dbcb 892c24 mov dword ptr [esp],ebp

8086dbce 648b1d1c000000 mov ebx,dword ptr fs:[1Ch] <--ebx = kpcr

8086dbd5 8bf1 mov esi,ecx <--esi=新线程的ETHREAD.

8086dbd7 8bbb24010000 mov edi,dword ptr [ebx+124h] <--edi=旧线程ETHREAD

8086dbdd 89b324010000 mov dword ptr [ebx+124h],esi <--当前线程表示已经变了.

8086dbe3 8a4f58 mov cl,byte ptr [edi+58h]

8086dbe6 e8f5000000 call nt!SwapContext (8086dce0)

8086dbeb 8b2c24 mov ebp,dword ptr [esp]

8086dbee 8b7c2404 mov edi,dword ptr [esp+4]

8086dbf2 8b742408 mov esi,dword ptr [esp+8]

8086dbf6 8b5c240c mov ebx,dword ptr [esp+0Ch]

8086dbfa 83c410 add esp,10h

8086dbfd c3 ret

再来看看XPSP2SwapContext部分汇编代码:

//ESI为新线程的ETHREADEDI为旧线程的ETHREAD

nt!SwapContext:

8086dce0 0ac9 or cl,cl

8086dce2 26c6462d02 mov byte ptr es:[esi+2Dh],2

8086dce7 9c pushfd //<---------旧线程的ESP-4

8086dce8 8d8b40050000 lea ecx,[ebx+540h]

8086dcee e8ddafffff call nt!KeAcquireQueuedSpinLockAtDpcLevel (80868cd0)

8086dcf3 8d8b38050000 lea ecx,[ebx+538h]

8086dcf9 e8feafffff call nt!KeReleaseQueuedSpinLockFromDpcLevel (80868cfc)

8086dcfe 8b0b mov ecx,dword ptr [ebx]

8086dd00 83bb9409000000 cmp dword ptr [ebx+994h],0

8086dd07 51 push ecx//<---------旧线程的ESP-4

8086dd08 0f8583010000 jne nt!ScPatchFxe+0x3c (8086de91)

8086dd0e 833d6cc5888000 cmp dword ptr [nt!PPerfGlobalGroupMask (8088c56c)],0

8086dd15 0f854d010000 jne nt!ScPatchFxe+0x13 (8086de68)

8086dd1b 0f20c5 mov ebp,cr0

8086dd1e 8bd5 mov edx,ebp

8086dd20 807f3100 cmp byte ptr [edi+31h],0

8086dd24 0f8419010000 je nt!SwapContext+0x163 (8086de43)

8086dd2a 8a4e2c mov cl,byte ptr [esi+2Ch]

8086dd2d 884b50 mov byte ptr [ebx+50h],cl

8086dd30 fa cli

8086dd31 896728 mov dword ptr [edi+28h],esp //旧线程的ESP保存在KernelStack

8086dd34 8b4618 mov eax,dword ptr [esi+18h]

8086dd37 8b4e1c mov ecx,dword ptr [esi+1Ch]

8086dd3a 2d10020000 sub eax,210h

8086dd3f 894b08 mov dword ptr [ebx+8],ecx

8086dd42 894304 mov dword ptr [ebx+4],eax

8086dd45 33c9 xor ecx,ecx

8086dd47 8a4e31 mov cl,byte ptr [esi+31h]

8086dd4a 83e2f1 and edx,0FFFFFFF1h

8086dd4d 0bca or ecx,edx

8086dd4f 0b880c020000 or ecx,dword ptr [eax+20Ch]

8086dd55 3be9 cmp ebp,ecx

8086dd57 0f85de000000 jne nt!SwapContext+0x15b (8086de3b)

8086dd5d 8d4900 lea ecx,[ecx]

8086dd60 f740e400000200 test dword ptr [eax-1Ch],20000h

8086dd67 7503 jne nt!SwapContext+0x8c (8086dd6c)

8086dd69 83e810 sub eax,10h

8086dd6c 8b4b40 mov ecx,dword ptr [ebx+40h]

8086dd6f 894104 mov dword ptr [ecx+4],eax

8086dd72 8b6628 mov esp,dword ptr [esi+28h] //此时esp已是新线程的上次切换时的值。

8086dd75 8b4620 mov eax,dword ptr [esi+20h]

8086dd78 894318 mov dword ptr [ebx+18h],eax

8086dd7b fb sti

8086dd7c 8b4744 mov eax,dword ptr [edi+44h]

8086dd7f 3b4644 cmp eax,dword ptr [esi+44h]

8086dd82 c6475000 mov byte ptr [edi+50h],0

8086dd86 7440 je nt!SwapContext+0xe8 (8086ddc8)

8086dd88 8b7e44 mov edi,dword ptr [esi+44h] //注意:edi改为新线程的EPROCESS

8086dd8b 8b4b48 mov ecx,dword ptr [ebx+48h]

8086dd8e 314834 xor dword ptr [eax+34h],ecx

8086dd91 314f34 xor dword ptr [edi+34h],ecx

8086dd94 66f74720ffff test word ptr [edi+20h],0FFFFh

8086dd9a 7571 jne nt!SwapContext+0x12d (8086de0d)

8086dd9c 33c0 xor eax,eax

8086dd9e 0f00d0 lldt ax

8086dda1 8d8b40050000 lea ecx,[ebx+540h]

8086dda7 e850afffff call nt!KeReleaseQueuedSpinLockFromDpcLevel (80868cfc)

8086ddac 33c0 xor eax,eax

8086ddae 8ee8 mov gs,ax

8086ddb0 8b4718 mov eax,dword ptr [edi+18h]

8086ddb3 8b6b40 mov ebp,dword ptr [ebx+40h]

8086ddb6 8b4f30 mov ecx,dword ptr [edi+30h]

8086ddb9 89451c mov dword ptr [ebp+1Ch],eax

8086ddbc 0f22d8 mov cr3,eax

8086ddbf 66894d66 mov word ptr [ebp+66h],cx

8086ddc3 eb0e jmp nt!SwapContext+0xf3 (8086ddd3)

8086ddc5 8d4900 lea ecx,[ecx]

8086ddc8 8d8b40050000 lea ecx,[ebx+540h]

8086ddce e829afffff call nt!KeReleaseQueuedSpinLockFromDpcLevel (80868cfc)

8086ddd3 8b4318 mov eax,dword ptr [ebx+18h]

8086ddd6 8b4b3c mov ecx,dword ptr [ebx+3Ch]

8086ddd9 6689413a mov word ptr [ecx+3Ah],ax

8086dddd c1e810 shr eax,10h

8086dde0 88413c mov byte ptr [ecx+3Ch],al

8086dde3 88613f mov byte ptr [ecx+3Fh],ah

8086dde6 ff464c inc dword ptr [esi+4Ch]

8086dde9 ff831c060000 inc dword ptr [ebx+61Ch]

8086ddef 59 pop ecx//<---------本线程ESP+4

8086ddf0 890b mov dword ptr [ebx],ecx

8086ddf2 807e4900 cmp byte ptr [esi+49h],0

8086ddf6 7504 jne nt!SwapContext+0x11c (8086ddfc)

8086ddf8 9d popfd //<---------本线程ESP+4

8086ddf9 33c0 xor eax,eax

8086ddfb c3 ret

我们主要来分析保存在线程KernelStack中的ESP堆栈的状态:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 345pt; HEIGHT: 220.5pt" type="#_x0000_t75"><imagedata o:title="Stack" src="file:///C:/DOCUME~1/cindy/LOCALS~1/Temp/msohtml1/01/clip_image001.jpg"></imagedata></shape>

KernelStackETHREAD0x28处:

nt!_ETHREAD

+0x000 Tcb : _KTHREAD

+0x000 Header : _DISPATCHER_HEADER

+0x000 Type : UChar

+0x001 Absolute : UChar

+0x002 Size : UChar

+0x003 Inserted : UChar

+0x004 SignalState : Int4B

+0x008 WaitListHead : _LIST_ENTRY

+0x000 Flink : Ptr32

+0x004 Blink : Ptr32

+0x010 MutantListHead : _LIST_ENTRY

+0x000 Flink : Ptr32

+0x004 Blink : Ptr32

+0x018 InitialStack : Ptr32

+0x01c StackLimit : Ptr32

+0x020 Teb : Ptr32

+0x024 TlsArray : Ptr32

+0x028 KernelStack : Ptr32 ß----此处

+0x02c DebugActive : UChar

…………

因为当前线程已经不是这个结构了,SwapContext8086dd88已经替换了ESP了。所以我们需要找一个非当前线程的PETHREAD,于是

*(PULONG)((PETHREAD->KernelStack) + 8) 就是SwapContext的返回地址了。

Pfj就是HOOK的这个地址。但是需要注意的是此处ESI还是新线程的ETHREAD;但是EDI已经不是旧线程的ETHREAD了,它已在SwapContext中被修改成新线程的EPROCESS(见SwapContext8086dd88)或其他值了。

所以若是你若HOOK此处,则只能使用ESI值作为新线程的ETHREADEDI是不能用了。网文《check hidden process(hook SwapContext)》([2])就是在此处出了点问题。

其实找到SwapContext地址也不难,可以使用KiSwapContextCall SwapContext指令(8086dbe6 e8f5000000 call nt!SwapContext)SwapContext地址为:

pSwapContext = *(PULONG)((PETHREAD->KernelStack) + 8);

pSwapContext = pSwapContext + *(PULONG)((ULONG)pSwapContext – 4);

HOOK此处的地址,ESI就是新线程的ETHREADEDI就是旧线程的ETHREAD了。

参考文献:

[1]. http://pjf.blogcn.com/diary,109827361.shtml

[2]. http://www.antiprote ct.com/printer_friendly_posts.asp?TID=4

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics