首页
社区
课程
招聘
[原创]拦截进程创建(不会卡死桌面)
发表于: 2011-1-28 16:44 24458

[原创]拦截进程创建(不会卡死桌面)

2011-1-28 16:44
24458
 
kd> u PspUserThreadStartup
nt!PspUserThreadStartup:
805c7050 6a20            push    20h
[COLOR=red]805c7052 6870ae4d80      push    offset nt!ObWatchHandles+0x61c (804dae70)[/COLOR]
805c7057 e8c41ef7ff      call    nt!_SEH_prolog (80538f20)
805c705c 64a124010000    mov     eax,dword ptr fs:[00000124h]
805c7062 8bf0            mov     esi,eax
805c7064 8975e0          mov     dword ptr [ebp-20h],esi
805c7067 8b7e44          mov     edi,dword ptr [esi+44h]
805c706a 897ddc          mov     dword ptr [ebp-24h],edi
 
kd> dt _ETHREAD
ntdll!_ETHREAD
   ...
   +0x224 StartAddress     : Ptr32 Void
   ...
 
 
/************************************************************************/
/*    获取信息,并根据用户的选择结束进程或者允许运行                     */
/*    arg[0] 和 arg[1] 分别为PspUserThreadStartup 的两个参数   */
/*    arg[0] = StartRoutine, arg[1] = StartContext                      */
/************************************************************************/
void DoSomethingIWant(PULONG arg)
{
 ULONG dwEProcess = (ULONG)PsGetCurrentProcess();
 ANSI_STRING ansiCurrentProcessName,ansiPerentProcessName;
 ULONG uRet = 0;
 ULONG Pid, PerentPid;
 KSPIN_LOCK    SpinLock;
 KIRQL kirql;
 PLIST_ENTRY head,curr;
 ULONG n;
 
 if (g_uStartSign == 0) //没准备好?
 {
  return;
 }
 Pid =  (ULONG)PsGetCurrentProcessId();
 PerentPid = *(PULONG)(dwEProcess + OFFSET_PERENT_PID_EPROCESS);//通过偏移从EPROCESS中获取父进程ID,偏移为硬编码
 KeInitializeSpinLock(&SpinLock);
 if (g_uStartSign != arg[1])  //是否为进程的第一个线程
 {
  //添加PID到PidTable中
  KeAcquireSpinLock(&SpinLock,&kirql); 
  SetPidTable(Pid, 1);
  KeReleaseSpinLock(&SpinLock,kirql);
  //取当前进程名
  GetProcessPathName(dwEProcess,&ansiCurrentProcessName);
  //取父进程名
  GetProcessPathNameByPID(PerentPid, &ansiPerentProcessName);
  //打印信息~~
  DbgPrint("[ProcessMon]Process Creating, Process Name = %s ,PID = %d ,PerentName = %s PID = %d\r\n",
   ansiCurrentProcessName.Buffer,Pid, ansiPerentProcessName.Buffer,PerentPid);
  //让用户选择
  uRet = GetUserChoose(&ansiPerentProcessName,&ansiCurrentProcessName, PerentPid, Pid);
 
  //从PidTable中删除PID
  KeAcquireSpinLock(&SpinLock,&kirql); 
  SetPidTable(Pid, 0);
  KeReleaseSpinLock(&SpinLock,kirql);
  //释放内存了.
  if(ansiCurrentProcessName.Length) RtlFreeAnsiString(&ansiCurrentProcessName);
  if(ansiPerentProcessName.Length) RtlFreeAnsiString(&ansiPerentProcessName); 
  //根据用户的选择允许运行或者结束进程
  if(uRet)
   ZwTerminateProcess(NtCurrentProcess(), 0);
  KeSetEvent(&g_eventNotify, 0, 0); //通知那些等待的线程---------------------
  KeClearEvent(&g_eventNotify);  //置为非信号----------------------------|
 }        //            | 
 else       //            | 
 {        //            |
  //不是第一个线程               |     
  while (IsPidInTable(Pid)) //如果线程所属进程在等待用户判断,则让其等待  |   
  {       //            |  
   KeWaitForSingleObject(&g_eventNotify,Executive,KernelMode,0,0); // <-----
  }
  //通过EPROCESS->ThreadListHead遍历线程,ThreadListHead的偏移量为硬编码
  for (n = 0, curr = head = (PLIST_ENTRY)(dwEProcess + OFFSET_THREAD_LIST_HEAD_EPROCESS);
    curr->Blink != head ;
    curr = curr->Blink, n++){} //计算当前进程的线程数目
  DbgPrint("[ProcessMon]Pid: %.4d  ,Thread count = %d\r\n",Pid, n);
 }
 
 return;
}
 
 
/************************************************************************/
/*   自己假冒的函数     保存现场后CALL DoSomethingIWant                 */
/************************************************************************/
__declspec(naked) void FakePspUserThreadStartup()
{
 __asm{
  pushfd
  pushad
  mov  ebx,esp
  add  ebx,44
  push ebx
  call DoSomethingIWant
  popad
  popfd
  jmp  g_Orig
 }
 
}
 
/************************************************************************/
/*   挂钩PspUserThreadStartup                 */
/*   挂钩的地址是PspUserThreadStartup+2                                 */
/************************************************************************/
void HookPspUserThreadStartup()
{ 
 PUCHAR pHookAddr = (PUCHAR)FindPspUserThreadStartupAddress();
 UCHAR JMPCode[5] = {0xe9,0,0,0,0};
 UCHAR JMPBackCode[5] = {0xe9,0,0,0,0};
 g_Orig = ExAllocatePool(NonPagedPool,10);
 if (!g_Orig)
 {
  DbgPrint("[ProcessMon]Failed with Allocate Pool\r\n");
  return ;
 }
 
 if (!pHookAddr) return;
 pHookAddr += 2; //挂钩的地址是PspUserThreadStartup+2
 
 *((PULONG)(JMPCode+1)) = (ULONG) FakePspUserThreadStartup - ((ULONG)pHookAddr + 5);
 *((PULONG)(JMPBackCode+1)) = (ULONG)pHookAddr + 5 - ((ULONG)g_Orig + 10);
 memcpy(
   g_Orig,
   (PVOID)pHookAddr,
   5);
 memcpy(
   (PVOID)((ULONG)g_Orig+5),
   (PVOID)JMPBackCode,
   5);
 __asm{
   cli
   mov  eax,cr0
   and  eax,not 10000h
   mov  cr0,eax
 }
 
 memcpy((PVOID)pHookAddr,JMPCode,5);
 
 __asm{
   mov  eax,cr0
   or   eax,10000h
   mov  cr0,eax
   sti
  }
 
}

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (21)
雪    币: 656
活跃值: (458)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
2
收藏哈,不错
2011-1-28 16:57
0
雪    币: 4560
活跃值: (1037)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
不错不错,收藏之
2011-1-28 17:08
0
雪    币: 225
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
不错不错,收藏之
2011-1-28 17:24
0
雪    币: 271
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wep
5
感谢分享。
2011-1-28 17:37
0
雪    币: 154
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2011-1-28 21:07
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
感觉还是卡死explorer并且把弹出窗口做成模态好.
2011-1-28 21:18
0
雪    币: 153
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
支持lz,祝愿找个好工作
2011-1-28 21:43
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
跟了下xp sp3 和 win7 找不到初始化apc的操作诶 请问楼主 哪个函数内 做api动作
2011-10-27 10:45
0
雪    币: 100
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
不错不错,留名备查
2011-12-19 22:53
0
雪    币: 9
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
mark一下,留名备查
2011-12-20 11:40
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
mark,谢谢楼主
2011-12-21 16:27
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
一个进程还可以,多次创建你怎么办?
2011-12-21 16:51
0
雪    币: 130
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
还有创建成功程序,被拦截的后果是无法考虑的。
2011-12-21 16:57
0
雪    币: 8833
活跃值: (2419)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
15
其实不用hook也可以拦截~
直接用CreateThreadNotifyRoutine也一样~~
PspUser那个thread中间直接call到CreateThreadNotifyRoutine哦~嘿嘿,各种内涵奥妙不言而喻~
2011-12-22 07:52
0
雪    币: 122
活跃值: (72)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
2012-4-16 17:42
0
雪    币: 949
活跃值: (18)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
17
mark r0 拦截进程。感谢共享
2012-4-16 18:00
0
雪    币: 238
活跃值: (55)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
18
mark r0
2012-4-16 18:02
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
谢谢楼主.~~这玩意以后肯定用得着.
2012-4-16 23:54
0
雪    币: 3590
活跃值: (6331)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
不错不错,收藏之
2012-11-29 19:45
0
雪    币: 123
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
不错不错,收藏之
2012-11-30 08:37
0
雪    币: 4064
活跃值: (4402)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
22
感谢分享!
2020-7-9 15:07
0
游客
登录 | 注册 方可回帖
返回