using namespace std;
char* pointpath=NULL;
//把文件读取到缓冲区FileBuffer,成功返回开辟的空间的指针,失败返回NULL
LPVOID REPE()
{
FILE* pfile = NULL;
DWORD FileSize = 0;
LPVOID FileBuffer = NULL;
pfile = fopen(pointpath,"rb");
if (!pfile)
{
printf("文件打开失败\n");
fclose(pfile);
return NULL;
}
fseek(pfile, SEEK_SET, SEEK_END);
FileSize = ftell(pfile);
fseek(pfile, SEEK_SET, SEEK_SET);
FileBuffer = malloc(FileSize);
if (!FileBuffer)
{
printf("开辟空间失败\n");
fclose(pfile);
free(FileBuffer);
return NULL;
}
size_t n = fread(FileBuffer,FileSize,1,pfile);
if (!n)
{
printf("读取文件到内存失败\n");
free(FileBuffer);
return NULL;
}
fclose(pfile);
return FileBuffer;
}
//把FileBuffer 拉伸成ImageBuffer //2022/1/26 搞定没问题
LPVOID FileBufferToImageBuffer()
{
LPVOID ImageBuffer = NULL;
LPVOID FileBuffer = NULL;
FileBuffer = REPE();
if (!FileBuffer)
{
printf("FileBuffer赋值成功\n");
free(FileBuffer);
}
if (*(PWORD)((char*)FileBuffer) != IMAGE_DOS_SIGNATURE)
{
printf("在FTI里 不是有效的MZ标记\n");
}
PIMAGE_DOS_HEADER FILE_DOC = NULL;
PIMAGE_NT_HEADERS FILE_NT = NULL;
PIMAGE_FILE_HEADER FILE_FIE = NULL;
PIMAGE_OPTIONAL_HEADER64 FILE_OP64 = NULL;
PIMAGE_SECTION_HEADER FILE_SEC = NULL;
FILE_DOC = (PIMAGE_DOS_HEADER)((char*)FileBuffer); //头部转化
FILE_NT = (PIMAGE_NT_HEADERS)((char*)FileBuffer + FILE_DOC->e_lfanew);
if (FILE_NT->Signature!=IMAGE_NT_SIGNATURE)
{
printf("在FTI里 NT头部赋值失败");
}
FILE_FIE= (PIMAGE_FILE_HEADER)((char*)FileBuffer + FILE_DOC->e_lfanew+4);
FILE_OP64=(PIMAGE_OPTIONAL_HEADER64)((char*)FileBuffer + FILE_DOC->e_lfanew + 4+IMAGE_SIZEOF_FILE_HEADER);
FILE_SEC = (PIMAGE_SECTION_HEADER)((char*)FileBuffer + FILE_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER + FILE_FIE->SizeOfOptionalHeader); //第一个节表的位置
DWORD ImageBufferSize = 0;
ImageBufferSize = FILE_OP64->SizeOfImage;
ImageBuffer = malloc(ImageBufferSize);
if (!ImageBuffer)
{
printf("拉伸后的空间失败了\n");
free(ImageBuffer);
return NULL;
}
memset(ImageBuffer, 0, ImageBufferSize);
//开始Copy FileBufferToImageBuffer
memcpy(ImageBuffer, FileBuffer, FILE_OP64->SizeOfHeaders); //copy头部
PIMAGE_DOS_HEADER IMAGE_DOC = NULL;
PIMAGE_NT_HEADERS IMAGE_NT = NULL;
PIMAGE_FILE_HEADER IMAGE_FIE = NULL;
PIMAGE_OPTIONAL_HEADER64 IMAGE_OP64 = NULL;
PIMAGE_SECTION_HEADER IMAGE_SEC = NULL;
IMAGE_DOC = (PIMAGE_DOS_HEADER)(ImageBuffer);
IMAGE_NT = (PIMAGE_NT_HEADERS)((char*)ImageBuffer + IMAGE_DOC->e_lfanew);
IMAGE_FIE = (PIMAGE_FILE_HEADER)((char*)ImageBuffer + IMAGE_DOC->e_lfanew + 4);
IMAGE_OP64=(PIMAGE_OPTIONAL_HEADER64)((char*)ImageBuffer + IMAGE_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
IMAGE_SEC = (PIMAGE_SECTION_HEADER)((char*)ImageBuffer + IMAGE_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_FIE->SizeOfOptionalHeader);
int Nsec = FILE_FIE->NumberOfSections;
cout << "复制的节表的数量=" << Nsec << endl;
for (int i = 0; i < Nsec; i++)
{
FILE_SEC = (PIMAGE_SECTION_HEADER)((char*)FileBuffer + FILE_DOC->e_lfanew
+ 4 + IMAGE_SIZEOF_FILE_HEADER + FILE_FIE->SizeOfOptionalHeader+i*IMAGE_SIZEOF_SECTION_HEADER);
IMAGE_SEC = (PIMAGE_SECTION_HEADER)((char*)ImageBuffer + IMAGE_DOC->e_lfanew
+ 4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_FIE->SizeOfOptionalHeader + i * IMAGE_SIZEOF_SECTION_HEADER);
//关于memcpy的函数我们要注意到参数的传递方向(目标,源头,复制的长度)
memcpy((PDWORD)((char*)ImageBuffer+(FILE_SEC->PointerToRawData)), (PDWORD)((char*)FileBuffer + (IMAGE_SEC->VirtualAddress)),FILE_SEC->SizeOfRawData); //通过循环把节的数据拷贝
printf("从FileBuffer节表%s复制到ImageBuffer节表%s成功\n", FILE_SEC->Name, IMAGE_SEC->Name);
}
printf("FileBufferToImageBuffer结束,ImageBuffer的尺寸:%x\n",IMAGE_OP64->SizeOfImage);
return ImageBuffer;
}
//把ImageBuffer 拉伸成NewBuffer,需要传入ImageBuffer空间的指针,成功返回NewBuffer的空间地址指针 //2022/1/26 搞定没问题
LPVOID ImageBufferToNewBuffer(LPVOID ImageBuffer)
{
LPVOID NewBuffer = NULL;
PIMAGE_DOS_HEADER IMAGE_DOC = NULL;
PIMAGE_NT_HEADERS IMAGE_NT = NULL;
PIMAGE_FILE_HEADER IMAGE_FILE = NULL;
PIMAGE_OPTIONAL_HEADER64 IMAGE_OP64 = NULL;
PIMAGE_SECTION_HEADER IMAGE_SEC = NULL;
IMAGE_DOC =(PIMAGE_DOS_HEADER)ImageBuffer;
if (IMAGE_DOC->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("在ITNew里 不是有效的MZ标记\n");
free(ImageBuffer);
}
IMAGE_NT = (PIMAGE_NT_HEADERS)((char*)ImageBuffer + IMAGE_DOC->e_lfanew);
if (IMAGE_NT->Signature != IMAGE_NT_SIGNATURE)
{
printf("在ITNew里 NT头部赋值失败");
}
IMAGE_FILE = (PIMAGE_FILE_HEADER)((char*)ImageBuffer + IMAGE_DOC->e_lfanew + 4);
IMAGE_OP64 = (PIMAGE_OPTIONAL_HEADER64)((char*)ImageBuffer + IMAGE_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
IMAGE_SEC = (PIMAGE_SECTION_HEADER)((char*)ImageBuffer + IMAGE_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_FILE->SizeOfOptionalHeader);
DWORD NewBufferSize = 0;
NewBufferSize = IMAGE_OP64->SizeOfImage;
NewBuffer = malloc(NewBufferSize);
if (!NewBuffer)
{
printf("NewBuffer空间开辟失败\n");
free(NewBuffer);
}
memset(NewBuffer, 0, NewBufferSize);
//开始ImageBuffer 转化为NewBuffer
memcpy(NewBuffer, ImageBuffer, IMAGE_OP64->SizeOfHeaders); //copy头部
PIMAGE_DOS_HEADER New_DOC = NULL;
PIMAGE_NT_HEADERS New_NT = NULL;
PIMAGE_FILE_HEADER New_FIE = NULL;
PIMAGE_OPTIONAL_HEADER64 New_OP64 = NULL;
PIMAGE_SECTION_HEADER New_SEC = NULL;
New_DOC = (PIMAGE_DOS_HEADER)(NewBuffer);
New_NT = (PIMAGE_NT_HEADERS)((char*)NewBuffer + New_DOC->e_lfanew);
New_FIE = (PIMAGE_FILE_HEADER)((char*)NewBuffer + New_DOC->e_lfanew + 4);
New_OP64 = (PIMAGE_OPTIONAL_HEADER64)((char*)NewBuffer + New_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER);
New_SEC = (PIMAGE_SECTION_HEADER)((char*)NewBuffer + New_DOC->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER + New_FIE->SizeOfOptionalHeader);
int Nsec = New_FIE->NumberOfSections;
for (int i = 0; i < Nsec; i++)
{
IMAGE_SEC = (PIMAGE_SECTION_HEADER)((char*)ImageBuffer + IMAGE_DOC->e_lfanew
+ 4 + IMAGE_SIZEOF_FILE_HEADER + IMAGE_FILE->SizeOfOptionalHeader + i * IMAGE_SIZEOF_SECTION_HEADER);
New_SEC = (PIMAGE_SECTION_HEADER)((char*)NewBuffer + New_DOC->e_lfanew
+ 4 + IMAGE_SIZEOF_FILE_HEADER + New_FIE->SizeOfOptionalHeader + i * IMAGE_SIZEOF_SECTION_HEADER);
memcpy(((PWORD)(char*)NewBuffer + (New_SEC->PointerToRawData)), ((PWORD)(char*)ImageBuffer + (IMAGE_SEC->VirtualAddress)), New_SEC->SizeOfRawData);
//memcpy((PDWORD)((char*)FileBuffer + (IMAGE_SEC->VirtualAddress)), (PDWORD)((char*)ImageBuffer + (FILE_SEC->PointerToRawData)), FILE_SEC->SizeOfRawData); //通过循环把节的数据拷贝
}
printf("ImageBufferToNewBuffer结束,Newbuffer的尺寸是:%x\n",New_OP64->SizeOfImage);
return NewBuffer;
}
//存盘用函数,传入的参数是内存映像空间的指针 buffer //2022/1/26 搞定没问题,但是存盘之后打不开
VOID FileSave(LPVOID Buffer)
{
char* FileSavepath= NULL;
string Filesavepath;
cout << "请输入要存盘的文件路径" << endl;
cin >> Filesavepath;
FileSavepath = &Filesavepath[0];
cout << "文件的路径为:" << FileSavepath << endl;
DWORD SaveSize=0;
cout << "请输入存盘的函数尺寸(buffer函数有显示)" << endl;
cin >> SaveSize;
cout << "存盘尺寸为:" << SaveSize << endl;
FILE* FileSave = NULL;
FileSave = fopen(FileSavepath, "wb");
if (!FileSave)
{
printf("新建流文件失败\n");
fclose(FileSave);
}
size_t saven= fwrite(Buffer, SaveSize,1,FileSave);
if (!saven)
{
printf("fwrite写入函数失败\n");
fclose(FileSave);
}
else
{
printf("写入成功\n");
}
}
int main()
{
string path;
cout << "请输入文件的路径及名称" << endl;
cin >> path;
cout << "输入结束,路径为:" <<path<< endl;
pointpath = &path[0];
LPVOID imagebuffers = FileBufferToImageBuffer();
printf("拉伸后的内存地址是%x\n", imagebuffers);
LPVOID newbuffers = ImageBufferToNewBuffer(imagebuffers);
printf("压缩后的内存地址是%x\n", newbuffers);
cout << "开始将Newbuffer的代码进行存盘" << endl;
FileSave(newbuffers);
}