APC注入:Asynchronous Procedure Call,异步过程调用,每个线程都有一个APC队列,在用户模式下,当线程调用SleepEx,WaitForSingleObjectEx等进入"Alterable Wait Status.
此时系统会遍历APC队列,先进先出地处理其中函数(QueueUserAPC)
优:比较隐蔽 缺:实现的条件苛刻
//负责注入的exe
#include <Windows.h>
DWORD APCInject(PCHAR sProcName,PCHAR sDllName)
{
DWORD dRet=0;
OutputDebugStringA("[+] APCInject enter !");
//创建buffer
HANDLE hFile=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,strlen(sDllName)+1,NULL);
if(!hFile)
{
OutputDebugStringA("[-] APCInject CreateFileMapping error!");
return -2;
}
PCHAR hView=(PCHAR)MapViewOfFile(hFile,FILE_MAP_ALL_ACCESS,0,0,0);
if(!hView)
{
OutputDebugStringA("[-] APCInject MapViewOfFile error!");
CloseHandle(hFile);
return -3;
}
else
{
//给buffer设置待注入的dll路径
strcpy_s(hView,strlen(sDllName)+1,sDllName);
}
// 启动目标进程
PROCESS_INFORMATION pi;STARTUPINFOA st;
ZeroMemory(&pi,sizeof(pi));
ZeroMemory(&st,sizeof(st));
st.cb=sizeof(STARTUPINFO);
//以suspend方式创建进程
if(CreateProcessA(sProcName,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&st,&pi))
{
LPVOID RemoteString=NULL;
ULONG ViewSize=0;
void * lpDllName = NULL;
///
//目标进程地址空间分配待注入dll路径空间
lpDllName = VirtualAllocEx(pi.hProcess, NULL, (strlen(sDllName) + 1), MEM_COMMIT, PAGE_READWRITE);
if(lpDllName)
{
//把待注入dll路径写入目标进程空间
if(WriteProcessMemory(pi.hProcess, lpDllName, sDllName,strlen(sDllName), NULL))
{
LPVOID nLoadLibrary=(LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"),"LoadLibraryA");
//调用QueueUserAPC向远线程插入一个APC,这个APC就是LoadLibrary
if(!QueueUserAPC((PAPCFUNC)nLoadLibrary,pi.hThread,(ULONG_PTR)lpDllName))
{
OutputDebugStringA("[-] APCInject QueueUserAPC call error!");
dRet=-6;
}
}
else
{
OutputDebugStringA("[-] APCInject WriteProcessMemory call error!");
dRet=-5;
}
}
else
{
OutputDebugStringA("[-] APCInject VirtualAllocEx call error!");
dRet=-4;
}
//恢复主线程
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
{
OutputDebugStringA("[-] APCInject CreateProcess error!");
dRet=-4;
}
UnmapViewOfFile(hView);
CloseHandle(hFile);
OutputDebugStringA("[+] APCInject exit !");
return dRet;
}
void main(int argc, char **argv)
{
APCInject(argv[1],argv[2]);
}
//被注入的DLL
#include <Windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "the simple inject success", "Dll Inject", MB_OKCANCEL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
测试如下:
\Debug>Test.exe C:\Windows\System32\notepad.exe WaiGua.dll
测试结果: