目录
前言
本文章用于学习,如有错误还望指出。
上篇文章写了关于PE文件头(DOS头,标准PE头,可选PE头的解析),今天这篇文件是关于节表的解析。
首先介绍一下节表的每个成员:
typedef struct _IMAGE_SECTION_HEADER
{
0x00 BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//描述了此节区的名称,八个字节,这个名字是可以改的,如果你没有指定,编译器会生成固定的名字。
要注意的是:这一串是ASCII字符,需要以0结尾,编译器生成的名字长度如果小于8个字节还行,余下补0,但是如果正好8个字节,你在进行打印的时候就会越界了,在下面会写出处理办法。
union {
0x08 DWORD PhysicalAddress;
0x08 DWORD VirtualSize;
} Misc;//这个节表(有几个节,就有几个节表)指向的节真实的大小(没有经过对齐的)。
0x0c DWORD VirtualAddress; //当程序载入内存时,相对于ImageBase的偏移,指向节的第一个字节。
0x10 DWORD SizeOfRawData; //节进行文件对齐之后的长度。
0x14 DWORD PointerToRawData; //节在硬盘中,或者通过16位文本编辑器打开时,相对于起始地址的偏移,指向节的第一个字节。
0x18 DWORD PointerToRelocations;
0x1c DWORD PointerToLinenumbers;
0x20 WORD NumberOfRelocations;
0x22 WORD NumberOfLinenumbers;
0x24 DWORD Characteristics;//节的属性,例如:可读可写可执行。
};
过程
具体的实现过程:
这里是以Xshell 7版本做为测试的。
对于PE头部分的解析就不放出来了,在之前的文章里面有提及到,下面写的是关于节表解析
//首先根据节表的特征,使用数组记录
const BYTE* _IMAGE_SECTION_HEADER[10]
{
"Name[IMAGE_SIZEOF_SHORT_NAME]",
"Misc",
"VirtualAddress",
"SizeOfRawData",
"PointerToRawData",
"PointerToRelocations",
"PointerToLinenumbers",
"NumberOfRelocations",
"NumberOfLinenumbers",
"Characteristics"
};
//每一个成员的长度
int Section_LENGTH[10]
{
8,4,4,4,4,4,4,2,2,4
};
//节表
//节表的数量
/*
BufBackUp是文件读入内存的起始值,也就是0
Turn是dos头中最后一个成员,存着NT头的起始位置的偏移
+4,+2,是为了索引到标准PE头中的第二个成员:NumberOfSection,节的个数,后面循环的时候需 要用到
*/
WORD * P_Section_num = (WORD*)(BufBackUp + Turn + 4 + 2);
//定位节表
WORD* P_Size_Optioanal_Header = (WORD *)(BufBackUp + Turn + 0x4 + 0x10);
//让Buf指向第一个节表的开始位置,节表和节表之间是贴着的,而且长度相同,很好理解,因为节表就是描述节的概要性信息的嘛。
Buf = (BufBackUp + Turn + 0x4 + 20 + (*P_Size_Optioanal_Header));
i = 0;
DWORD j = 0;
//以节表的个数做为外层循环次数
while(j < (*P_Section_num))
{
//内存循环每个节表的成员,一共10个
while (i < 10)
{
printf("%s:", _IMAGE_SECTION_HEADER[i]);
if (Section_LENGTH[i] == 8)
{
int TempCount = 0;
BYTE TempArr[9] = {0};
//这个地方大家注意一下,我验证的时候通过strcpy_s复制,但是一直在报越界问题,我//验证觉的是因为strcpy_s是以源字符串直到0结尾做为源字符串的长度,不是根据第二个参数来的。
while (TempCount< 8 && (*(Buf + TempCount)) != 0)
{
TempArr[TempCount] = Buf[TempCount];
TempCount ++;
}
printf("%s\n", TempArr);
Buf += 8;
}
else if(Section_LENGTH[i] == 4)
{
DWORD* PTemp = (DWORD*)Buf;
printf("%x\n", (*PTemp));
Buf += 4;
}
else
{
WORD* PTemp = (WORD*)Buf;
printf("%x\n", (*PTemp));
Buf += 2;
}
i++;
}
printf("\n");
i = 0;
j++;
}
这是跑出来的结果: