资源枚举

写一个例子,枚举一个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资源表编程(枚举资源树)的更多相关文章

  1. WindowsPE 第七章 资源表

    资源表 在程序设计中,总会设计一些数据.这些数据可能是源代码内部需要用到的常量,菜单选项.界面描述等:也可能是源代码外部的,比如程序的图标文件.北京音乐文件.配置文件等,以上这些数据统称为资源.按照程 ...

  2. PE格式第九讲,资源表解析

    PE格式第九讲,资源表解析 一丶熟悉Windows管理文件的方法 首先,为什么标题是这个,主要是为了下边讲解资源方便,因为资源结构体很乱.如果直接拿出来讲解,那么就会很晕. 1.windows管理文件 ...

  3. [PE结构分析] 11.资源表结构

    资源表是一个树形结构,可以设置成2的31次方的层数,Windows 使用了3级: 类型->名称->语言 其中涉及到四个结构: Data Description Resource Direc ...

  4. Window黑客编程之资源释放技术

    前言 今天说一下写病毒木马会广泛使用的一种技术--资源释放技术.为什么我们在写木马时会使用到资源释放技术呢?这是因为它可以使我们写的程序变得简洁.如果程序需要额外加载一些DLL文件或者文本文件,我们可 ...

  5. iteye上总结的编程精华资源

    原文:http://www.iteye.com/magazines/130 博客是记录学习历程.分享经验的最佳平台,多年以来,各路技术大牛在ITeye网站上产生了大量优质的技术文章,并将系列文章集结成 ...

  6. 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例

    [源码下载] 背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例 作者:webabcd 介绍背水一战 Windows 10 之 资源 资源限定符概述 资源限定符示例 ...

  7. bundle绑定资源表

    1.注册绑定资源表 在application_Start函数中: (注意不要加拓展名,否则压缩时出问题) BundleTable.Bundles.Add(new ScriptBundle(" ...

  8. Windows Store App 全球化:引用分离资源文件中的资源

    大部分应用程序仅需要单个默认资源文件,例如Strings/zh-CN/Resources.resw,但是在某些应用程序中,最好将资源分离到多个资源文件中,以便更好地组织资源内容,这样就需要考虑如何引用 ...

  9. 第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表、课程章节表、课程视频表、课程资源表

    第三百七十四节,Django+Xadmin打造上线标准的在线教育平台—创建课程app,在models.py文件生成4张表,课程表.课程章节表.课程视频表.课程资源表 创建名称为app_courses的 ...

随机推荐

  1. .NET 6 Preview 2 发布

    前言 在 2021 年 3 月 11 日, .NET 6 Preview 2 发布,这次的改进主要涉及到 MAUI.新的基础库和运行时.JIT 改进. .NET 6 正式版将会在 2021 年 11 ...

  2. [THUPC2019] 找树

    一.题目 点此看题 二.解法 这道题很离谱啊,看上去是求一个最大值,其实是把生成树权值为 \(i\) 的个数都给算出来,因为权值很小. 既然是生成树可以考虑矩阵树定理,我们考虑他是求这样一个式子: \ ...

  3. webpack4.x 从零开始配置vue 项目(一)基础搭建项目

    序 现在依旧记得第一次看到webpack3.x 版本配置时候的状态  刚开始看到这些真的是一脸懵.希望这篇文章能帮到刚开始入门的同学. webpack 是什么? webpack是一个模块化打包工具,w ...

  4. API管理工具

    开源的api文档管理系统 api文档 php 在项目中,需要协同开发,所以会写许多API文档给其他同事,以前都是写一个简单的TXT文本或Word文档,口口相传,这种方式比较老土了,所以,需要有个api ...

  5. Centos7安装maven详情以及配置

    一.maven安装: 1.获取maven下载地址: 查询maven最新版本地址:https://maven.apache.org/download.cgi 当前最新版本为maven 3.6.3    ...

  6. Java单链表反转图文详解

    Java单链表反转图文详解 最近在回顾链表反转问题中,突然有一些新的发现和收获,特此整理一下,与大家分享 背景回顾 单链表的存储结构如图: 数据域存放数据元素,指针域存放后继结点地址 我们以一条 N1 ...

  7. TypeError: Can't convert 'int' object to str implicitly Python常见错误

    尝试连接非字符串值与字符串 想要字符串连接非字符串需要先进行强制转化 可以用str()函数 --------------------------------

  8. DDOS攻击与防御简单阐述,列出DDOS的攻击方法和防御方法

    参考1:https://www.hi-linux.com/posts/50873.html#%E7%BD%91%E7%BB%9C%E5%B1%82-ddos-%E6%94%BB%E5%87%BB 什么 ...

  9. PictureCleaner 官方版 v1.1.3.04061,免费的图片校正及漂白专业工具,专业去除文档图片黑底麻点杂色,规格化A4、B5尺寸输出,还你一个清晰的文本。

    当家长多年,每天都要拍照试卷打印.用App去掉图片黑底就成了每天必备工作.可是,有些图片文件不是来自手机,所以需要一个电脑版的图片漂白工具.经过一个多月努力,PictureCleaner官方版诞生了 ...

  10. js 一数组分割成若干个数组,并装换成字符串赋个li标签

    success: function (datas) { //请求成功后处理函数. var htmltext = ''; var data = datas.result; console.log(dat ...