佚名通过本文主要向大家介绍了pe文件,pe文件结构,pe核心文件未加载成功,pe文件不正确,pe文件格式等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: PE 文件的问题
描述:
代码也有很详细的注释,但是 从 +++++ 之间的我就看不懂了,
新增加的一个节。
不管是在加载到内存中还是说文件本身中的
我对齐的方式 肯定是 和我 添加的节的自身有关系啊
怎么会和上面的一个节(添加之前的最后一个节)有关系的,
我是真的想不通。
请帮我解答下
谢谢了
解决方案1:
计算新增节实际占磁盘多少空间
比如要新增的代码长度为513字节,那么实际在磁盘中应该占1024字节,因为在PE文件中,节通常是按0x200也就是512对齐的,注意FILE_ALIGN_MENT的定义 解决方案3:
描述:
唉....
找了半天也不知道,这个问题该发在什么地方去。就随便找一个地方发了吧。希望能有高人看到
问题是这样的 我最近在看pe的东西,然后在csdn上下载了一个朋友的源码,拿来研究,但是其中有个地方,我想了好就都没有想明白,到底是为什么啊为什么啊...
上代码
int Align(int size,int ALIGN_BASE)
{
int ret;
int result;
assert(0!=ALIGN_BASE);
result=size%ALIGN_BASE;
if (0!=result) //余数不为零,也就是没有整除
{
ret=((size/ALIGN_BASE)+1)*ALIGN_BASE;
}
else
{
ret=size;
}
return ret;
}
int main(int argc,char*argv[])
{
IMAGE_DOS_HEADER DosHeader;
IMAGE_NT_HEADERS NtHeader;
IMAGE_SECTION_HEADER SectionHeader;
IMAGE_SECTION_HEADER newSectionHeader;
int numOfSections;
FILE* pNewFile;
int FILE_ALIGN_MENT;
int SECTION_ALIGN_MENT;
char srcFileName[FILE_NAME_LENGTH];
char newFileName[FILE_NAME_LENGTH];
int i;
int extraLengthAfterAlign;
unsigned int newEP;
unsigned int oldEP;
BYTE jmp;
char* pExtra_data;
int extra_data_real_length;
strcpy(newFileName,"C:\\HelloWorld.exe");
pNewFile=fopen(newFileName,"rb+");
if (NULL==pNewFile)
{
puts("Open File failed\n");
exit(0);
}
fseek(pNewFile,0,SEEK_SET);
fread(&DosHeader,sizeof(IMAGE_DOS_HEADER),1,pNewFile);
if(DosHeader.e_magic!=IMAGE_DOS_SIGNATURE)
{
puts("not a valid PE file\n");
exit(0);
}
fseek(pNewFile,DosHeader.e_lfanew,SEEK_SET);
fread(&NtHeader,sizeof(IMAGE_NT_HEADERS),1,pNewFile);
if(NtHeader.Signature!=IMAGE_NT_SIGNATURE)
{
puts("Not a valid PE file\n");
exit(0);
}
//到这里,该文件就算是被验明正身的 合法的pe文件了
numOfSecti //文件的节数目
FILE_ALIGN_MENT=NtHeader.OptionalHeader.FileAlignment; //文件的对齐粒度
SECTI //内存中节的对齐粒度
#if DEBUG
printf("NumberOfSections->%d\n",numOfSections);
printf("FILE_ALIGN_MENT->%x\n",FILE_ALIGN_MENT);
printf("SECTION_ALIGN_MENT->%x\n",FILE_ALIGN_MENT);
#endif
oldEP=NtHeader.OptionalHeader.AddressOfEntryPoint; //文件执行入口地址
#if DEBUG
printf("oldEP->%x\n",oldEP);
#endif
//定位到最后一个sectionHeader
for (int i=0;i<numOfSections;i++)
{
fread(&SectionHeader,sizeof(IMAGE_SECTION_HEADER),1,pNewFile);
#if DEBUG
printf("节的名字:%s\n",SectionHeader.Name);
#endif
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//增加一个新节前的准备工作
extraLengthAfterAlign=Align(EXTRA_CODE_LENGTH,FILE_ALIGN_MENT);
#if DEBUG
printf("extraLengthAfterAlign->%x\n",extraLengthAfterAlign);
#endif
NtHeader.FileHeader.NumberOfSections++;
//先清零
memset(&newSectionHeader,0,sizeof(IMAGE_SECTION_HEADER));
//修改部分数据
strncpy((char*)newSectionHeader.Name,SECTION_NAME,strlen(SECTION_NAME));
//修正VirtualAddress and VirtualSzie 通过SECTION_ALIGN_MENT
//修正VirtualAddresss
newSectionHeader.VirtualAddress=Align(SectionHeader.VirtualAddress+SectionHeader.Misc.VirtualSize,SECTION_ALIGN_MENT);
//修正VirtualSize
newSectionHeader.Misc.VirtualSize=Align(extraLengthAfterAlign,SECTION_ALIGN_MENT);
//修正PointerToRawData
newSectionHeader.PointerToRawData=Align(SectionHeader.PointerToRawData+SectionHeader.SizeOfRawData,FILE_ALIGN_MENT);
//修正sizeofRawData
newSectionHeader.SizeOfRawData=Align(SECTION_SIZE,FILE_ALIGN_MENT);
//修正新节的属性
newSectionHeader.Characteristics=0xE0000020; //可读可写可执行
#if DEBUG
printf("\nSizeofCode:%x\n",NtHeader.OptionalHeader.SizeOfCode);
printf("\nSizeofImage:%x\n",NtHeader.OptionalHeader.SizeOfImage);
#endif
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
system("pause");
return 0;
}
代码也有很详细的注释,但是 从 +++++ 之间的我就看不懂了,
新增加的一个节。
不管是在加载到内存中还是说文件本身中的
我对齐的方式 肯定是 和我 添加的节的自身有关系啊
怎么会和上面的一个节(添加之前的最后一个节)有关系的,
我是真的想不通。
请帮我解答下
谢谢了
解决方案1:
文件按照对齐粒度对齐后所要占用的空间
解决方案2:计算新增节实际占磁盘多少空间
比如要新增的代码长度为513字节,那么实际在磁盘中应该占1024字节,因为在PE文件中,节通常是按0x200也就是512对齐的,注意FILE_ALIGN_MENT的定义 解决方案3:
因为你添加的那个节需要文件偏移在那个节的文件对齐后那里?
例如最后一个节实际大小只有2个字节,但是对齐是4个字节。那你就应该在第5个字节偏移开始添加新节,而不是在第三个。前面那些地方就填充0,这也是常说的节对齐空隙
有点忘记了,也不知道是不是这样
职业帮顶,bs给分