當前位置:編程學習大全網 - 編程語言 - DLL文件劫持應該怎麽辦

DLL文件劫持應該怎麽辦

DLL當壹個可執行文件運行時,Windows加載器將可執行模塊映射到進程的地址空間中,加載器分析可執行模塊的輸入表,並設法找出任何需要的DLL,並將它們映射到進程的地址空間中。

由於輸入表中只包含DLL名而沒有它的路徑名,因此加載程序必須在磁盤上搜索DLL文件。首先會嘗試從當前程序所在的目錄加載DLL,如果沒找到,則在Windows系統目錄查找,最後是在環境變量中列出的各個目錄下查找。利用這個特點,先偽造壹個系統同名的DLL,提供同樣的輸出表,每個輸出函數轉向真正的系統DLL。程序調用系統DLL時會先調用當前目錄下偽造的DLL,完成相關功能後,再跳到系統DLL同名函數裏執行,如圖18.4。這個過程用個形象的詞來描述就是系統DLL被劫持(hijack)了。

184.gif

利用這種方法取得控制權後,可以對主程序進行補丁。此種方法只對除kernel32.dll, ntdll.dll等核心系統庫以外的DLL有效,如網絡應用程序的ws2_32.dll,遊戲程序中的d3d8.dll,還有大部分應用程序都調用的lpk.dll,這些DLL都可被劫持。

利用5.6.2章提供的CrackMeNet.exe來演示壹下如何利用劫持技術制作補丁,目標文件用Themida v1.9.2.0加殼保護。

1.補丁地址

去除這個CrackMe網絡驗證方法參考第5章,將相關補丁代碼存放到函數PatchProcess( )裏。例如將401496h改成:

代碼:00401496 EB 29 jmp short 004014C1

補丁編程實現就是:

代碼:

unsigned char p401496[2] = {0xEB, 0x29};

WriteProcessMemory(hProcess,(LPVOID)0x401496, p401496, 2, NULL);

p401496這個數組的數據格式,可以用OllyDBG插件獲得,或十六進制工具轉換。例如Hex Workshop打開文件,執行菜單Edit/Copy As/Source即可得到相應的代碼格式。

2.構建輸出函數

查看實例CrackMeNet.exe輸入表,會發現名稱為ws2_32.dll的DLL,因此構造壹個同名的DLL來完成補丁任務。偽造的ws2_32.dll有著真實ws2_32.dll壹樣的輸出函數,完整源碼見光盤。實現時,可以利用DLL模塊中的函數轉發器來實現這個目標,其會將對壹個函數的調用轉至另壹個DLL中的另壹個函數。可以這樣使用壹個pragma指令:

代碼:#pragma comment(linker, "/EXPORT:SomeFunc=DllWork.someOtherFunc")

這個pragma告訴鏈接程序,被編譯的DLL應該輸出壹個名叫SomeFunc的函數。但是SomeFunc函數的實現實際上位於另壹個名叫SomeOtherFunc的函數中,該函數包含在稱為DllWork. dll的模塊中。

如要達到劫持DLL的目的,生成的DLl輸出函數必須與目標DLL輸出函數名壹樣,本例可以這樣構造pragma指令:

代碼:#pragma comment(linker, "/EXPORT:WSAStartup=_MemCode_WSAStartup,@115")

編譯後的DLL,會有與ws2_32.dll同名的壹個輸出函數WSAStartup,實際操作時,必須為想要轉發的每個函數創建壹個單獨的pragma代碼行,讀者可以寫壹個工具或用其他辦法,將ws2_32.dll輸出函數轉換成相應的pragma指令。

當應用程序調用偽裝ws2_32.dll的輸出函數時,必須將其轉到系統ws2_32.dl中去,這部分的代碼自己實現。例如WSAStartup輸出函數如下構造:

代碼:

ALCDECL MemCode_WSAStartup(void)

{

GetAddress("WSAStartup");

__asm JMP EAX;//轉到系統ws2_32.dll的WSAStartup輸出函數

}

其中GetAddress()函數的代碼如下:

代碼:

// MemCode 命名空間

namespace MemCode

{

HMODULE m_hModule = NULL; //原始模塊句柄

DWORD m_dwReturn[500] = {0}; //原始函數返回地址

// 加載原始模塊

inline BOOL WINAPI Load()

{

TCHAR tzPath[MAX_PATH]={0};

TCHAR tzTemp[MAX_PATH]={0};

GetSystemDirectory(tzPath, sizeof(tzPath));

strcat(tzPath,"\\ws2_32.dll");

m_hModule = LoadLibrary(tzPath);//加載系統系統目錄下ws2_32.dll

if (m_hModule == NULL)

{

wsprintf(tzTemp, TEXT("無法加載 %s,程序無法正常運行。"), tzPath);

MessageBox(NULL, tzTemp, TEXT("MemCode"), MB_ICONSTOP);

}

return (m_hModule != NULL);

}

// 釋放原始模塊

inline VOID WINAPI Free()

{

if (m_hModule)

FreeLibrary(m_hModule);

}

// 獲取原始函數地址

FARPROC WINAPI GetAddress(PCSTR pszProcName)

{

FARPROC fpAddress;

TCHAR szProcName[16]={0};

TCHAR tzTemp[MAX_PATH]={0};

if (m_hModule == NULL)

{

if (Load() == FALSE)

ExitProcess(-1);

}

fpAddress = GetProcAddress(m_hModule, pszProcName);

if (fpAddress == NULL)

{

if (HIWORD(pszProcName) == 0)

{

wsprintf(szProcName, "%d", pszProcName);

pszProcName = szProcName;

}

wsprintf(tzTemp, TEXT("無法找到函數 %hs,程序無法正常運行。"), pszProcName);

MessageBox(NULL, tzTemp, TEXT("MemCode"), MB_ICONSTOP);

ExitProcess(-2);

}

return fpAddress;

}

}

using namespace MemCode;

編譯後,用LordPE查看偽造的ws2_32.dll輸出函數,和真實ws2_32.dll完全壹樣,如圖18.5所示。

185.gif

查看偽造的ws2_32.dll中任意壹個輸出函數,例如WSACleanup:

代碼:

.text:10001CC0 ; int __stdcall WSACleanup()

.text:10001CC0 WSACleanup proc near

.text:10001CC0 push offset aWsacleanup ;"WSACleanup"

.text:10001CC5 call sub_10001000 ;GetAddress(WSACleanup)

.text:10001CCA jmp eax

.text:10001CCA WSACleanup endp

會發現輸出函數WSACleanup()首先調用GetAddress(WSACleanup),獲得真實ws2_32.dll中WSACleanup的地址,然後跳過去執行,也就是說ws2_32.dll各輸出函數被HOOK了。

3.劫持輸出函數

ws2_32.dll有許多輸出函數,經分析,程序發包或接包時,WSAStartup輸出函數調用的比較早,因此在這個輸出函數放上補丁的代碼。代碼如下:

代碼:

ALCDECL MemCode_WSAStartup(void)

{

hijack();

GetAddress("WSAStartup");

__asm JMP EAX;

}

hijack()函數主要是判斷是不是目標程序,如是就調用PatchProcess()進行補丁。

void hijack()

{

if (isTarget(GetCurrentProcess())) //判斷主程序是不是目標程序,是則補丁之

{

PatchProcess(GetCurrentProcess());

}

}

偽造的ws2_32.dll制作好後,放到程序當前目錄下,這樣當原程序調用WSASTartup函數時就調用了偽造的ws2_32.dll的WSASTartup函數,此時hijack()函數負責核對目標程序校驗,並將相關數據補丁好,處理完畢後,轉到系統目錄下的ws2_32.dll執行。

這種補丁技術,對加殼保護的軟件很有效,選擇掛接的函數最好是在殼中沒有被調用,當掛接函數被執行時,相關的代碼己被解壓,可以直接補丁了。有些情況下,必須用計數器統計掛接的函數的調用次數來接近OEP。此方法巧妙地繞過了殼的復雜檢測,很適合加殼程序的補丁制作。

壹些木馬或病毒也會利用DLL劫持技術搞破壞,因此當在應用程序目錄下發現系統壹些DLL文件存在時,應引起註意。

  • 上一篇:計算機畢業論文
  • 下一篇:如何用電腦制作遊戲
  • copyright 2024編程學習大全網