日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

导入表注入原理和C语言实现

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 导入表注入原理和C语言实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、導入表注入的原理

注入是把DLL加載到另一個進程的4GB地址空間中,實現方式有很多種,導入表注入是我學的第一種注入,是通過修改程序的導入表,把自己的DLL添加到導入表中,來實現這個目的。

導入表是連續存儲在節里的,它后面還有其他數據,不能直接追加一個導入表,所以必須找一塊足夠大的內存,把原來的所有導入表移動過去,再追加我們DLL的導入表。新增節是比較簡單的做法,我的代碼中也采用新增節。

導入表注入是讓系統根據EXE的導入表,幫我們實現加載DLL,需要知道一點,DLL至少要有一個導出函數,系統才會幫我們加載DLL

新增節存儲如下數據(順序隨意安排):
原來的所有導出表 IMAGE_IMPORT_DESCRIPTOR
新增DLL的導出表 IMAGE_IMPORT_DESCRIPTOR
導出表結束標記,sizeof(IMAGE_IMPORT_DESCRIPTOR) 個0
INT表
INT表結束標記
IMPORT_BY_NAME 結構,包括Hint和導出函數名所占的字節數
IAT表
IAT表結束標記
模塊名

這些數據都寫入到內存中后,根據他們的地址,給其中某些結構的屬性賦值
導入表中的FirstThunk,OriginalFirstThunk分別存儲INT,IAT的RVA;
導入表的Name存儲模塊名的RVA;
INT,IAT的值是IMPORT_BY_NAME的RVA;

除此之外,完成了所有結構的屬性設置后,不要忘了修改數據目錄項,讓導入表指向新增節首字節。

二、注入代碼和運行結果

// 導入表注入demo,通過修改導入表,將 InjectDll.dll 添加到導入表 // DLL只有一個導出函數 ExportFunction,保證至少有一個導出函數DLL才會被加載 // DLL的主函數在加載和分離時會彈窗 DWORD ImportTableInjectDemo(LPVOID pFileBuffer, LPVOID *pNewFileBuffer, DWORD dwFileSize) {PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;PIMAGE_FILE_HEADER pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);PIMAGE_OPTIONAL_HEADER32 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));PIMAGE_SECTION_HEADER pSectionHeader = \(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);PIMAGE_IMPORT_DESCRIPTOR pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + \RvaToFoa(pFileBuffer, pOptionHeader->DataDirectory[1].VirtualAddress));// 計算新增節的大小// 新增節存儲的內容有:原來的所有導入表,新導入表,新INT, IAT, 模塊名,一個_IMAGE_IMPORT_BY_NAME// 上述容器按0為結束標記的,也要包含結束標記DWORD dwNewSectionSize = 0;DWORD dwNumberOfDll = 0;while (pImportTable->OriginalFirstThunk || pImportTable->FirstThunk){//printf("%s\n", (LPCSTR)(RvaToFoa(pFileBuffer, pImportTable->Name) + (DWORD)pFileBuffer));dwNumberOfDll++;pImportTable++;}dwNewSectionSize += (dwNumberOfDll + 2) * sizeof(IMAGE_IMPORT_DESCRIPTOR); // 原有的和新添加的導入表,以及結束標記dwNewSectionSize += 16; // 這里包括一個INT,一個IAT和兩個結束標記dwNewSectionSize += strlen("InjectDll.dll") + 1; // 模塊名dwNewSectionSize += 2 + strlen("ExportFunction") + 1; // _IMAGE_IMPORT_BY_NAME,包括Hint和函數名DWORD dwNewFileSize = AddCodeSection(pFileBuffer, pNewFileBuffer, dwFileSize, dwNewSectionSize);pDosHeader = (PIMAGE_DOS_HEADER)*pNewFileBuffer;pPEHeader = (PIMAGE_FILE_HEADER)(pDosHeader->e_lfanew + (DWORD)pDosHeader + 4);pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)*pNewFileBuffer + \RvaToFoa(*pNewFileBuffer, pOptionHeader->DataDirectory[1].VirtualAddress));// 設置新增節屬性pSectionHeader[pPEHeader->NumberOfSections - 1].Characteristics = 0xC0000040; // 可讀寫,含已初始化數據// 定義指針指向新增節首字節LPVOID pNewSec = (LPVOID)((DWORD)*pNewFileBuffer + pSectionHeader[pPEHeader->NumberOfSections - 1].PointerToRawData);LPVOID pInsert = pNewSec; // 復制原有的導入表memcpy(pInsert, pImportTable, dwNumberOfDll * sizeof(IMAGE_IMPORT_DESCRIPTOR)); // 設置新導入表的時間戳,ForwarderChainpImportTable = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pInsert + dwNumberOfDll * sizeof(IMAGE_IMPORT_DESCRIPTOR)); pImportTable->TimeDateStamp = 0; // 表示不使用綁定導入pImportTable->ForwarderChain = -1;// 設置導入表結束標記pInsert = (LPVOID)((DWORD)pImportTable + sizeof(IMAGE_IMPORT_DESCRIPTOR)); // 指向結束標記memset(pInsert, 0, sizeof(IMAGE_IMPORT_DESCRIPTOR));// 指定INT表插入點pInsert = (LPVOID)((DWORD)pInsert + sizeof(IMAGE_IMPORT_DESCRIPTOR)); // 現在指向INT表PIMAGE_THUNK_DATA pINT = (PIMAGE_THUNK_DATA)pInsert; // 定義指向INT表的指針// 設置INT結束標志memset(pINT + 1, 0, sizeof(IMAGE_THUNK_DATA));// 設置 IMPORT_BY_NAME,INT表和IAT表共同指向這塊內存PIMAGE_IMPORT_BY_NAME pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pINT + 8); // IMPORT_BY_NAME插入點pImportByName->Hint = 0; // 設置沒有用的導出序號strcpy((char*)(pImportByName->Name), "ExportFunction"); // 設置函數名// INT表的值是 IMPORT_BY_NAME 的RVA*((PDWORD)pINT) = FoaToRva(*pNewFileBuffer, (DWORD)pImportByName - (DWORD)*pNewFileBuffer); // 設置INT的值// 設置IAT表pInsert = (LPVOID)((DWORD)pImportByName + 2 + strlen("ExportFunction") + 1); // 指向IAT表 PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)pInsert; // IAT插入點memcpy(pIAT, pINT, 8);// 分配模塊名的內存,并完成導入表剩余屬性的賦值pInsert = (LPVOID)((DWORD)pInsert + 8); strcpy((char *)pInsert, "InjectDll.dll");// 設置導入表屬性pImportTable->FirstThunk = FoaToRva(*pNewFileBuffer, (DWORD)pINT - (DWORD)*pNewFileBuffer);pImportTable->OriginalFirstThunk = FoaToRva(*pNewFileBuffer, (DWORD)pIAT - (DWORD)*pNewFileBuffer);pImportTable->Name = FoaToRva(*pNewFileBuffer, (DWORD)pInsert - (DWORD)*pNewFileBuffer);// 更新目錄項中導入表的位置pOptionHeader->DataDirectory[1].VirtualAddress = FoaToRva(*pNewFileBuffer, ((DWORD)pNewSec - (DWORD)*pNewFileBuffer));return dwNewFileSize; }

給ipmsg注入dll,雙擊運行exe,先彈出對話框

然后才運行程序

程序退出時,再次彈出對話框

三、DLL的代碼

這是DLL的主函數,加載時彈一次窗,分離時也彈一次窗。

BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:Init();break;case DLL_PROCESS_DETACH:Destroy();break;}return TRUE; }

四、完整代碼

至此,PE模塊的課程已經結束,有很多PE的知識還沒涉及到,這些要在以后學習了相關知識后再了解。

PE所有課后作業的核心代碼都在這了!

https://blog.csdn.net/Kwansy/article/details/106234264

總結

以上是生活随笔為你收集整理的导入表注入原理和C语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。