dll注入原理分析

獲取目標進程的pid
獲取目標進程的句柄
向目標進程寫入注入dll的路徑字符串
建立遠程線程

// zhuru1.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include "pch.h"
#include <iostream>
#include <stdio.h> 
#include <Windows.h> 
#include <TlHelp32.h> 
//Code By Pnig0s1992 
//Date:2012,3,13 


DWORD getProcessHandle(LPCTSTR lpProcessName)//根據進程名查找進程PID 
{
	DWORD dwRet = 0;
	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hSnapShot == INVALID_HANDLE_VALUE)
	{
		printf("\n獲得進程快照失敗%d", GetLastError());
		return dwRet;
	}

	PROCESSENTRY32 pe32;//聲明進程入口對象 
	pe32.dwSize = sizeof(PROCESSENTRY32);//填充進程入口對象大小 
	Process32First(hSnapShot, &pe32);//遍歷進程列表 
	do
	{
		if (!lstrcmp(pe32.szExeFile, lpProcessName))//查找指定進程名的PID 
		{
			dwRet = pe32.th32ProcessID;
			break;
		}
	} while (Process32Next(hSnapShot, &pe32));
	CloseHandle(hSnapShot);
	return dwRet;//返回 
}

INT main(INT argc, CHAR * argv[])
{
	LPCTSTR aimProcess = L"Music_Player.exe";
	DWORD dwPid = getProcessHandle((LPCTSTR)aimProcess);//得到目標進程pid
	LPCSTR lpDllName = "E:\\c_project\\Dlltest\\Debug\\Dlltest.dll";
	HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwPid);//獲取目標進程的句柄
	if (hProcess == NULL)
	{
		printf("\n獲取進程句柄錯誤%d", GetLastError());
		return -1;
	}
	DWORD dwSize = strlen(lpDllName) + 1;
	DWORD dwHasWrite;
	LPVOID lpRemoteBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);//獲取目標進程的空間
	if (WriteProcessMemory(hProcess, lpRemoteBuf, lpDllName, dwSize, &dwHasWrite))//向目標進程空間寫入注入dll的路徑
	{
		if (dwHasWrite != dwSize)
		{
			VirtualFreeEx(hProcess, lpRemoteBuf, dwSize, MEM_COMMIT);
			CloseHandle(hProcess);
			return -1;
		}

	}
	else
	{
		printf("\n寫入遠程進程內存空間出錯%d。", GetLastError());
		CloseHandle(hProcess);
		return -1;
	}

	DWORD dwNewThreadId;
	LPVOID lpLoadDll = LoadLibraryA;
	HANDLE hNewRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadDll, lpRemoteBuf, 0, &dwNewThreadId);//在目標進程中創建遠程線程
	if (hNewRemoteThread == NULL)
	{
		printf("\n建立遠程線程失敗%d", GetLastError());
		CloseHandle(hProcess);
		return -1;
	}

	WaitForSingleObject(hNewRemoteThread, INFINITE);//等待遠程線程執行結束

	CloseHandle(hNewRemoteThread);//關閉遠程線程

	//準備卸載之前注入的Dll 
	DWORD dwHandle, dwID;
	LPVOID pFunc = GetModuleHandleA;//獲得在遠程線程中被注入的Dll的句柄 
	HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpRemoteBuf, 0, &dwID);
	WaitForSingleObject(hThread, INFINITE);//等待遠程線程執行結束
	GetExitCodeThread(hThread, &dwHandle);//線程的結束碼即爲Dll模塊兒的句柄 
	CloseHandle(hThread);
	pFunc = FreeLibrary;
	hThread = CreateRemoteThread(hThread, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID); //將FreeLibraryA注入到遠程線程中去卸載Dll 
	WaitForSingleObject(hThread, INFINITE);//等待遠程線程執行結束
	CloseHandle(hThread);
	CloseHandle(hProcess);
	return 0;
}

問題一

每次當我先用ollydbg附加Music_Player.exe這個進程時,然後調試我們的注入程序,當執行到

在這裏插入圖片描述
OpenProcess返回NULL。
想到一個辦法,先不用olly attach,等在目標進程中創建了遠程線程後,我們在進行attach,於是乎陷入了死鎖
ollydbg停在了 ntdll.ldrshutdownthread
在這裏插入圖片描述
注入程序停在了WaitForSingleObject(hNewRemoteThread, INFINITE);等待目標線程的結束
在這裏插入圖片描述
在詢問過高人後發現是自己知識還存在很大的盲區。
ollydbg在attach目標進程後會將所有進程全部掛起
在這裏插入圖片描述
我們創建的遠程線程也被掛起了,因爲WaitForSingleObject(hNewRemoteThread, INFINITE),所以我們的注入程序會被阻塞
在這裏插入圖片描述
在這裏插入圖片描述
點擊resume all threads,激活所有線程
在這裏插入圖片描述
程序正常運行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章