DLL注入-APC注入
生活随笔
收集整理的这篇文章主要介绍了
DLL注入-APC注入
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
APC注入
APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:
1)当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断(或者是Messagebox弹窗的时候不点OK的时候也能注入)。
2)当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。
3)利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的。
核心函数:
局限:
这种注入方式局限性很明显,一是必须要等待时机,而是当注入成功后,SleepEx或者其他等待函数直接就会跳过当前等待继续往下走,这样可能造成被注入程序的不稳定行,经常导致被注入程序崩溃。
代码:
// LoadExeWin32.cpp : 定义控制台应用程序的入口点。 // #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;//根据进程名字获取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; } //关闭句柄 CloseHandle(handleThread); } } //循环下一个线程 } 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:
然后再写一个被注入程序:
测试结果:
注入自己的程序成功:
随便尝试了下注入QQ.exe,直接崩溃退出了。
总结
以上是生活随笔为你收集整理的DLL注入-APC注入的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: WindowsPE 第五章 导出表
- 下一篇: Windows核心编程 第十四章 虚拟内