.idata数据的解析

本文详细探讨了PE文件中.idata段的解析过程,包括如何通过相对虚拟地址计算链接库名称在文件中的偏移,以及如何遍历并输出IMAGE_IMPORT_DESCRIPTOR等结构信息。通过示例代码展示了如何将解析细节存储到XML文件中,以便进一步分析。
摘要由CSDN通过智能技术生成

每类Section代表不同的数据,不同的数据存储组织方式一定是有非常大区别的。代码段与资源段一定区别巨大,这意味着我需要一个一个的学习每个段的解析。

 

idata段解析

这个段主要存储的是导入符号信息。昨天花了很多时间研究符号的获取,但就在刚刚开始就卡壳了,很多人都是说读取了IMAGE_IMPORT_DESCRIPTOR,就可以获取到链接库名称,但这个字段是一个地址,我根本不能理解这个地址如何对应到文件中的偏移,后来是今天才突然恍然大悟,原来那个是相对虚拟地址,而段头结构中还有一个相对虚拟地址,用来指示段数据被加载到内存后的相对虚拟地址,用段偏移+链接库名称相对虚拟地址-段头结构中的相对虚拟地址就是链接库名称在文件中的偏移。这个计算与基地址一丁点关系都没有,不明白很多文章在将这里的时候来时说基地址问题,有啥联系,白让我浪费脑细胞。

        关于地址转换问题想明白后,其余都是浮云,只要按照其它教程中提到的方法遍历就行,实在不行,看我写的代码就行了。

        另外这次代码做了改动,直接将所有知道的细节都输出到xml文件中,用于以后分析,是否将文件中的每个字节都真的明白了。是否还有很多数据游离于我们分析的结构外?

 

代码:

#include<iostream>

#include<Windows.h>

 

#include<sstream>

#include<string>

#include<vector>

#include <map>

 

 

FILE* fpOutput =NULL;

 

// 对文件数据信息分类

//主要目的是更加准确的确定每个数据的位置

struct Section

{

intm_iStart;

intm_iEnd;

std::stringm_strSectionName;

 

std::map<std::string,std::string>m_mapProperties;

 

std::vector<Section*>vecChild;

};

std::vector<Section*>g_vecSection;

 

void AddSection(intiOffset,int iLen,const char* pName)

{

Section*s = new Section;

s->m_iStart= iOffset;

s->m_iEnd   = iOffset + iLen;

s->m_strSectionName= pName;

 

g_vecSection.push_back(s);

}

void AddSection(intiOffset,int iLen,const char* pName,conststd::map<std::string,std::string>& mapProperties)

{

Section*s = new Section;

s->m_iStart= iOffset;

s->m_iEnd   = iOffset + iLen;

s->m_strSectionName= pName;

s->m_mapProperties  = mapProperties;

 

g_vecSection.push_back(s);

}

 

voidAddChild(std::vector<Section*>& vecChild,Section* pS)

{

for(size_ti=0; i<vecChild.size(); i++)

{

if(pS->m_iStart>=vecChild[i]->m_iStart&&

pS->m_iEnd<= vecChild[i]->m_iEnd)

{

returnAddChild(vecChild[i]->vecChild,pS);

}

}

 

vecChild.push_back(pS);

}

voidOutputInfo(std::vector<Section*>& vecS)

{

for(size_ti=0; i<vecS.size(); i++)

{

std::stringstreamstream;

stream<<"<SectionName=\""<<vecS[i]->m_strSectionName<<"\"Start=\""<<vecS[i]->m_iStart<<"\"End=\""<<vecS[i]->m_iEnd<<"\" ";

 

std::map<std::string,std::string>::iteratorit = vecS[i]->m_mapProperties.begin();

for(;it != vecS[i]->m_mapProperties.end(); it++)

{

stream<<it->first<<"=\""<<it->second<<"\"";

}

stream<<">"<<std::endl;

 

fprintf(fpOutput,"%s",stream.str().c_str());

OutputInfo(vecS[i]->vecChild);

 

std::stringstreamstream1;

stream1<<"</Section>"<<std::endl;

fprintf(fpOutput,"%s",stream1.str().c_str());

}

}

void OutputSection()

{

std::map<int,std::map<int,Section*>>mapS;

 

for(size_ti=0; i<g_vecSection.size(); i++)

mapS[g_vecSection[i]->m_iStart][g_vecSection[i]->m_iEnd]= g_vecSection[i];

 

Section*root = new Section;

root->m_iStart= -1;

root->m_iEnd   = 200000000;

 

std::map<int,std::map<int,Section*>>::iteratorit = mapS.begin();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值