注入(一):APC注入
阿新 • • 發佈:2019-02-02
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
測試結果: