![]() |
#2
yuma2021-02-21 16:53
![]() #include<stdio.h> #include<stdlib.h> #include<string.h> #include<malloc.h> #define DWORD unsigned int #define WORD unsigned short #define BYTE unsigned char int FileSize(char* filePath) { int fileLength = 0; FILE* fp = fopen(filePath,"rb"); if(fp==NULL) { printf("open file failed!\n"); return 0; } fseek(fp,0,SEEK_END); fileLength = ftell(fp); fseek(fp,0,SEEK_SET); fclose(fp); fp = NULL; return fileLength; } BYTE* CreateMemory(int size) { BYTE* memory = (BYTE*)malloc(size); if(memory==NULL) { printf("malloc failed!\n"); return NULL; } memset(memory,0,size); return memory; } BYTE* ToFileBuffer(char* filePath) { int fileLength = FileSize(filePath); BYTE* fileBuffer = CreateMemory(fileLength); FILE* filePointer = fopen(filePath,"rb"); fread(fileBuffer,1,fileLength,filePointer); fclose(filePointer); filePointer = NULL; printf("tofilebuffer success!\n"); printf("fileBuffer:%p\n",fileBuffer); return fileBuffer; } BYTE* FileBufferToImageBuffer(BYTE* fileBuffer) { DWORD i = 0; DWORD j = 0; DWORD e_lfanew = *((DWORD*)(fileBuffer + 0x3C)); WORD SizeOfOptionalHeader = *((WORD*)(fileBuffer + e_lfanew + 0x14)); DWORD SIZE_PE_signature = 0x4; DWORD SIZE_FILE_HEADER = 0x14; WORD NUM_SECTION = *((WORD*)(fileBuffer + e_lfanew + 0x6)); DWORD SIZE_SECTION = NUM_SECTION * 40; DWORD SIZE_IMAGE = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x38)); DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader; DWORD SIZE_HEADERS = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x3C)); BYTE* imageBuffer = CreateMemory(SIZE_IMAGE); for(i=0;i<SIZE_HEADERS;i++) { *(imageBuffer+i) = *(fileBuffer+i); } i = 0; while(i<NUM_SECTION) { DWORD Misc = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x8 + i*0x28)); DWORD PointerToRawData = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x14 + i*0x28)); DWORD VirtualAddress = *((DWORD*)(fileBuffer + SIZE_HEADER + 0xc + i*0x28)); for(j=0;j<Misc;j++) { *(imageBuffer+VirtualAddress+j) = *(fileBuffer+PointerToRawData+j); } i++; } printf("FileBufferToImageBuffer success!\n"); printf("fileBuffer:%p\n",fileBuffer); printf("imageBuffer:%p\n",imageBuffer); return imageBuffer; } BYTE* ImageBufferToNewBuffer(BYTE* imageBuffer,char* filePath) { int fileLength = FileSize(filePath); DWORD i = 0; DWORD j = 0; DWORD e_lfanew = *((DWORD*)(imageBuffer + 0x3C)); WORD SizeOfOptionalHeader = *((WORD*)(imageBuffer + e_lfanew + 0x14)); DWORD SIZE_PE_signature = 0x4; DWORD SIZE_FILE_HEADER = 0x14; WORD NUM_SECTION = *((WORD*)(imageBuffer + e_lfanew + 0x6)); DWORD SIZE_SECTION = NUM_SECTION * 40; DWORD SIZE_IMAGE = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x38)); DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader; DWORD SIZE_HEADERS = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x3C)); BYTE* newBuffer = CreateMemory(fileLength); for(i=0;i<SIZE_HEADERS;i++) { *(newBuffer+i) = *(imageBuffer+i); } i = 0; while(i<NUM_SECTION) { DWORD Misc = *((DWORD*)(imageBuffer + SIZE_HEADER + 0x8 + i*0x28)); DWORD PointerToRawData = *((DWORD*)(imageBuffer + SIZE_HEADER + 0x14 + i*0x28)); DWORD VirtualAddress = *((DWORD*)(imageBuffer + SIZE_HEADER + 0xc + i*0x28)); for(j=0;j<Misc;j++) { *(newBuffer+PointerToRawData+j) = *(imageBuffer+VirtualAddress+j); } i++; } printf("ImageBufferToNewBuffer success!\n"); printf("imageBuffer:%p\n",imageBuffer); printf("newBuffer:%p\n",newBuffer); return newBuffer; } void WriteFile(char* Path,char* filePath,BYTE* memory) { int fileLength = FileSize(Path); FILE* fileBuffer = fopen(filePath,"wb"); fwrite(memory,1,fileLength,fileBuffer); fclose(fileBuffer); fileBuffer = NULL; printf("WriteFile success!\n"); return ; } int main() { char* Path = "C:\\Windows\\notepad.exe"; //调试的时候,此处需要进行修改下,这是原始文件名称 char* DstPath = "D:\\dscalltest111.exe"; //此处是将原来的文件加载到内存后,再从内存中提取出来,然后生成目标文件 BYTE* p = ToFileBuffer(Path); BYTE* p1 = FileBufferToImageBuffer(p); BYTE* p2 = ImageBufferToNewBuffer(p1,Path); WriteFile(Path,DstPath,p2); printf("文件生成成功!\n"); printf("p:%p\n",p); printf("p1:%p\n",p1); printf("p2:%p\n",p2); free(p1); //此处存在问题 printf("free(p1) success! p1:%p\n",p1); p1 = NULL; printf("p1 = NULL!\n"); free(p2); printf("free(p2) success! p2:%p\n",p2); p2 = NULL; printf("p2 = NULL!\n"); free(p); printf("free(p) success! p:%p\n",p); p = NULL; printf("p = NULL!\n"); getchar(); } 随便改了一下,运行正常了。 ![]() 只有本站会员才能查看附件,请 登录 只有本站会员才能查看附件,请 登录 [此贴子已经被作者于2021-2-21 16:54编辑过] |
在直接运行exe的时候,会出现程序崩溃(如果是运行文件对齐和内存对齐一致的文件,没有任何问题;运行文件对齐和内存对齐不一致的会有问题)。
但是加断点单步执行没有任何问题。。哭了...实在是找不到问题了

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#define DWORD unsigned int
#define WORD unsigned short
#define BYTE unsigned char
int FileSize(char* filePath)
{
int fileLength = 0;
FILE* fp = fopen(filePath,"rb");
if(fp==NULL)
{
printf("open file failed!\n");
return 0;
}
fseek(fp,0,SEEK_END);
fileLength = ftell(fp);
fseek(fp,0,SEEK_SET);
fclose(fp);
fp = NULL;
return fileLength;
}
BYTE* CreateMemory(int size)
{
BYTE* memory = (BYTE*)malloc(size);
if(memory==NULL)
{
printf("malloc failed!\n");
return NULL;
}
memset(memory,0,size);
return memory;
}
BYTE* ToFileBuffer(char* filePath)
{
int fileLength = FileSize(filePath);
BYTE* fileBuffer = CreateMemory(fileLength);
FILE* filePointer = fopen(filePath,"rb");
fread(fileBuffer,1,fileLength,filePointer);
fclose(filePointer);
filePointer = NULL;
printf("tofilebuffer success!\n");
printf("fileBuffer:%p\n",fileBuffer);
return fileBuffer;
}
BYTE* FileBufferToImageBuffer(BYTE* fileBuffer)
{
DWORD i = 0;
DWORD j = 0;
DWORD e_lfanew = *((DWORD*)(fileBuffer + 0x3C));
WORD SizeOfOptionalHeader = *((WORD*)(fileBuffer + e_lfanew + 0x14));
DWORD SIZE_PE_signature = 0x4;
DWORD SIZE_FILE_HEADER = 0x14;
WORD NUM_SECTION = *((WORD*)(fileBuffer + e_lfanew + 0x6));
DWORD SIZE_SECTION = NUM_SECTION * 40;
DWORD SIZE_IMAGE = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x38));
DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader;
DWORD SIZE_HEADERS = *((DWORD*)(fileBuffer + e_lfanew + 0x4 + 0x14 + 0x3C));
BYTE* imageBuffer = CreateMemory(SIZE_IMAGE);
for(i=0;i<SIZE_HEADERS;i++)
{
*(imageBuffer+i) = *(fileBuffer+i);
}
i = 0;
while(i<NUM_SECTION)
{
DWORD Misc = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x8 + i*0x28));
DWORD PointerToRawData = *((DWORD*)(fileBuffer + SIZE_HEADER + 0x14 + i*0x28));
DWORD VirtualAddress = *((DWORD*)(fileBuffer + SIZE_HEADER + 0xc + i*0x28));
for(j=0;j<Misc;j++)
{
*(imageBuffer+VirtualAddress+j) = *(fileBuffer+PointerToRawData+j);
}
i++;
}
printf("FileBufferToImageBuffer success!\n");
printf("fileBuffer:%p\n",fileBuffer);
printf("imageBuffer:%p\n",imageBuffer);
return imageBuffer;
}
BYTE* ImageBufferToNewBuffer(BYTE* imageBuffer,char* filePath)
{
int fileLength = FileSize(filePath);
DWORD i = 0;
DWORD j = 0;
DWORD e_lfanew = *((DWORD*)(imageBuffer + 0x3C));
WORD SizeOfOptionalHeader = *((WORD*)(imageBuffer + e_lfanew + 0x14));
DWORD SIZE_PE_signature = 0x4;
DWORD SIZE_FILE_HEADER = 0x14;
WORD NUM_SECTION = *((WORD*)(imageBuffer + e_lfanew + 0x6));
DWORD SIZE_SECTION = NUM_SECTION * 40;
DWORD SIZE_IMAGE = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x38));
DWORD SIZE_HEADER = e_lfanew + SIZE_PE_signature + SIZE_FILE_HEADER + SizeOfOptionalHeader;
DWORD SIZE_HEADERS = *((DWORD*)(imageBuffer + e_lfanew + 0x4 + 0x14 + 0x3C));
BYTE* newBuffer = CreateMemory(fileLength);
for(i=0;i<SIZE_HEADERS;i++)
{
*(newBuffer+i) = *(imageBuffer+i);
}
i = 0;
while(i<NUM_SECTION)
{
DWORD Misc = *((DWORD*)(imageBuffer + SIZE_HEADER + 0x8 + i*0x28));
DWORD PointerToRawData = *((DWORD*)(imageBuffer + SIZE_HEADER + 0x14 + i*0x28));
DWORD VirtualAddress = *((DWORD*)(imageBuffer + SIZE_HEADER + 0xc + i*0x28));
for(j=0;j<Misc;j++)
{
*(newBuffer+PointerToRawData+j) = *(imageBuffer+VirtualAddress+j);
}
i++;
}
printf("ImageBufferToNewBuffer success!\n");
printf("imageBuffer:%p\n",imageBuffer);
printf("newBuffer:%p\n",newBuffer);
return newBuffer;
}
void WriteFile(char* Path,char* filePath,BYTE* memory)
{
int fileLength = FileSize(Path);
FILE* fileBuffer = fopen(filePath,"wb");
fwrite(memory,1,fileLength,fileBuffer);
fclose(fileBuffer);
fileBuffer = NULL;
printf("WriteFile success!\n");
return ;
}
int main()
{
char* Path = "C:\\dscalltest.exe"; //调试的时候,此处需要进行修改下,这是原始文件名称
char* DstPath = "C:\\dscalltest111.exe"; //此处是将原来的文件加载到内存后,再从内存中提取出来,然后生成目标文件
BYTE* p = ToFileBuffer(Path);
BYTE* p1 = FileBufferToImageBuffer(p);
BYTE* p2 = ImageBufferToNewBuffer(p1,Path);
WriteFile(Path,DstPath,p2);
printf("文件生成成功!\n");
printf("p:%p\n",p);
printf("p1:%p\n",p1);
printf("p2:%p\n",p2);
free(p1); //此处存在问题
printf("free(p1) success! p1:%p\n",p1);
p1 = NULL;
printf("p1 = NULL!\n");
free(p2);
printf("free(p2) success! p2:%p\n",p2);
p2 = NULL;
printf("p2 = NULL!\n");
free(p);
printf("free(p) success! p:%p\n",p);
p = NULL;
printf("p = NULL!\n");
return 0;
}