前言:
眼前同学们对“文件解析中请稍后”可能比较关心,看官们都想要学习一些“文件解析中请稍后”的相关文章。那么小编同时在网摘上网罗了一些对于“文件解析中请稍后””的相关知识,希望朋友们能喜欢,看官们快快来了解一下吧!在解析PE中,使用二级指针了,,在将PE加在到内存拉伸,拷贝section使用出现了问题,导致PE加载到内存,保存为PE文件的时候,无法运行.
PE加载到还原为文件
下面的一段代码,是有问题的.我们先看看代码
PIMAGE_SECTION_HEADER temp_section_header = section_header;for (int i = 0; i < file_header->NumberOfSections; i++){ //每次都是获取第一个节的内存地址 void* des = (void*)((unsigned long)temp_buffer + temp_section_header->VirtualAddress); void* src = (void*)((unsigned long)ptemp +(temp_section_header + i)->PointerToRawData); // //每次都是一个节的大小 memcpy(des, src, temp_section_header->SizeOfRawData); }
在循环内的3行代码,有两个代码是问题的(第一行和第三行).
正确的代码
PIMAGE_SECTION_HEADER temp_section_header = section_header;for (int i = 0; i < file_header->NumberOfSections; i++){ PIMAGE_SECTION_HEADER psection = temp_section_header + i; //这里 void* des = (void*)((unsigned long)temp_buffer + psection->VirtualAddress); //temp_section_header + 1,移动多少呢? void* src = (void*)((unsigned long)ptemp + psection->PointerToRawData); memcpy(des, src, psection->SizeOfRawData);}拉伸
拉伸:读取section(节)在文件中的PointerToRawData(在文件中的偏移量),大小为SizeOfRawData(文件中对齐的长度),转为在内存上布局.
//将pe文件(在内存中,还是文件布局)转换为pe在内存布局unsigned long buffer_to_image(char** file_buffer, char** image_buffer){ PIMAGE_DOS_HEADER dos_header = NULL; PIMAGE_NT_HEADERS nt_header = NULL; PIMAGE_FILE_HEADER file_header = NULL; PIMAGE_OPTIONAL_HEADER optional_header = NULL; PIMAGE_SECTION_HEADER section_header = NULL; char* ptemp = *file_buffer; void* temp_buffer = NULL; if (file_buffer == NULL) { printf("file_buff is null\n"); return 0; } if (*(short*)ptemp != IMAGE_DOS_SIGNATURE) { printf("%08x\n", *(short*)ptemp); //校验是否为dos头 pe开头为mz return 0; } dos_header = (PIMAGE_DOS_HEADER)ptemp; if (*(short*)((unsigned long)ptemp + dos_header->e_lfanew) != IMAGE_NT_SIGNATURE) { //校验nt头是否有pe标志 PE return 0; } nt_header = (PIMAGE_NT_HEADERS)((unsigned long)ptemp + dos_header->e_lfanew); file_header = (PIMAGE_FILE_HEADER)((unsigned long)nt_header + 4); optional_header = (PIMAGE_OPTIONAL_HEADER)((unsigned long)file_header + IMAGE_SIZEOF_FILE_HEADER); section_header = (PIMAGE_SECTION_HEADER)((unsigned long)optional_header + file_header->SizeOfOptionalHeader); //分配空间 temp_buffer = calloc(1, optional_header->SizeOfImage); if (!temp_buffer) { temp_buffer = NULL; return 0; } //从dos头开始拷贝,拷贝首部+块表的大小,到内存中 memcpy(temp_buffer, dos_header, optional_header->SizeOfHeaders); //SizeOfHeaders为首部及块表(首部+块表)的大小 PIMAGE_SECTION_HEADER temp_section_header = section_header; for (int i = 0; i < file_header->NumberOfSections; i++) { PIMAGE_SECTION_HEADER psection = temp_section_header + i; void* des = (void*)((unsigned long)temp_buffer + psection->VirtualAddress); void* src = (void*)((unsigned long)ptemp + psection->PointerToRawData); memcpy(des, src, psection->SizeOfRawData); } *image_buffer = temp_buffer; return optional_header->SizeOfImage; //SizeOfImage在内存中整个PE映像的大小}还原
//从内存还原为文件int recovery_file(void** image_buffer, char* file, int size){ PIMAGE_DOS_HEADER dos_header = NULL; PIMAGE_NT_HEADERS nt_header = NULL; PIMAGE_FILE_HEADER file_header = NULL; PIMAGE_OPTIONAL_HEADER optional_header = NULL; PIMAGE_SECTION_HEADER section_header = NULL; char* ptemp = *image_buffer; dos_header = (PIMAGE_DOS_HEADER)ptemp; if (*(short*)((unsigned long)ptemp + dos_header->e_lfanew) != IMAGE_NT_SIGNATURE) { //校验nt头是否有pe标志 PE return 0; } nt_header = (PIMAGE_NT_HEADERS)((unsigned long)ptemp + dos_header->e_lfanew); file_header = (PIMAGE_FILE_HEADER)((unsigned long)nt_header + 4); optional_header = (PIMAGE_OPTIONAL_HEADER)((unsigned long)file_header + IMAGE_SIZEOF_FILE_HEADER); section_header = (PIMAGE_SECTION_HEADER)((unsigned long)optional_header + file_header->SizeOfOptionalHeader); char* file_buffer = calloc(1, size); memcpy(file_buffer, dos_header, optional_header->SizeOfHeaders); PIMAGE_SECTION_HEADER temp_section_header = section_header; for (int i = 0; i < file_header->NumberOfSections; i++) { PIMAGE_SECTION_HEADER psection = temp_section_header + i; void* des = (void*)((unsigned long)file_buffer + psection->PointerToRawData); void* src = (void*)((unsigned long)ptemp + psection->VirtualAddress); memcpy(des, src, psection->SizeOfRawData); } FILE* fp = fopen(file, "wb+"); if (fp != NULL) { fwrite((void*)file_buffer, size, 1, fp); } fclose(fp);}
个人能力有限,如果您发现有什么不对,请私信我
如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流
标签: #文件解析中请稍后