pe格式从入门到图形化显示(六)-数据目录

本文详细介绍了WindowsPE文件格式中的数据目录结构,包括导出目录、导入目录等16种目录的作用,并展示了如何使用Qt工具解析数据目录并以图形化方式显示,以便于理解和分析PE文件的内容。
摘要由CSDN通过智能技术生成


前言

通过分析和解析Windows PE格式,并使用qt进行图形化显示


一、什么是Windows PE格式中的数据目录?

PE(Portable Executable)文件格式中的数据目录是一个表,它提供了关于PE文件中各种数据结构和资源的位置信息。数据目录位于PE文件头的可选头(Optional Header)部分,紧跟在标准PE头之后。
PE文件格式中的数据目录总共有16个
1、导出目录(Export Directory):包含有关从PE文件导出的函数和数据的信息。
2、导入目录(Import Directory):包含有关PE文件依赖的其他模块和函数库的信息。
3、资源目录(Resource Directory):包含有关PE文件中嵌入的资源(如图标、字符串、位图等)的信息。
4、异常目录(Exception Directory):包含有关PE文件中定义的异常处理信息。
5、安全目录(Security Directory):包含有关PE文件的安全证书和权限集的信息。
6、重定位目录(Relocation Directory):包含有关PE文件可能需要进行的重定位操作的信息。
7、调试目录(Debug Directory):包含有关PE文件的调试信息。
8、版权目录(Architecture Directory):包含有关PE文件特定于处理器体系结构的信息。
9、全局指针目录(Global Ptr Directory):包含有关PE文件使用的全局指针的信息。
10、TLS目录(TLS Directory):包含有关PE文件使用的线程局部存储(Thread Local Storage)的信息。
11、负载配置目录(Load Configuration Directory):包含有关PE文件的安全性和稳定性配置的信息。
12、绑定导入目录(Bound Import Directory):包含有关PE文件绑定的导入信息。
13、IAT目录(Import Address Table Directory):包含有关PE文件中导入函数的地址表的信息。
14、延迟加载导入目录(Delay Import Directory):包含有关PE文件中延迟加载的导入信息。
15、COM表(COM Descriptor Directory):包含有关PE文件作为COM组件的信息。
16、预留类型表(Reserved):一个预留的条目,通常未使用。

二、解析数据目录并显示

1.数据目录结构体

数据目录表由一个或多个目录条目组成,每个条目描述了一个特定的数据结构或资源的位置。每个目录条目包含以下两个字段:
VirtualAddress(虚拟地址):该字段给出了数据结构或资源在PE文件虚拟地址空间中的起始地址。这个地址是一个RVA(相对虚拟地址)。
Size(大小):该字段给出了数据结构或资源的字节大小。

struct IMAGE_DATA_DIRECTORY
{
    DWORD VirtualAddress;
    DWORD Size;
};

2.解析数据目录表

bool PEParser::parserFileData(const QByteArray &fileData)
{
    //判断是否是MZ开头的文件
    if (fileData.left(2) != "MZ")
    {
        return false;
    }
    //解析DOS头
    parserDOSHeader(fileData.left(sizeof(IMAGE_DOS_HEADER)));
    //DOSStub数据
    m_dosStubData = fileData.mid(sizeof(IMAGE_DOS_HEADER), m_dosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER));
    long peAddress = m_dosHeader.e_lfanew;
    if (fileData.mid(peAddress, 2) != "PE")
    {
        return false;
    }
    m_fileData = fileData;
    //去除前4个字节的PE头标识
    long fileHeaderIndex = peAddress + 4;
    //记录文件头索引
    m_fileHeaderIndex = fileHeaderIndex;
    //解析标准PE文件头
    paserFileHeader(fileData.mid(fileHeaderIndex, sizeof(IMAGE_FILE_HEADER)));
    //解析扩展PE文件头
    long optionHeaderIndex = fileHeaderIndex + sizeof(IMAGE_FILE_HEADER);
    //记录扩展PE文件头索引
    m_optionHeaderIndex = optionHeaderIndex;
    //解析扩展PE文件头
    parserOptionHeader(fileData.mid(optionHeaderIndex, m_fileHeader.SizeOfOptionalHeader));
    //解析节表
    long sectionHeaderIndex = optionHeaderIndex + m_fileHeader.SizeOfOptionalHeader;
    //节表结构在文件中开始的偏移
    m_sectionHeaderIndex = sectionHeaderIndex;
    //解析节表
    parserSectionHeader(fileData.mid(sectionHeaderIndex,
                                     m_fileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER)));
    //解析数据目录
    parserDataDirectory();
    return true;
}

void PEParser::parserDataDirectory()
{
    m_directories.clear();
    if (m_x86Flag)
    {
        for (int i = 0; i < m_optionalHeader32.NumberOfRvaAndSizes; ++i)
        {
            m_directories.append(m_optionalHeader32.DataDirectory[i]);
        }
    }
    else
    {
        for (int i = 0; i < m_optionalHeader64.NumberOfRvaAndSizes; ++i)
        {
            m_directories.append(m_optionalHeader64.DataDirectory[i]);
        }
    }
    emit sendDataDirectory(m_directories);
}

3.显示数据目录表

void MainWindow::showDataDirectory(const QList<IMAGE_DATA_DIRECTORY> &directories)
{
    QStringList directoryName;
    directoryName << "导出表" << "导入表" << "资源表" << "异常表"
                  << "安全表" << "重定位表" << "调试表" << "版权表"
                  << "全局指针表" << "TLS表" << "加载配置表" << "绑定导入表"
                  << "IAT表" << "延迟导入表" << "COM表" << "预留类型表";
    ui->tableWidget_dataDirectories->clearContents();
    ui->tableWidget_dataDirectories->setRowCount(0);
    for (int i = 0; i < directories.size(); ++i)
    {
        ui->tableWidget_dataDirectories->insertRow(i);
        ui->tableWidget_dataDirectories->setItem(i, 0, new QTableWidgetItem(directoryName[i]));
        ui->tableWidget_dataDirectories->setItem(i, 1, new QTableWidgetItem(QString::asprintf("%08lX", directories[i].VirtualAddress)));
        ui->tableWidget_dataDirectories->setItem(i, 2, new QTableWidgetItem(QString::asprintf("%08lX", directories[i].Size)));
        ui->tableWidget_dataDirectories->setItem(i, 3, new QTableWidgetItem(m_peParser.RVA2FOA(directories[i].VirtualAddress).sectionName));
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mrack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值