每类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();