LPVOID ExpentPE_File()
/
/
拉伸文件
{
int
memSize
=
0
;
int
headerSize
=
0
;
PIMAGE_DOS_HEADER pDosHeader
=
NULL;
PIMAGE_NT_HEADERS pNTHeaders
=
NULL;
PIMAGE_FILE_HEADER pPEHeader
=
NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader
=
NULL;
PIMAGE_SECTION_HEADER pSectionHeader
=
NULL;
LPVOID sectionSource;
LPVOID sectionDestinaton;
LPVOID memcopycheck;
LPVOID pFileBuffer
=
NULL;
LPVOID pImageBuffer
=
NULL;
int
Filesize
=
0
;
/
/
读取文件
pFileBuffer
=
ReadPEFile((LPSTR)
"C:\\notepad.exe"
);
Filesize
=
File_size((LPSTR)
"C:\\notepad.exe"
);
if
(!pFileBuffer)
{
printf(
"文件读取失败\n"
);
return
NULL;
}
/
/
判断是否是有效的MZ标志
if
(
*
((PWORD)pFileBuffer) !
=
IMAGE_DOS_SIGNATURE)
{
printf(
"不是有效的MZ标志\n"
);
free(pFileBuffer);
return
NULL;
}
/
/
DOS头地址,类型为结构体指针
pDosHeader
=
(PIMAGE_DOS_HEADER)((DWORD)pFileBuffer);
/
/
NT头地址,类型为结构体指针
pNTHeaders
=
(PIMAGE_NT_HEADERS)((DWORD)pFileBuffer
+
pDosHeader
-
>e_lfanew);
/
/
printf(
"%x\n"
,
*
pNTHeaders);
/
/
标准PE头地址,类型为结构体指针
pPEHeader
=
(PIMAGE_FILE_HEADER)((DWORD)pNTHeaders
+
4
);
/
/
可选PE头地址,类型为结构体指针
pOptionHeader
=
(PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader
+
IMAGE_SIZEOF_FILE_HEADER);
/
/
定位可选PE头中ImageBuffer的大小,即拉伸后PE文件的大小
memSize
=
pOptionHeader
-
>SizeOfImage;
/
/
printf(
"%d"
,memSize);
/
/
开辟相应的地址空间,定义开辟空间的首地址
pImageBuffer
=
malloc((
int
)memSize);
/
/
将开辟的空间全部置零
memset(pImageBuffer,
0
, (
int
)memSize);
if
(!pImageBuffer)
{
printf(
"内存分配失败!"
);
return
NULL;
}
headerSize
=
pOptionHeader
-
>SizeOfHeaders;
/
/
将FileBuffer的头文件复制到ImageBuffer中
memcopycheck
=
memcpy(pImageBuffer, pFileBuffer, (
int
)headerSize);
if
(!memcopycheck)
{
printf(
"内存复制失败!"
);
free(pImageBuffer);
return
NULL;
}
/
/
定位第一个节表头位置,数据类型为结构体指针
pSectionHeader
=
(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader
+
pPEHeader
-
>SizeOfOptionalHeader);
/
/
printf(
"%d\n"
,pPEHeader
-
>NumberOfSections);
/
/
循环定位所有的节表
for
(
int
i
=
0
; i < (
int
)(pPEHeader
-
>NumberOfSections); i
+
+
)
{
/
/
printf(
"%s\n"
,pSectionHeader
-
>Name);
/
/
printf(
"%d\n"
,i);
/
/
定位所有的节所在ImageBuffer的位置
sectionDestinaton
=
(LPVOID)((DWORD)pImageBuffer
+
pSectionHeader
-
>VirtualAddress);
/
/
定位所有的节所在FileBuffer的位置
sectionSource
=
(LPVOID)((DWORD)pFileBuffer
+
pSectionHeader
-
>PointerToRawData);
/
/
将所有在FileBuffer中的节循环复制到ImageBuffer中去
memcopycheck
=
memcpy(sectionDestinaton, sectionSource, (
int
)(pSectionHeader
-
>SizeOfRawData));
if
(!memcopycheck)
{
printf(
"内存复制失败!"
);
free(pImageBuffer);
return
NULL;
}
/
/
定位到下一个节表位置
pSectionHeader
=
(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader
+
(DWORD)IMAGE_SIZEOF_SECTION_HEADER);
}
/
/
释放内存
free(pFileBuffer);
pFileBuffer
=
NULL;
return
pImageBuffer;
}