1. 程式人生 > >注入(一):APC注入

注入(一):APC注入

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

測試結果: