作 者: bzhkl
时 间: 2008-12-11,12:01
链 接: http://bbs.pediy.com/showthread.php?t=78464
以前想检测一个被隐藏的进程 后来用暴力枚举的方法解决了 但是HOOK SwapContext没有看到有完整的代码 所以搜集了点网上有用的模块 自己整合实现了下 确定支持XP3, XP2没测试 应该也能支持
附完整工程代码
难点:是得到SwapContext地址 还有一些细节问题~
原理:KiSwapContext调用SwapContext时候 ESI存放的是要换进线程的上下文 EDI存放的是要换出线程的上下文 然后截获ESI 即换进的ETHREAD 得到相应的EPROCESS 然后搜集
缺点:对系统性能影响非常大,因为系统线程调度很频繁, wrk的KiSwapContext用汇编写的就能体现出来对效率的要求高~.
另外有个有趣的问题
KiSwapContext 是fastcall调用方式 就是通过ECX EDX传 多出的按STDCALL传
WRK 是这样注释的
; BOOLEAN
; KiSwapContext (
; IN PKTHREAD OldThread
; IN PKTHREAD NewThread
; )
但是看下 WRK中的代码
mov edi, ecx ; set old thread address
mov esi, edx ; set next thread address
movzx ecx, byte ptr [edi].ThWaitirql ; set APC interrupt bypass disable
call SwapContext ; swap context
发现的确是两个参数
用WINDBG看
80545975 8bf1 mov esi,ecx
80545977 8bbb24010000 mov edi,dword ptr [ebx+124h]
8054597d 89b324010000 mov dword ptr [ebx+124h],esi
80545983 8a4f58 mov cl,byte ptr [edi+58h]
80545986 e8f5000000 call nt!SwapContext (80545a80)
发现KiSwapContext 是一个参数, esi是要换进的线程上下文 是通过ECX (第一个参数得到) edi 则不是
所以结论 KiSwapContext的参数现在是一个了,也许我WRK没更新 老版本。。
WRK KiSwapContext 代码
cPublicFastCall KiSwapContext, 2
.fpo (0, 0, 0, 4, 1, 0)
;
; N.B. The following registers MUST be saved such that ebp is saved last.
; This is done so the debugger can find the saved ebp for a thread
; that is not currently in the running state.
;
sub esp, 4*4
mov [esp+12], ebx ; save registers
mov [esp+8], esi ;
mov [esp+4], edi ;
mov [esp+0], ebp ;
mov ebx, PCR[PcSelfPcr] ; set address of PCR
mov edi, ecx ; set old thread address
mov esi, edx ; set next thread address
movzx ecx, byte ptr [edi].ThWaitirql ; set APC interrupt bypass disable
call SwapContext ; swap context
mov ebp, [esp+0] ; restore registers
mov edi, [esp+4] ;
mov esi, [esp+8] ;
mov ebx, [esp+12] ;
时 间: 2008-12-11,12:01
链 接: http://bbs.pediy.com/showthread.php?t=78464
以前想检测一个被隐藏的进程 后来用暴力枚举的方法解决了 但是HOOK SwapContext没有看到有完整的代码 所以搜集了点网上有用的模块 自己整合实现了下 确定支持XP3, XP2没测试 应该也能支持
附完整工程代码
难点:是得到SwapContext地址 还有一些细节问题~
原理:KiSwapContext调用SwapContext时候 ESI存放的是要换进线程的上下文 EDI存放的是要换出线程的上下文 然后截获ESI 即换进的ETHREAD 得到相应的EPROCESS 然后搜集
缺点:对系统性能影响非常大,因为系统线程调度很频繁, wrk的KiSwapContext用汇编写的就能体现出来对效率的要求高~.
另外有个有趣的问题
KiSwapContext 是fastcall调用方式 就是通过ECX EDX传 多出的按STDCALL传
WRK 是这样注释的
; BOOLEAN
; KiSwapContext (
; IN PKTHREAD OldThread
; IN PKTHREAD NewThread
; )
但是看下 WRK中的代码
mov edi, ecx ; set old thread address
mov esi, edx ; set next thread address
movzx ecx, byte ptr [edi].ThWaitirql ; set APC interrupt bypass disable
call SwapContext ; swap context
发现的确是两个参数
用WINDBG看
80545975 8bf1 mov esi,ecx
80545977 8bbb24010000 mov edi,dword ptr [ebx+124h]
8054597d 89b324010000 mov dword ptr [ebx+124h],esi
80545983 8a4f58 mov cl,byte ptr [edi+58h]
80545986 e8f5000000 call nt!SwapContext (80545a80)
发现KiSwapContext 是一个参数, esi是要换进的线程上下文 是通过ECX (第一个参数得到) edi 则不是
所以结论 KiSwapContext的参数现在是一个了,也许我WRK没更新 老版本。。
WRK KiSwapContext 代码
cPublicFastCall KiSwapContext, 2
.fpo (0, 0, 0, 4, 1, 0)
;
; N.B. The following registers MUST be saved such that ebp is saved last.
; This is done so the debugger can find the saved ebp for a thread
; that is not currently in the running state.
;
sub esp, 4*4
mov [esp+12], ebx ; save registers
mov [esp+8], esi ;
mov [esp+4], edi ;
mov [esp+0], ebp ;
mov ebx, PCR[PcSelfPcr] ; set address of PCR
mov edi, ecx ; set old thread address
mov esi, edx ; set next thread address
movzx ecx, byte ptr [edi].ThWaitirql ; set APC interrupt bypass disable
call SwapContext ; swap context
mov ebp, [esp+0] ; restore registers
mov edi, [esp+4] ;
mov esi, [esp+8] ;
mov ebx, [esp+12] ;