模拟PE文件加载到内存过程
模拟加载过程,就是用代码把这个过程实现一遍。
主要是把下面3个函数实现以下。
DWORD ReaDiskdFileToFileBuffer(void* DiskFilePath,void** FileBuffer)
DWORD CopyFileBufferToImageBuffer(void* FileBuffer,void** ImageBuffer)
DWORD CopyImageBufferToNewFileBuffer(LPVOID pImageBuffer,LPVOID* pNewBuffer)

DWORD ReaDiskdFileToFileBuffer(void* DiskFilePath,void** FileBuffer){FILE* OpenFile = fopen((char*)DiskFilePath,"rb");if(OpenFile == NULL){printf("打开文件失败\n");return -1;}else{printf("打开文件成功\n");}
fseek(OpenFile,0,SEEK_END);
long pos = ftell(OpenFile);
printf("文件大小为%d字节\n",pos);
fseek(OpenFile,0,SEEK_SET);
void* pFileBUffer = (void*)malloc(sizeof(char)*pos);printf("%x\n",pFileBUffer);//分配一块内存空间//pFileBuffer = &pFileBUffer;//这种方式写法有问题,导致指针传递
*FileBuffer = pFileBUffer;
printf("%x\n",*FileBuffer);
if(pFileBUffer==NULL){printf("分配内存失败\n");return 0;}else{printf("分配内存成功\n");memset(*FileBuffer,0,pos);}
fread(pFileBUffer,pos,1,OpenFile);printf("%02x\n",*((char*)pFileBUffer));pFileBUffer = NULL;fclose(OpenFile);
return pos;
}//void** lpFileBuffer=&FileBufferDWORD AddFileBufferNewSection(LPVOID* lpFileBuffer){
//void* lpNewFileBuffer = malloc(LastSectionHeader->PointerToRawData+LastSectionHeader->SizeOfRawData+AddSpecSize);//0、因为要增加节,先把lpFileBuffer原指向的空间扩大,扩大的大小为希望新增节的大小。//1、先判断空间是否足够,SizeofHeaders - 60(DOS头) - Dos Stub(根据elfnew) - 24(NT头大小) - SizeofOptionHeader - NunmberOfSection*40 >=80(至少2个节表的空间) //2、添加一个节表,可以直接复制一个原来的到New的位置,然后再逐个修改,节表中的名字、内存对齐大小、内存VA、磁盘中对齐大小,相对位置、节的属性等。//3、修改NumberOfSection,SizeofImage//char* lpFileBuffer1 = FileBuffer;原内存char* lpFileBuffer1=(char*)(*lpFileBuffer);
unsigned int* NT_offset =(unsigned int* )(lpFileBuffer1 + 60);NT_header* lp_NT_header =(NT_header*)(lpFileBuffer1 + *NT_offset);Image_OPtional_header* lp_Optional_header =(Image_OPtional_header*)(lpFileBuffer1 + *NT_offset + 24);int AllHeadSize= *NT_offset + 24 + lp_NT_header->OptionHeaderSize +lp_NT_header->NumberOfSection*40;int RemainSpec=lp_Optional_header->SizeOfHeaders -AllHeadSize;Image_Section_header* NewSectionHeader= (Image_Section_header*)(lpFileBuffer1+AllHeadSize);Image_Section_header* LastSectionHeader = (Image_Section_header*)(lpFileBuffer1+AllHeadSize-40);//2、节表中的相应值修改if(RemainSpec>=80){printf("文件所有头后边有充足的空间,需要继续判断是否有连续的80个0空间存在!\n");//复制一个原来的节表到新增的节表内容memcpy(lpFileBuffer1+AllHeadSize,lpFileBuffer1+AllHeadSize-40,40);//NewSectionHeader->Name[8]={'.','t','t','t','t',0,0,0};memset(NewSectionHeader->Name,0,8);strcpy(NewSectionHeader->Name,".tttt");NewSectionHeader->Misc.VirtualSize = 0x00001000;NewSectionHeader->VirtualAddress=lp_Optional_header->SizeOfImage;//一种是SizeOfImage,另一种是最后一个节的内存偏移+maxsize(Misc,RawOfData)NewSectionHeader->SizeOfRawData =0x00001000;NewSectionHeader->PointerToRawData=LastSectionHeader->PointerToRawData+LastSectionHeader->SizeOfRawData;NewSectionHeader->Characteristics=0x20000060;
}else{printf("空间不够,需要占用Dos Stub部分或者扩大最后一个节区!\n");
if(*NT_offset - 60>=80)printf("Dos Stub空间足够,可以把头部向上平移!\n");elseprintf("Dos Stub空间不够,准备扩大最后一个节区!\n");
}//3、修改NumberOfSection,SizeofImagelp_NT_header->NumberOfSection = lp_NT_header->NumberOfSection+1;lp_Optional_header->SizeOfImage =lp_Optional_header->SizeOfImage + AddSpecSize;//0、先0x1000扩大空间void* lpNewFileBuffer = malloc(LastSectionHeader->PointerToRawData+LastSectionHeader->SizeOfRawData+AddSpecSize);memset(lpNewFileBuffer,0,LastSectionHeader->PointerToRawData+LastSectionHeader->SizeOfRawData+AddSpecSize);printf("lpNewFileBuffer:%x\n",lpNewFileBuffer);
//1、把原来的内容原封不动的复制到这个大空间中。memcpy(lpNewFileBuffer,lpFileBuffer1,LastSectionHeader->PointerToRawData+LastSectionHeader->SizeOfRawData);//lpFileBuffer1 = (char*)lpNewFileBuffer;这句也是指针复制*lpFileBuffer = lpNewFileBuffer;//free(lpNewFileBuffer);printf("*lpFileBuffer:%x\n",*lpFileBuffer);return 0;}DWORD AddImageBufferNewSection(LPVOID* lpImageBuffer){//1、先判断空间是否足够,SizeofHeaders - 60(DOS头) - Dos Stub(根据elfnew) - 24(NT头大小) - SizeofOptionHeader - NunmberOfSection*40 >=80(至少2个节表的空间) //2、添加一个节表,可以直接复制一个原来的到New的位置,然后再逐个修改,节表中的名字、内存对齐大小、内存VA、磁盘中对齐大小,相对位置、节的属性等。//3、修改NumberOfSection,SizeofImagechar* lpFileBuffer1=(char*)(*lpImageBuffer);
unsigned int* NT_offset =(unsigned int* )(lpFileBuffer1 + 60);NT_header* lp_NT_header =(NT_header*)(lpFileBuffer1 + *NT_offset);Image_OPtional_header* lp_Optional_header =(Image_OPtional_header*)(lpFileBuffer1 + *NT_offset + 24);int AllHeadSize= *NT_offset + 24 + lp_NT_header->OptionHeaderSize +lp_NT_header->NumberOfSection*40;int RemainSpec=lp_Optional_header->SizeOfHeaders -AllHeadSize;Image_Section_header* NewSectionHeader= (Image_Section_header*)(lpFileBuffer1+AllHeadSize);Image_Section_header* LastSectionHeader = (Image_Section_header*)(lpFileBuffer1+AllHeadSize-40);//2、节表中的相应值修改if(RemainSpec>=80){printf("文件所有头后边有充足的空间,需要继续判断是否有连续的80个0空间存在!\n");//复制一个原来的节表到新增的节表内容memcpy(lpFileBuffer1+AllHeadSize,lpFileBuffer1+AllHeadSize-40,40);//NewSectionHeader->Name[8]={'.','t','t','t','t',0,0,0};memset(NewSectionHeader->Name,0,8);strcpy(NewSectionHeader->Name,".tttt");NewSectionHeader->Misc.VirtualSize = 0x00001000;NewSectionHeader->VirtualAddress=lp_Optional_header->SizeOfImage;//一种是SizeOfImage,另一种是最后一个节的内存偏移+maxsize(Misc,RawOfData)NewSectionHeader->SizeOfRawData =0x00001000;NewSectionHeader->PointerToRawData=LastSectionHeader->PointerToRawData+LastSectionHeader->SizeOfRawData;NewSectionHeader->Characteristics=0x20000060;
}else{printf("空间不够,需要占用Dos Stub部分或者扩大最后一个节区!\n");
if(*NT_offset - 60>=80)printf("Dos Stub空间足够,可以把头部向上平移!\n");elseprintf("Dos Stub空间不够,准备扩大最后一个节区!\n");
}//3、修改NumberOfSection,SizeofImagelp_NT_header->NumberOfSection = lp_NT_header->NumberOfSection+1;lp_Optional_header->SizeOfImage =lp_Optional_header->SizeOfImage + AddSpecSize;//0、用SizeOfImage扩大0x1000空间void* lpNewFileBuffer = malloc(lp_Optional_header->SizeOfImage);//printf("lpNewFileBuffer:%x\n",lpNewFileBuffer);
//1、把原来的内容原封不动的复制到这个大空间中。memset(lpNewFileBuffer,0,lp_Optional_header->SizeOfImage);memcpy(lpNewFileBuffer,lpFileBuffer1,lp_Optional_header->SizeOfImage-AddSpecSize);
//lpFileBuffer1 = (char*)lpNewFileBuffer;这句也是指针复制*lpImageBuffer = lpNewFileBuffer;//free(lpNewFileBuffer);//printf("*lpFileBuffer:%x\n",*lpFileBuffer);return 0;}DWORD CopyFileBufferToImageBuffer(void* FileBuffer,void** ImageBuffer){//AddFileBufferNewSection(&FileBuffer);unsigned int* NToffset =(unsigned int*)((char*)FileBuffer + 60);
NT_header* lpNt_header =(NT_header*)((char*)FileBuffer + *NToffset);
Image_Section_header* lp_Section=(Image_Section_header*)((char*)FileBuffer + *NToffset + 24 + lpNt_header->OptionHeaderSize);Image_OPtional_header* lp_Option_header = (Image_OPtional_header*)((char*)FileBuffer + *NToffset + 24);
//AddFileBufferNewSection(FileBuffer);printf("%02x\n",*(char*)FileBuffer);printf("lp_Option_header->SizeOfImage:%x\n",lp_Option_header->SizeOfImage);*ImageBuffer = malloc(lp_Option_header->SizeOfImage);if(*ImageBuffer == 0){printf("创建ImageBuffer的时候,分配内存失败");return 0;}else{printf("创建ImageBuffe成功!\n");}memset(*ImageBuffer,0,lp_Option_header->SizeOfImage);memcpy(*ImageBuffer,FileBuffer,lp_Option_header->SizeOfHeaders);lp_Option_header->DllCharacteristics =0x0081;
for(int i=0;i < lpNt_header->NumberOfSection;i++){memcpy((char*)(*ImageBuffer) +(lp_Section+i)->VirtualAddress ,(char*)FileBuffer+(lp_Section+i)->PointerToRawData,minSize((lp_Section+i)->SizeOfRawData,(lp_Section+i)->Misc.VirtualSize));//memcpy((char*)(*ImageBuffer) +(lp_Section+i)->VirtualAddress ,(char*)FileBuffer+(lp_Section+i)->PointerToRawData,(lp_Section+i)->SizeOfRawData);}return lp_Option_header->SizeOfImage;}DWORD CopyImageBufferToNewFileBuffer(LPVOID pImageBuffer,LPVOID* pNewBuffer){AddImageBufferNewSection(&pImageBuffer);
unsigned int* NToffset =(unsigned int*)((char*)pImageBuffer + 60);
NT_header* lpNt_header =(NT_header*)((char*)pImageBuffer + *NToffset);
Image_Section_header* lp_Section=(Image_Section_header*)((char*)pImageBuffer + *NToffset + 24 + lpNt_header->OptionHeaderSize);Image_OPtional_header* lp_Option_header = (Image_OPtional_header*)((char*)pImageBuffer + *NToffset + 24);
Image_Section_header* lp_LastSection = lp_Section + (lpNt_header->NumberOfSection-1);
*pNewBuffer = malloc(lp_LastSection->PointerToRawData + lp_LastSection->SizeOfRawData);if(*pNewBuffer ==0){printf("分配新的NewBuffer失败!\n");return 0;}else{printf("分配新的NewBuffer成功!准备从ImageBuffer到NewFileBuffer\n");memset(*pNewBuffer,0,lp_LastSection->PointerToRawData + lp_LastSection->SizeOfRawData);memcpy(*pNewBuffer,pImageBuffer,lp_Option_header->SizeOfHeaders);}
for(int j=0;j<lpNt_header->NumberOfSection;j++){memcpy((char*)(*pNewBuffer)+(lp_Section+j)->PointerToRawData,(char*)pImageBuffer+(lp_Section+j)->VirtualAddress,minSize((lp_Section+j)->Misc.VirtualSize,(lp_Section+j)->SizeOfRawData));}
FILE *fp;fp = fopen(Save_File , "w+b" );fwrite(*pNewBuffer, lp_LastSection->PointerToRawData + lp_LastSection->SizeOfRawData,1, fp );printf("存盘成功\n");fclose(fp);
return lp_LastSection->PointerToRawData + lp_LastSection->SizeOfRawData;
}

浙公网安备 33010602011771号