HOOK SwapContext 枚举隐藏进程(学习笔记4)(2)

下面是主要代码

 

01 DWORD gThreadsProcessOffset =0x220;    // ETHREAD 在 EPROCESS偏移
02 /*
03  
04 +0x218 TopLevelIrp      : Uint4B
05 +0x21c DeviceToVerify   : Ptr32 _DEVICE_OBJECT
06 +0x220 ThreadsProcess   : Ptr32 _EPROCESS
07 */
08  
09 ULONG ProcessNameOffset = 0x174;      // 进程对应的文件名 在 EPROCESS偏移
10 /*
11 +0x170 Session          : Ptr32 Void
12 +0x174 ImageFileName    : [16] UChar
13 +0x184 JobLinks         : _LIST_ENTRY
14 */
15  
16 PProcessList wLastItem = NULL;       
17 int BeTerminate = 0;                  //1 表示线程必须要停止  3表示线程不是PENDING状态  0表示线程可以正常运行
18  
19 void _stdcall CollectProcess(PEPROCESS pEPROCESS)  // 搜集EPROCESS
20 {
21   if (!IsAdded(wLastItem, pEPROCESS)) AddItem(&wLastItem, pEPROCESS);
22   return;
23 }
24  
25 void __stdcall ThreadCollect(PUCHAR pEthread)   //根据ETHREAD得到EPROCESS 并调用CollectProcess来搜集
26 {
27   PEPROCESS pEprocess = *(PEPROCESS *)(pEthread + gThreadsProcessOffset);
28   if (pEprocess) CollectProcess(pEprocess);
29   return;
30 }
31  
32  
33 DWORD outPEthread = 0;
34 void __stdcall ProcessData(DWORD pInEthread, DWORD pOutEthread)
35 {
36   DWORD pid, eprocess;
37   char * pname;
38   if (MmIsAddressValid(PVOID(pInEthread+0x220)) )   
1 // 这里以及下面要判断是不是一个真正的 Ethread 结构体 有时好像调用SwapContext传进来的不是 
001 //Ethread 结构体 然后就蓝屏 具体没有深究 加个判断就不蓝了~
002   {
003     eprocess = *(DWORD*)(pInEthread+0x220);
004      
005     if (MmIsAddressValid(PVOID(eprocess) ) )
006     {
007       ThreadCollect((PUCHAR)pInEthread);
008     }
009      
010   }
011 }
012  
013  
014  
015 PBYTE GoBackAddr = NULL;
016 PBYTE ChangAddr = NULL;
017  
018 DWORD CallContextOffset = 0;
019  
020 __declspec(nakedVOID HookSwap()
021 {
022  
023   _asm
024   {
025     pushad
026       pushfd
027       cli
028   }
029  
030   _asm
031   {
032        // EDI 是换出的线程上下文
033          push edi
034       //ESI 是换入的线程上下文
035       push esi
036       call ProcessData   //搜集进程
037   }
038    
039   _asm
040   
041     sti
042       popfd
043       popad
044   }
045   _asm jmp DWORD PTR[GoBackAddr]
046 }
047  
048 /*
049 得到SwapContext地址的原理是
050 用PsLookupThreadByThreadId得到Idle System的KTHREAD
051 res=(PCHAR)(Thread->Tcb.KernelStack);
052 SwapAddr=*(DWORD *)(res+0x08);
053 */
054 PCHAR GetSwapAddr()
055 {
056   PCHAR res = 0;
057   NTSTATUS  Status;
058   PETHREAD Thread;
059    
060   if (*NtBuildNumber <= 2195)
061     Status = PsLookupThreadByThreadId((PVOID)4, &(PETHREAD)Thread);
062   else
063     Status = PsLookupThreadByThreadId((PVOID)8, &(PETHREAD)Thread);
064    
065   if (NT_SUCCESS(Status))
066   {
067     if (MmIsAddressValid(Thread))
068     {
069       res = (PCHAR)(Thread->Tcb.KernelStack);
070  
071     }
072     if (MmIsAddressValid(res+8))
073     {
074       _asm
075       {
076         mov eax,res
077           add eax,8
078           mov eax,[eax]
079           mov res,eax
080       }
081     }
082     else
083     {
084       res = 0;
085       return NULL;
086     }
087   }
088   _asm
089   {
090     mov eax,res
091       sub eax,5
092       mov ChangAddr,eax
093       mov edx,[eax+1]
094       mov CallContextOffset,edx
095       add eax,edx
096       add eax,5
097       mov GoBackAddr,eax
098       mov res,eax
099   }
100   return res;
101 }
102  
103  
104  
105 BOOL  HookSwapFunction(BOOL flag)
106
107   if (flag == TRUE)
108   {
109     KIRQL OldIrql=0;
110     DWORD NewOffset;//HookSwap-ChangAddr-5;
111     _asm
112     {
113       mov eax,HookSwap
114         mov edx,ChangAddr
115         sub eax,edx
116         sub eax,5
117         mov NewOffset,eax
118     }
119  
120     PAGED_CODE()
121       ASSERT(KeGetCurrentIrql()<=DISPATCH_LEVEL);
122     KeRaiseIrql(2,&OldIrql);//HIGH_LEVEL
123     __asm
124     {
125       CLI
126         MOV   EAX, CR0
127         AND   EAX, NOT 10000H  //disable WP bit
128         MOV   CR0, EAX
129     }
130     _asm
131     {
132       mov eax,ChangAddr
133         push NewOffset
134         pop dword ptr[eax+1]
135          
136     }
137      
138     __asm
139     {
140       MOV   EAX, CR0
141         OR    EAX, 10000H  //enable WP bit
142         MOV   CR0, EAX
143         STI
144     }
145      
146      
147     KeLowerIrql(OldIrql);
148      
149   }
150   //Bug Check 0xD1: DRIVER_IRQL_NOT_LESS_OR_EQUAL
151    
152   else
153   {
154     KIRQL OldIrql=0;
155     KeRaiseIrql(2,&OldIrql);///HIGH_LEVEL
156     __asm
157     {
158       CLI
159         MOV   EAX, CR0
160         AND   EAX, NOT 10000H  //disable WP bit
161         MOV   CR0, EAX
162     }
163      
164     _asm
165     {
166       mov eax,ChangAddr
167         push CallContextOffset
168         pop dword ptr[eax+1]
169     }
170      
171      
172     __asm
173     {
174       MOV   EAX, CR0
175         OR    EAX, 10000H  //enable WP bit
176         MOV   CR0, EAX
177         STI
178     }
179     KeLowerIrql(OldIrql);
180     //    DbgPrint("HookSwapFunctionFALSE");//jution
181   }
182    
183 }
184  
185 PEPROCESS processObject (PETHREAD ethread) {
186   return  (PEPROCESS)(ethread->Tcb.ApcState.Process);
187 }
188  
189  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值