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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows PE资源表编程(枚举资源树)

發布時間:2025/6/17 windows 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows PE资源表编程(枚举资源树) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

資源枚舉

? ? 寫一個例子,枚舉一個PE文件的資源表。首先說下資源相關的作為鋪墊。

1.資源類型也是PE可選頭中數據目錄的一種。位于第三個類型。


2.資源目錄分為三層。第四層是描述文件相關的。這些結構是按照二叉排序樹的結構存的。每一個節點都可以看成是一段連續的數據塊(1個資源目錄頭+n個資源目錄項)。


3.整體基本結構:


OK,基礎知識就簡單說這些。如果還是不清楚,看下這里http://blog.csdn.net/u013761036/article/details/54562473這里我單獨針對資源表寫的一個博客。


說下寫這個枚舉資源表結構的程序思路:

理解了PE里面怎么存資源的剩下的就很簡單了。

1.把PE加載到內存里。拿出來PE頭,找到擴展頭里面的第三個數據項。找到資源表RVA和大小。

2.根據RVA用函數換算出FOA的地址,這個地址指向的就是第一層目錄的目錄頭結構,根據這個目錄頭開始,緊跟在后面的就是n個以名稱命名的和m個以id命名的資源目錄項。

3.上面2可以把目錄頭看成節點,把目錄項看成連接到下一條節點的邊,這樣DFS或者BFS跑三層。依次枚舉經過的信息。在第三層的時候直接把文件相關的也都輸出來就可以了。

[:DFS-深度優先搜索,就是平時說的遞歸?BFS-廣度優先搜索,用隊列模擬的一個擴散感覺的遍歷]

剛剛寫了個例子,簡單跑了一遍沒發現啥問題:代碼如下:

注意兩個地方(這個我被坑了好一會):

1

? 結構里面涉及的下一個目錄項和指向資源塊的地址都是相對于資源表的起始位置而不是文件起始位置。

2

?指針加法問題

?XXXX?*?y;

?DWORD?z;

?Y地址后偏移z長度得到x地址

?XXXX?*?x?=?(XXXX?*)((DWORD)?y?+?DWORD(z))

// GET_RES.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <windows.h> #include <winbase.h> #include <stdio.h> #include <tchar.h> #include <imagehlp.h> #include <vector> #include <string> #include <iostream> #include <string> using namespace std; //CP_ACP string ws2s(const wstring& wide, UINT CodePage){int wide_length = static_cast<int>(wide.length());if (wide_length == 0)return string();int charcount = WideCharToMultiByte(CodePage, 0, wide.data(), wide_length,NULL, 0, NULL, NULL);if (charcount == 0)return string();string mb;mb.resize(charcount);WideCharToMultiByte(CodePage, 0, wide.data(), wide_length,&mb[0], charcount, NULL, NULL);return mb; }VOID ShowRes_DFS(DWORD dwDeep ,IMAGE_RESOURCE_DIRECTORY* pNowResourceDesc ,IMAGE_RESOURCE_DIRECTORY* pBaseResourceDesc){/*一級子目錄按照資源類型分類。二級子目錄按照資源ID分類。三級子目錄按照資源代碼頁分類。三級子目錄后即為節點,也就是所說的文件。這里的文件其實就是包含了資源數據的指針和大小等信息的一個數據結構而已。對于所有資源數據塊的訪問均可以從這里開始。*/dwDeep ++;IMAGE_RESOURCE_DIRECTORY_ENTRY *pResourceBaseAddress = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)((PBYTE) pNowResourceDesc + sizeof(IMAGE_RESOURCE_DIRECTORY)); for(int i = 0 ;i < pNowResourceDesc->NumberOfIdEntries + pNowResourceDesc->NumberOfNamedEntries ;i ++){IMAGE_RESOURCE_DIRECTORY_ENTRY *pNowResourceAddress = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)((DWORD)pResourceBaseAddress + i * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));for(int j = 1 ;j < (dwDeep-1) * 3 ;j ++){cout<<" ";}cout<<"Value: ";if(pNowResourceAddress->NameIsString){IMAGE_RESOURCE_DIR_STRING_U *wsName = (IMAGE_RESOURCE_DIR_STRING_U*)((DWORD)pNowResourceAddress->NameOffset + (DWORD)pBaseResourceDesc);wstring wsV = wstring(wsName->NameString ,wsName->Length);cout<<ws2s(wsV ,CP_ACP);}else{cout<<pNowResourceAddress->Id;}cout<<endl;if(pNowResourceAddress->DataIsDirectory){ShowRes_DFS(dwDeep ,(IMAGE_RESOURCE_DIRECTORY*)((DWORD)pNowResourceAddress->OffsetToDirectory + (DWORD)pBaseResourceDesc),pBaseResourceDesc);}else{for(int j = 1 ;j < (dwDeep) * 3 ;j ++){cout<<" ";}IMAGE_RESOURCE_DATA_ENTRY * pFileRes = (IMAGE_RESOURCE_DATA_ENTRY*)((DWORD)pNowResourceAddress->OffsetToDirectory + (DWORD)pBaseResourceDesc);cout<<"File: RVA-"<<pFileRes->OffsetToData;cout<<",Size-"<<pFileRes->Size;cout<<",Page-"<<pFileRes->CodePage;cout<<endl;}}return ; }typedef PVOID (CALLBACK* PFNEXPORTFUNC)(PIMAGE_NT_HEADERS,PVOID,ULONG,PIMAGE_SECTION_HEADER*);BOOL FindReso(const wstring &wsPeFilePath){HANDLE hFileHandle,hFileMapHandle;DWORD dwFileAttrib=0;void * pBaseAddress; hFileHandle=CreateFile(wsPeFilePath.c_str(),GENERIC_READ,0,0,OPEN_EXISTING,dwFileAttrib,0); if(hFileHandle == INVALID_HANDLE_VALUE){return FALSE;}hFileMapHandle=CreateFileMapping(hFileHandle,0,PAGE_READONLY,0,0,0); if(hFileMapHandle==NULL){ CloseHandle(hFileHandle); return FALSE; } pBaseAddress=MapViewOfFile(hFileMapHandle,FILE_MAP_READ,0,0,0); if (pBaseAddress==NULL) { CloseHandle(hFileMapHandle); CloseHandle(hFileHandle); return FALSE; } HMODULE hModule = ::LoadLibrary(L"DbgHelp.dll");if(!hModule){return FALSE;}PFNEXPORTFUNC ImageRvaToVax=(PFNEXPORTFUNC)GetProcAddress(hModule,"ImageRvaToVa");if(!ImageRvaToVax){FreeLibrary(hModule);return FALSE;}IMAGE_DOS_HEADER * pDosHeader = (IMAGE_DOS_HEADER*)pBaseAddress; IMAGE_NT_HEADERS * pNtHeader = (IMAGE_NT_HEADERS *)((BYTE*)pBaseAddress+ pDosHeader->e_lfanew);IMAGE_OPTIONAL_HEADER * pOptHeader = (IMAGE_OPTIONAL_HEADER *)((BYTE*)pBaseAddress + pDosHeader->e_lfanew + 24);IMAGE_RESOURCE_DIRECTORY* pResourceDesc = (IMAGE_RESOURCE_DIRECTORY*)ImageRvaToVax(pNtHeader,pBaseAddress,pOptHeader->DataDirectory[2].VirtualAddress,0); if(pResourceDesc->NumberOfIdEntries + pResourceDesc->NumberOfNamedEntries == 0){return TRUE;}ShowRes_DFS(0 ,pResourceDesc ,pResourceDesc);FreeLibrary(hModule);CloseHandle(hFileMapHandle); CloseHandle(hFileHandle); return TRUE; } int _tmain(int argc, _TCHAR* argv[]) {WCHAR wcLocalFilePath[MAX_PATH] = {0};GetModuleFileName(0 ,wcLocalFilePath ,MAX_PATH);FindReso(wcLocalFilePath);return 0; }


總結

以上是生活随笔為你收集整理的Windows PE资源表编程(枚举资源树)的全部內容,希望文章能夠幫你解決所遇到的問題。

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