1. 程式人生 > >修改PE檔案注入dll

修改PE檔案注入dll

修改思路 PE檔案中匯入dll資訊以結構體列表形式儲存在IDT中。只要將myhack.dll新增到列表尾部即可。

IDT結構 在這裡插入圖片描述 IDT的描述在IMAGE_OPTION_HEADER裡面的IMPORT Table,通過size可以確定是否有足夠的空間讓我們新增 IDT是由IMAGE_IMPORT_DESCRIPTION(簡稱IID)結構體組成的陣列,陣列末尾以NULL結構體結束。每個IID結構體為0x14位元組所以這裡IID區域為RVA 真正的IDT在Section .rdata的IMPORT Directory Table 在這裡插入圖片描述 這裡可以數一下我這裡有16個結構體(18*0x14=0x168)前面查到的size為0x168 沒有足夠的空間。 移動IDT

需要找一個足夠大的空間,這段空間在磁碟檔案中但是不會被載入到記憶體。 看一下rdata頭的資訊 在這裡插入圖片描述 size of raw data表示該節區在磁碟中的大小,0x50a00 virtual size表示該節區在記憶體中的大小,0x5081c 回頭看一下IDT的size是0x168,需要的是0x168+0x14=0x17c data段沒被載入的空間大小為

>>> hex(0x50a00-0x5081c)
'0x1e4'

所以.rdata區域的空間完全足夠用了。 找到IDT的所有資料準備搬家 在這裡插入圖片描述 把它放到hex(0x152600+0x5081c)='0x1a2e1c’這個地址處 在這裡插入圖片描述

修改IIMPORT Table的值 需要把剛才設定的IDT的地址和size放入到IMPORT Table裡面,注意這裡填入的是RVA(也就是載入記憶體時的地址)。 RVA_IDT=RVA_idata+size_idata_R=0x154000+0x5081c=0x1A481C 這裡是小端儲存所以應該倒著存放,別忘了size要改為0x17c 在這裡插入圖片描述

刪除繫結匯入表

BOUND IMPORT TABLE(繫結匯入表)是一種提高DLL載入速度的技術,不是必須項這裡為了方便刪除掉它。這裡不存在就不需要多餘的操作了。 建立IDT表項 在這裡插入圖片描述 如圖,每一項都有 import Name Table RVA RVA to INT 緊跟著2位0 Name RVA RVA to Dll Name import Address Table RVA RVA to IAT

IDT表結構 在這裡插入圖片描述 這三項也放在不被載入的區域即可,這裡放置在IDT表下面。

修改如下 在這裡插入圖片描述 修改IAT節區屬性 實際執行的時候IAT將會被替換所以寫入的IAT可以是隨意的資料,但是想要執行這個操作還需要修改IAT節區為可寫。 在這裡插入圖片描述

可以看到,預設rdata節區是不可寫的。 在原屬性上新增IMAGE_SCN_MEM_WRITE(80000000) 跟原本的40000040進行或運算c0000040. 在這裡插入圖片描述

找到了一個自動化的指令碼

myhack.dll

#include"stdio.h"
#include"windows.h"
#include"shlobj.h"
#include"Wininet.h"
#include"tchar.h"
#pragma comment(lib,"Wininet.lib")
#define DEF_BUF_SIZE (4096)
#define DEF_URL L"http://www.google.com/index.html"
#define DEF_INDEX_FILE L"index.html"


//DownloadURL
BOOL DownloadURL(LPCTSTR szURL, LPCTSTR szFile)
{
	BOOL bRet = FALSE;
	HINTERNET hInternet = NULL, hURL = NULL;
	BYTE pBuf[DEF_BUF_SIZE] = { 0, };
	DWORD dwBytesRead = 0;
	FILE *pFile = NULL;
	errno_t err = 0;
	hInternet = InternetOpen(L"ReverseCore", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (NULL == hInternet)
	{
		OutputDebugString(L"InternetOpen() failed!\n");
		return FALSE;
	}
	hURL = InternetOpenUrl(hInternet, szURL, NULL, 0, INTERNET_FLAG_RELOAD,0);
	if (NULL == hInternet)
	{
		OutputDebugString(L"InternetOpen() failed!\n");
		goto _DownloadURL_EXIT;
	}
	if (err == _tfopen_s(&pFile, szFile, L"wt"))
	{
		OutputDebugString(L"fopen() failed");
		goto _DownloadURL_EXIT;
	}
	while (InternetReadFile(hURL, pBuf, DEF_BUF_SIZE, &dwBytesRead))
	{
		if (!dwBytesRead)
			break;
		fwrite(pBuf, dwBytesRead, 1, pFile);
	}
	bRet = TRUE;
_DownloadURL_EXIT:
	if (pFile)
		fclose(pFile);
	if (hURL)
		InternetCloseHandle(hURL);
	if (hInternet)
	{
		InternetCloseHandle(hInternet);
	}

	return bRet;
}

//downloadURL會下載szURL中指定的網頁檔案並將其儲存在szFile目錄中

//DropFile
HWND g_hWnd = 0;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
	DWORD dwPID = 0;
	
	GetWindowThreadProcessId(hWnd, &dwPID);
	if (dwPID == (DWORD)lParam)
	{
		g_hWnd = hWnd;
		return FALSE;
	}
	return TRUE;
}

HWND GetWindowHandleFromPID(DWORD dwPID)
{
	EnumWindows(EnumWindowsProc, dwPID);
	return g_hWnd;
}
BOOL DropFile(LPCTSTR wcsFile)
{
	HWND hWnd = NULL;
	DWORD dwBufSize = 0;
	BYTE *pBuf = NULL;
	DROPFILES *pDrop = NULL;
	char szFile[MAX_PATH] = { 0 ,};
	HANDLE hMem = 0;
	WideCharToMultiByte(CP_ACP, 0, wcsFile, -1, szFile, MAX_PATH, NULL, NULL);
	dwBufSize = sizeof(DROPFILES)+strlen(szFile) + 1;
	if (!(hMem = GlobalAlloc(GMEM_ZEROINIT, dwBufSize)))
	{
		OutputDebugString(L"GlobalAlloc() failed!!!");
		return FALSE;
	}
	pBuf = (LPBYTE)GlobalLock(hMem);
	pDrop = (DROPFILES*)pBuf;
	pDrop->pFiles = sizeof(DROPFILES);
	strcpy_s((char *)(pBuf + sizeof(DROPFILES)), strlen(szFile) + 1, szFile);
	GlobalUnlock(hMem);
	if (!(hWnd = GetWindowHandleFromPID(GetCurrentProcessId())))
	{
		OutputDebugString(L"GetWndHandleFromPIF() failed!!\n");
		return FALSE;
	}
	PostMessage(hWnd, WM_DROPFILES, (WPARAM)pBuf, NULL);
	return TRUE;
}

//dummy函式
#ifdef __cplusplus
extern "C"{
#endif
	//出現在IDT中的dump export function......
	__declspec(dllexport)void dummy()
	{
		return;
	}
#ifdef __cplusplus
}
#endif


//dll main函式
DWORD WINAPI ThreadProc(LPVOID lParam)
{
	TCHAR szPath[MAX_PATH] = { 0, };
	TCHAR *p = NULL;
	GetModuleFileName(NULL, szPath, sizeof(szPath));
	if (p = _tcsrchr(szPath, L'\\'))
	{
		_tcscpy_s(p + 1, wcslen(DEF_INDEX_FILE) + 1, DEF_INDEX_FILE);
		if (DownloadURL(DEF_URL, szPath))
		{
			DropFile(szPath);
		}
	}
	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		CloseHandle(CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL));
		break;
	}
	return TRUE;
}