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);
}