吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 15541|回复: 25
收起左侧

[系统底层] 读取PE结构中的数据目录项

[复制链接]
X86ZJY 发表于 2018-8-19 13:12
中断了一段时间PE的学习,从昨天开始捡起来,研究了一下NT头里边的optionalheader的数据目录项,里边存放着很多重要的表的数据,想要解析那些表,就必须要能够解析这个数组。

typedef struct _IMAGE_DATA_DIRECTORY {        DWORD VirtualAddress; //相对虚拟地址    DWORD Size;      //大小 } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
这是vs里边给出的定义,数据目录在winnt.h中的定义为
[C++] 纯文本查看 复制代码
#define IMAGE_DIRECTORY_ENTRY_EXPORT        0 导出表
#define IMAGE_DIRECTORY_ENTRY_IMPORT        1 导入表 
#define IMAGE_DIRECTORY_ENTRY_RESOURCE      2 资源目录
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION         3 异常目录
#define IMAGE_DIRECTORY_ENTRY_SECURITY      4 安全目录
#define IMAGE_DIRECTORY_ENTRY_BASERELOC             5 重定位基本表
#define IMAGE_DIRECTORY_ENTRY_DEBUG         6 调试目录
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT         7 描术字串
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR         8 机器值
#define IMAGE_DIRECTORY_ENTRY_TLS       9 TLS目录
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG   10 载入配值目录
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT       11 绑定输入表
#define IMAGE_DIRECTORY_ENTRY_IAT       12 导入地址表
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT  13 延迟载入描述
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR     14 COM信息

这是15个基本表,其实一共有16个但是第十六个保留不适用所以没有写,想要用代码找必须要会手动查找。这里我是用的软件是windows自带的notepad  工具为UltraEdit

通过查询PE文件结构可以知道,数据目录项在节表上方,16项每项的大小为8个字节,所以从节表开始出向上找8行。
(但是这个地方我有点不理解为什么是virtualaddress在前,size在后边,看定义的时候位置是相反的。)
手动找到完成之后开始使用代码写,大体步骤为:
1、将文件读到缓冲区。
2、定义每个pe头的信息。
3、定义数据目录项指针将指针指向数据目录项、
4、打印信息。代码为:
[C++] 纯文本查看 复制代码
        
VOID DirectoryPrintf()
{
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL;
    PIMAGE_DATA_DIRECTORY pDirectory = NULL;
 
    BYTE Length = 8;  //本来是想通过加上长度来移动指针,发现不可以 这个地方忽略
 
    LPVOID pFileBuffer = NULL;
    ReadPEFile(INFILEPATH, &pFileBuffer);
 
    //判断读取文件是否成功
    if (!pFileBuffer){
        printf("读取文件失败");
        free(pFileBuffer);
        return;
    }
 
    //如果读取成功进行操作
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew);
    pFileHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER);
    pDirectory = (PIMAGE_DATA_DIRECTORY)(((DWORD)pOptionalHeader) + 96);
 
    //输出各种表的信息~
    printf("导出表:size: %x virtualaddress: %x\n",pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("导入表:SIZE:%x  virtualaddress:%x\n", pDirectory->Size,pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("资源目录:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("异常目录:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("安全目录:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("重定位基本表:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("调试目录:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("描述字串:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("机器值:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("TLS目录:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("载入配值目录:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("绑定输入表:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("导入地址表:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("延迟载入描述:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("COM信息:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    pDirectory++;
    printf("未使用的表:Size %x  VirtualAddress: %x\n", pDirectory->Size, pDirectory->VirtualAddress);
    printf("=====================================\n");
 
    free(pFileBuffer);
     
}
运行结果为:

跟上边UE查询的数据对应。好了,数据目录项已经读取完成,明天更新下导出表的一些操作代码算是给自己的flag毕竟学生嘛,惰性还是太严重。

点评

楼楼,你的图片上面显示防盗链~~ 组委会一张没看到~~  发表于 2018-8-27 07:26

免费评分

参与人数 2吾爱币 +6 收起 理由
愛你壹萬年 + 1 我很赞同!
L4Nce + 5 楼主 图挂了 处理下

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| X86ZJY 发表于 2018-8-20 15:06
无痕软件 发表于 2018-8-20 15:01
BYTE Length = 8;  //本来是想通过加上长度来移动指针,发现不可以 这个地方忽略

是可以的。前提你了解  ...

他的结构不是一个结构体么,两个DWORD  不就是8Byte么?为啥直接加8不行呢?
愛你壹萬年 发表于 2018-8-26 12:57
X86ZJY 发表于 2018-8-20 15:06
他的结构不是一个结构体么,两个DWORD  不就是8Byte么?为啥直接加8不行呢?

pDirectory +8 跟 pDirectory+1 不一样的 pDirectory的宽度是它结构体的宽度 得是地址+8 我是这样理解的 说的可能不对
hbkccccc 发表于 2018-8-20 00:00
头像被屏蔽
sstm 发表于 2018-8-20 08:32
提示: 作者被禁止或删除 内容自动屏蔽
hydswcxx 发表于 2018-8-20 10:12
这个学习中..
谢谢分享!
liuhaitao52PJ 发表于 2018-8-20 10:44
小白学习下,谢谢分享!
无痕软件 发表于 2018-8-20 15:01
BYTE Length = 8;  //本来是想通过加上长度来移动指针,发现不可以 这个地方忽略

是可以的。前提你了解 这个指针++ 移动多少byte。。。
无痕软件 发表于 2018-8-20 16:13
X86ZJY 发表于 2018-8-20 15:06
他的结构不是一个结构体么,两个DWORD  不就是8Byte么?为啥直接加8不行呢?

指针(已具名)+ 1 跳过的是 该指针指向对象的长度。。。。。。。。。。。。。
jiu812yan 发表于 2018-8-20 23:25
谢谢楼主
changyanmanman 发表于 2018-8-21 19:02
感谢楼主,学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-19 21:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表