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

来源:互联网 发布:集体智慧编程怎么样 编辑:程序博客网 时间:2024/04/29 20:42

下面是主要代码

 

01DWORD gThreadsProcessOffset =0x220;    // ETHREAD 在 EPROCESS偏移
02/*
03 
04+0x218 TopLevelIrp      : Uint4B
05+0x21c DeviceToVerify   : Ptr32 _DEVICE_OBJECT
06+0x220 ThreadsProcess   : Ptr32 _EPROCESS
07*/
08 
09ULONG ProcessNameOffset = 0x174;      // 进程对应的文件名 在 EPROCESS偏移
10/*
11+0x170 Session          : Ptr32 Void
12+0x174 ImageFileName    : [16] UChar
13+0x184 JobLinks         : _LIST_ENTRY
14*/
15 
16PProcessList wLastItem = NULL;       
17int BeTerminate = 0;                  //1 表示线程必须要停止  3表示线程不是PENDING状态  0表示线程可以正常运行
18 
19void _stdcall CollectProcess(PEPROCESS pEPROCESS)  // 搜集EPROCESS
20{
21  if (!IsAdded(wLastItem, pEPROCESS)) AddItem(&wLastItem, pEPROCESS);
22  return;
23}
24 
25void __stdcall ThreadCollect(PUCHAR pEthread)   //根据ETHREAD得到EPROCESS 并调用CollectProcess来搜集
26{
27  PEPROCESS pEprocess = *(PEPROCESS *)(pEthread + gThreadsProcessOffset);
28  if (pEprocess) CollectProcess(pEprocess);
29  return;
30}
31 
32 
33DWORD outPEthread = 0;
34void __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 
015PBYTE GoBackAddr = NULL;
016PBYTE ChangAddr = NULL;
017 
018DWORD 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
051res=(PCHAR)(Thread->Tcb.KernelStack);
052SwapAddr=*(DWORD *)(res+0x08);
053*/
054PCHAR 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 
105BOOL  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 
185PEPROCESS processObject (PETHREAD ethread) {
186  return  (PEPROCESS)(ethread->Tcb.ApcState.Process);
187}
188 
189 
原创粉丝点击