靜態修改PE輸入法
在dll映射的時候回調用dll的入口函數DLLMain,且發送消息DLL_PROCESS_ATTACH,dll文件代碼如下:
// dllmain.cpp : 定義 DLL 應用程序的入口點。
#include "pch.h"
extern "C" _declspec(dllexport) void Msg(void);
void Msg(void)
{
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "ceshi", "zfy", MB_OKCANCEL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
爲了使程序啓動時能調用指定的dll文件,我們需要修改輸入表,插入一個IID。
目標DLL文件信息:dll name:DllDemo.dll 輸出函數:Msg()
宿主exe文件信息:
區段信息:
數據目錄表的輸入表項,輸入表地址:RVA:0x7604 RawOffset:0x6A04,大小:0xC8
輸入表:
先需要插入一個IID結構,而緊鄰輸入表的內存一般是與OriginalFirstThunk和FirstThunk相關聯的結構,不能被覆蓋,所以我們需要找一塊區域儲存包含已有輸入表的和新IID的輸入表。
新輸入表大小:
也就是說我們需要找一塊大小爲0xDC的空間用來下入新的輸入表,分析上面區段信息,只有.text區段的VirtualSize小於SizeOfRawData,也就是說該程序僅.text段有多餘的空間,多餘的空間大小0x7800-0x7748=0xB8<所需要的的大小0xDC,所以我們需要擴展最後一個節或者新添加一個節,這裏我們採用擴展最後一個節.rsrc
按照最小對齊值,我們爲.rsrc擴展0x200的大小,
調整區段大小,由0x80修改爲0x82,並在rsrc節尾部添加0x200個字節的空間,
修改數據目錄表中的輸入表項:
地址由0x7604改爲0x10400-0x8400+0xB000=0x13000,大小修改爲0xDC
將原始輸入表內容複製到新的地址:
現在我們需要找地方寫入dll的信息:
我們這裏選擇直接在其他的dll的後面添加,也就是.text段多餘的那一段空間
添加的dll的信息:
OriginalFirstThunk的RVA:0x8748
FirstThunk的RVA:0x8750
name的RVA:0x8758
注:從上面的可以看出,OriginalFirstThunk和FirstThunk後面都留了一個爲0的IMAGE_THUNK_DATA結構,這兩個DWORD分別爲INT和IAT的結束標誌。
完善新的輸入表:
因爲我們新的dll文件的FirstThunk指向的IAT表的地址位於.text段,該值在加載內存後需要能被修改,所以我們要保證.text的數據可以修改;
.text段的原始屬性:0x60000020,現需要可寫權限,將屬性值修改爲:0x60000020+0x80000000=0xE0000020
對.text段屬性修改:
運行程序前會先彈出message框,表示dll注入成功