修改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
>>> 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節區為可寫。
找到了一個自動化的指令碼
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;
}