-
-
[原创][分享]PE文件结构之打印重定位表
-
发表于: 2020-10-8 11:34 3502
-
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
DWORD ReadPEFile(char
*
filepath,PVOID
*
pFileBuffer)
{
PVOID pTempFileBuffer
=
NULL;
DWORD Filesize
=
0
;
FILE
*
pFile
=
NULL;
pFile
=
fopen(filepath,
"rb"
);
if
(!pFile)
{
printf(
"文件打开失败"
);
return
0
;
}
fseek(pFile,
0
,SEEK_END);
Filesize
=
ftell(pFile);
fseek(pFile,
0
,SEEK_SET);
pTempFileBuffer
=
malloc(Filesize);
if
(!pTempFileBuffer)
{
printf(
"申请动态内存失败"
);
fclose(pFile);
return
0
;
}
size_t n
=
fread(pTempFileBuffer,Filesize,
1
,pFile);
if
(!n)
{
printf(
"文件写入文件缓冲区失败"
);
free(pTempFileBuffer);
fclose(pFile);
return
0
;
}
*
pFileBuffer
=
pTempFileBuffer;
pTempFileBuffer
=
NULL;
free(pTempFileBuffer);
fclose(pFile);
return
Filesize;
}
DWORD RvaToFoa(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA)
{
PIMAGE_SECTION_HEADER pSection
=
(PIMAGE_SECTION_HEADER)((DWORD)pNTHeader
+
sizeof(IMAGE_NT_HEADERS));
for
(
int
i
=
0
; i < pNTHeader
-
>FileHeader.NumberOfSections; i
+
+
)
{
if
(dwRVA >
=
pSection[i].VirtualAddress && dwRVA < (pSection[i].VirtualAddress
+
pSection[i].SizeOfRawData))
{
return
pSection[i].PointerToRawData
+
(dwRVA
-
pSection[i].VirtualAddress);
}
}
return
0
;
}
void relocation(PVOID pFileBuffer)
{
BYTE secName[
9
]
=
{
0
};
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNtHeaders;
PIMAGE_BASE_RELOCATION pBaseRec;
PIMAGE_SECTION_HEADER pSectionHeader;
pDosHeader
=
(PIMAGE_DOS_HEADER)pFileBuffer;
pNtHeaders
=
(PIMAGE_NT_HEADERS)((DWORD)pFileBuffer
+
pDosHeader
-
>e_lfanew);
printf(
"重定位表的相对虚拟地址:%x\n"
,pNtHeaders
-
>OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
printf(
"重定位表的大小:%x\n"
,pNtHeaders
-
>OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
DWORD pBaseRecOffset
=
RvaToFoa(pNtHeaders, pNtHeaders
-
>OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
/
/
注意这个VirtualAddress是VA
pBaseRec
=
(PIMAGE_BASE_RELOCATION)(pBaseRecOffset
+
(DWORD)pFileBuffer);
pSectionHeader
=
(PIMAGE_SECTION_HEADER)(pNtHeaders
+
1
);
for
(
int
i
=
0
; pBaseRec
-
>SizeOfBlock && pBaseRec
-
>VirtualAddress; i
+
+
)
{
DWORD FOA
=
RvaToFoa(pNtHeaders, pBaseRec
-
>VirtualAddress);
DWORD size
=
(pBaseRec
-
>SizeOfBlock
-
8
)
/
2
;
/
/
VirtualAddress SizeOfBlock共占
8
字节,每个项
2
字节
/
/
确定该结构所属的节
for
(DWORD j
=
0
;j<pNtHeaders
-
>FileHeader.NumberOfSections;j
+
+
)
{
DWORD lower
=
RvaToFoa(pNtHeaders, pSectionHeader[j].VirtualAddress);
DWORD upper
=
RvaToFoa(pNtHeaders, pSectionHeader[j].VirtualAddress
+
pSectionHeader[j].Misc.VirtualSize);
if
(FOA>
=
lower && FOA<
=
upper )
{
memcpy(secName,pSectionHeader[j].Name,
8
);
break
;
}
}
printf(
"第%d块.Relocation\n VirtualAddress %x(%s)\n SizeOfBlock %x\n"
, i
+
1
, pBaseRec
-
>VirtualAddress,secName, size);
/
/
打印本页的主要信息
printf(
"RVA,TYPE\n"
);
/
/
打印一个页中,所有重定位地址与信息
WORD
*
recAddr
=
(WORD
*
)((BYTE
*
)pBaseRec
+
8
);
/
/
指向第一个目录项
/
/
如果高
4
位是
3
则取后
12
位地址加上VirtualAddress才是真正需要修复的数据的Rva
for
(j
=
0
; j<size; j
+
+
)
{
DWORD offset
=
(recAddr[j] &
0x0FFF
)
+
FOA ;
WORD
type
=
recAddr[j] >>
12
;
if
(
type
!
=
0
)
{
printf(
"%08X, %x\n"
,offset
+
pBaseRec
-
>VirtualAddress,
type
);
}
}
memset(secName,
0
,
9
);
pBaseRec
=
(PIMAGE_BASE_RELOCATION )((BYTE
*
)pBaseRec
+
pBaseRec
-
>SizeOfBlock);
/
/
移到下一页
}
}
int
main(
int
argc, char
*
argv[])
{
char filepath[]
=
"F:\\pwn\\test\\TTTT.dll"
;
PVOID pFileBuffer
=
NULL;
ReadPEFile(filepath,&pFileBuffer);
relocation(pFileBuffer);
return
0
;
}
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
DWORD ReadPEFile(char
*
filepath,PVOID
*
pFileBuffer)
{
PVOID pTempFileBuffer
=
NULL;
DWORD Filesize
=
0
;
FILE
*
pFile
=
NULL;
pFile
=
fopen(filepath,
"rb"
);
if
(!pFile)
{
printf(
"文件打开失败"
);
return
0
;
}
fseek(pFile,
0
,SEEK_END);
Filesize
=
ftell(pFile);
fseek(pFile,
0
,SEEK_SET);
pTempFileBuffer
=
malloc(Filesize);
if
(!pTempFileBuffer)
{
printf(
"申请动态内存失败"
);
fclose(pFile);
return
0
;
}
size_t n
=
fread(pTempFileBuffer,Filesize,
1
,pFile);
if
(!n)
{
printf(
"文件写入文件缓冲区失败"
);
free(pTempFileBuffer);
fclose(pFile);
return
0
;
}
*
pFileBuffer
=
pTempFileBuffer;
pTempFileBuffer
=
NULL;
free(pTempFileBuffer);
fclose(pFile);
return
Filesize;
}
DWORD RvaToFoa(PIMAGE_NT_HEADERS pNTHeader, DWORD dwRVA)
{
PIMAGE_SECTION_HEADER pSection
=
(PIMAGE_SECTION_HEADER)((DWORD)pNTHeader
+
sizeof(IMAGE_NT_HEADERS));
for
(
int
i
=
0
; i < pNTHeader
-
>FileHeader.NumberOfSections; i
+
+
)
{
if
(dwRVA >
=
pSection[i].VirtualAddress && dwRVA < (pSection[i].VirtualAddress
+
pSection[i].SizeOfRawData))
{
return
pSection[i].PointerToRawData
+
(dwRVA
-
pSection[i].VirtualAddress);
}
}
return
0
;
}
void relocation(PVOID pFileBuffer)
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
看原图
赞赏
雪币:
留言: