Parsing PE files

In recent self parsing PE files, according to peppers (CFF Explorer) as well as the chiefs of each forum post, he made a black print PE file, which lasted seven days to complete, here want to have the relevant needs of the students at the idea of ​​sharing , inadequacies also hope you have educated us, pointing out. Thank you.

 

PE file header mainly DOS, NT head (containing the PE header, the optional PE header, the optional PE header but also contains a data directory, which contains other forms of RVA and size), the section table

Forms are mainly export table, import table, relocation table, resources table. In addition to the resource table, another form of the data are implemented in code printing.

 

First opened by CreateFile file, get the file handle, then call CreateFileMapping generation memory-mapped object, then call MapViewOfFile obtain the base address of the mapping file.

DOS header RVA = (IMAGE_DOS_HEADER) mapped base address;

NT head RVA = (IMAGE_NT_HEADERS) DOS header + DOS header -> e_lfanew value;

PE header RVA = & ((IMAGE_FILE_HEADER) NT header -> FileHeader);

Alternatively PE header RVA = & ((IMAGE_OPTIONAL_HEADER) NT header -> OptionalHeader);

Section table RVA = IMAGE_FIRST_SECTION (NT head); // position table section header size = DOS (OK) + PE header size standard (determination) + PE Optional Header Size (PE head members standard optional recording PE .SizeOfOptionalHeader head size)

Table Section Number: PE header -> NumberOfSections;

Import table, export table, the RVA relocation table lengths and the head in an optional PE -> DataDirectory third, first, sixth and VirtualAddress size among the array members (note array index starts from 0)

Po the following codes:

#include<Windows.h>
#include<iostream>
#include<time.h>

using namespace std;


struct _MAP_FILE_STRUCT typedef
{
HANDLE hFile; // file handle
HANDLE hMapping; // mapping file handle
LPVOID YXImageBase; // image base
} MAP_FILE_STRUCT, * PMAP_FILE_STRUCT;

/ * A loaded file to be opened
by way of memory mapped file is loaded into memory, the memory mapping function comprising: CreateFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFile and FlushViewOfFile.
Definition of a function, if it is a PE file returns true, otherwise to false: * /
BOOL the LoadFile (LPTSTR the lpFileName, PMAP_FILE_STRUCT pstMapFile) // load the file and the file handle,
{
IF (the lpFileName == nullptr a)
{
return to false;
}
hFile = NULL HANDLE;
HANDLE hMapping = NULL;
LPVOID the ImageBase = NULL;
Memset (pstMapFile, 0, the sizeof (MAP_FILE_STRUCT));

// 1, opened read-only file, the file handle returned
hFile = the CreateFile (the lpFileName, of GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
IF (hFile!)
{
Return to false;
}

2 // Create a memory-mapped file objects
hMapping the CreateFileMapping = (hFile, NULL, PAGE_READONLY, 0, 0, 0);
IF (hMapping!)
{
The CloseHandle (hFile);
return to false;
}

// 3, memory-mapped file to create a view of
the ImageBase the MapViewOfFile = (hMapping, FILE_MAP_READ, 0, 0, 0);
IF (the ImageBase!)
{
The CloseHandle (hFile);
the CloseHandle (hMapping);
return to false;
}
pstMapFile-> = hFile hFile;
pstMapFile-> hMapping = hMapping;
pstMapFile-> = YXImageBase the ImageBase;
return to true;
}

// Second, the program is finished, resource recovery
void UnLoadFile (PMAP_FILE_STRUCT pstMapFile)
{
IF (pstMapFile-> hFile)
{
the CloseHandle (pstMapFile-> hFile);
}


if (pstMapFile->hMapping)
{
CloseHandle(pstMapFile->hMapping);
}


IF (pstMapFile-> YXImageBase)
{
// undo CloseHandle function mapping using object handles memory mapped file Close
the UnmapViewOfFile (pstMapFile-> YXImageBase);
}
}

// Third, file format detection

bool IsPEFile (LPVOID ImageBase) // 1. If the base address is 0 2.DOC head e_magic not 5A4D (MZ) Signature 3.NT head is not 00.00455 million (PE) Renyi Cheng Li, the file is not a PE file
{
PIMAGE_DOS_HEADER pDH = nullptr; // pointer to null
PIMAGE_NT_HEADERS32 pNtH = nullptr;

if (!ImageBase)
{
return false;
}


pDH = (PIMAGE_DOS_HEADER)ImageBase;
if (pDH->e_magic != IMAGE_DOS_SIGNATURE) // 5A4D "MZ"
{
return false;
}

// pDH-> e_lfanew PIMAGE_NT_HEADERS32 stored offset address, the base address plus the address pDH shall MAGE_NT_HEADERS
pNtH = (PIMAGE_NT_HEADERS32) ((DWORD ) pDH + pDH-> e_lfanew); // last base address + DOS header is the value of the next element to obtain a head address NT
IF (pNtH-> the Signature = named IMAGE_NT_SIGNATURE!) // "the PE"
{
return to false;
}

return true;
}


// four, and the contents read FileHeader OptionalHeader of
PIMAGE_DOS_HEADER GetDOSHeaders (LPVOID ImageBase) // 1 , a configuration of acquiring the pointer pointing IMAGE_DOS_HEADERS
{
PIMAGE_DOS_HEADER = nullptr a pDH;
IF (IsPEFile (the ImageBase)!)
{
Return nullptr a;
}

Pdः = (Finage_dosh_hader) Imgebse;
Return PDH;
}

PIMAGE_NT_HEADERS GetNtHeader (LPVOID ImageBase) // 2 , a configuration of acquiring the pointer pointing IMAGE_NT_HEADERS
{
PIMAGE_DOS_HEADER = nullptr a pDH;
PIMAGE_NT_HEADERS = nullptr a pNtH;
(! IsPEFile (the ImageBase)) IF
{
return nullptr a;
}


Pdः = (Finage_dosh_hader) Imgebse;
Pnta = (Finage_nt_ःaadehris) ((DWORD) Pdः + Pdः-> I_lfanev);
return pNtH;
}

PIMAGE_FILE_HEADER GetFileHeader (LPVOID ImageBase) // 3 , a configuration of acquiring the pointer pointing IMAGE_FILE_HEADER
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader (the ImageBase);
IF (pNtH!)
{
Return nullptr a;
}
return & (pNtH-> FileHeader is);
}

PIMAGE_OPTIONAL_HEADER GetOptionalHeader (LPVOID ImageBase) // 4 , a configuration of acquiring the pointer pointing IMAGE_OPTIONAL_HEADER
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader (the ImageBase);
IF (pNtH!)
{
Return nullptr a;
}
return & (pNtH-> the OptionalHeader);
}


PIMAGE_SECTION_HEADER GetSectionone (LPVOID ImageBase) // 5 , the first point to obtain a pointer to the head section
{
PIMAGE_NT_HEADERS pNtH = GetNtHeader (the ImageBase); // get NT header
IF (pNtH!)
{
Return nullptr a;
}
positions // = the section table DOS header size (determined) + PE header size standard (determination) + PE optional header size (PE head members standard optional PE .SizeOfOptionalHeader recording head size)
return IMAGE_FIRST_SECTION (pNtH); // SECTION obtained by the formula first address
}


short GetSectionCount (LPVOID ImageBase) // 6 , the number derived by the section header of NumberOfSections File Hander
{
PIMAGE_FILE_HEADER pNtFileHeader = GetFileHeader (the ImageBase);
IF (! pNtFileHeader = NULL)
{
return pNtFileHeader-> in NumberOfSections;
}
}

// V. NAT
// 1. Relative virtual address forwarding file address (file address = base address + mapping file offset address (file offset address within the memory offset = RVA- range (start point) within the range of + File offset (start point)))
DWORD RVAtoFA (LPVOID the ImageBase, the RVA DWORD) // receiving a map base address of the current file to be converted and the RVA
{
PIMAGE_SECTION_HEADER m_section = GetSectionone (the ImageBase); // points to a section table
PIMAGE_FILE_HEADER m_pe = GetFileHeader ( ImageBase); // points to the PE header
int sectioncount = m_pe-> NumberOfSections; // get section table number
for (int NUM = 0; NUM <sectioncount; NUM ++)
{
IF (the RVA> = m_section-> && the VirtualAddress the RVA <(m_section -> VirtualAddress + m_section-> Misc.VirtualSize) ) // if the value falls within a range RVA current node
{
return (DWORD) RVA the ImageBase + - m_section-> + m_section- the VirtualAddress> the PointerToRawData;
/ * the file address = mapping file base + offset address (RVA- VirtualAddress + RawAddress)
Mapping the RVA = base address + - + RawAddress the VirtualAddress * /
}
m_section ++; // to point to the next table section
}
return 0;
}

// 2. Relative Virtual Address file offset address (file offset address memory offset = (starting point) within the range of + RVA- file offset range (start point)))
DWORD RVAtoFVA (LPVOID the ImageBase, the RVA DWORD) mapping // receiving a base address of the current file to be converted and the RVA
{
PIMAGE_SECTION_HEADER m_section = GetSectionone (the ImageBase); // points to a section table
PIMAGE_FILE_HEADER m_pe = GetFileHeader (ImageBase); // points to the PE header
int sectioncount = m_pe-> NumberOfSections; // get section table number
for (int NUM = 0; NUM <sectioncount; NUM ++)
{
IF (RVA> = m_section-> && the VirtualAddress RVA <(m_section-> + m_section- the VirtualAddress> Misc.VirtualSize)) // if RVA value falls within the range of the current node
{
return the RVA - m_section-> + m_section- the VirtualAddress> the PointerToRawData;
}
m_section ++; // to point to the next table section
}
return 0;
}

Virtual Address 3 // file offset address.
DWORD VAtoFVA (LPVOID the ImageBase, DWORD VA) VA // accepts a current base address mapping file to be converted and the
{
PIMAGE_NT_HEADERS pNT = GetNtHeader (the ImageBase); // get NT header
DWORD IB = pNT-> OptionalHeader.ImageBase; // get the base address
DWORD RVA = VA - IB; // VA to be converted is first converted to RVA

PIMAGE_SECTION_HEADER m_section = GetSectionone (ImageBase); // points to a section table
PIMAGE_FILE_HEADER m_pe = GetFileHeader (ImageBase); // points to the PE header
int sectioncount = m_pe-> NumberOfSections; // get section table number
for (int num = 0; num <sectioncount ; NUM ++)
{
IF (RVA> m_section-> && the VirtualAddress RVA <(m_section-> + m_section- the VirtualAddress> Misc.VirtualSize)) // if the value of the current node RVA falls within a range of
{
return RVA - m_section-> the VirtualAddress + m_section-> PointerToRawData; // file offset address is the RVA = - + RawAddress the VirtualAddress
}
m_section ++; // to point to the next table section
}
return 0;
}

// 4 relative virtual address translation of virtual addresses
DWORD RVAtoVA (LPVOID ImageBase, DWORD RVA ) // receiving a map base address of the current file to be converted and the RVA
{
PIMAGE_NT_HEADERS pNT = GetNtHeader (the ImageBase); // get NT header
DWORD IB = pNT-> OptionalHeader.ImageBase; // get the base address
return the IB the RVA +;
}

// Address 5 relative virtual address virtual
DWORD VAtoRVA (LPVOID ImageBase, DWORD VA ) // receiving a map base address of the current file to be converted and the VA
{
PIMAGE_NT_HEADERS pNT = GetNtHeader (the ImageBase); // get NT header
DWORD IB = pNT-> OptionalHeader.ImageBase; // get the base address of the
return VA - the IB;
}

// Sixth, the output file header information

void ShowFileHeaderInfo(PMAP_FILE_STRUCT stMapFile)
{
char strTmp[1024] = { 0 };

PIMAGE_DOS_HEADER p_dos = nullptr; // DOS header
p_dos = GetDOSHeaders (stMapFile-> YXImageBase);
IF (p_dos!)
{
The printf ( "Get DOS header failed \ n-");
return;
}
the printf ( "Header Dos: \ n-") ;
the printf ( "e_magic: 04LX% \ n-", p_dos-> e_magic);
/ * number of information * / omitted
printf ( "\ n");

PIMAGE_NT_HEADERS m_nt = nullptr; // NT head
m_nt = GetNtHeader (stMapFile-> YXImageBase);
IF (m_nt!)
{
The printf ( "get file header failed \ n-");
return;
}
the printf ( "NT Header: \ n-") ;
the printf ( "the Signature: 08x% \ n-", m_nt-> the Signature);

PIMAGE_FILE_HEADER p_file = nullptr; // PE header
// hexadecimal format information
p_file = GetFileHeader (stMapFile-> YXImageBase) ; // This will return out of the NT File structure of the first address header
char * strFileHeaderFormat = "\ nIMAGE_FILE_HEADER: \ the n-\
Machine:% 04LX \ the n-\
NumberOfSections:% 04LX \ the n-\
TimeDateStamp:% 04LX \ the n-\
PointerToSymbolTable:% 08X \ the n-\
NumberOfSymbols:% 08lX \ the n-\
SizeOfOptionalHeader:% 04LX \ the n-\
Characteristics :% 04LX \ n-\ n-";
sprintf (strTmp, strFileHeaderFormat, p_file-> Machine, p_file-> in NumberOfSections, p_file-> TimeDateStamp The, p_file-> PointerToSymbolTable, p_file-> NumberOfSymbols,
p_file-> SizeOfOptionalHeader The, p_file-> Characteristics) ;
the printf ( "% S", strTmp);

memset(strTmp, 0, sizeof(strTmp));


PIMAGE_OPTIONAL_HEADER p_oh = nullptr; // optional PE header
char * strFileOptHeaderFormat = "\ nIMAGE_OPTIONAL_HEADER: \ n-\
the Entry Point: 08lX% \ n-\
Image Base: 08lX% \ n-\
Code Base: 08lX% \ n-\
the Data Base:% 08lX \ the n-\
Image Size:% 08lX \ the n-\
Headers Size:% 08lX \ the n-\
Section Alignment:% 08lX \ the n-\
File Alignment:% 08lX \ the n-\
the Subsystem:% 08lX \ the n-\
the Check Sum:% 04LX \ the n- \
Dll Flags:% 04LX \ the n-\ the n-";
p_oh = GetOptionalHeader (stMapFile-> YXImageBase); // return this time out is the first address of the optional head structure of NT
IF (p_oh!)
{
printf (" the Get File Optional failed Header \ n-");!
return;
}
sprintf(strTmp, strFileOptHeaderFormat, p_oh->AddressOfEntryPoint, p_oh->ImageBase, p_oh->BaseOfCode, p_oh->BaseOfData,
p_oh->SizeOfImage, p_oh->SizeOfHeaders, p_oh->SectionAlignment, p_oh->FileAlignment, p_oh->Subsystem, p_oh->CheckSum, p_oh->DllCharacteristics);
printf("%s", strTmp);

 


PIMAGE_SECTION_HEADER p_section = nullptr; // table section
p_section = GetSectionone (stMapFile-> YXImageBase) ; // NT obtained by the first base address is calculated by the equation then a first section of the address
DWORD sectioncount = p_file-> NumberOfSections; // PE header by the NumberOfSections members obtained number of sections of
the printf ( "name: \ tVirtual Size \ tVirtual the Address \ Traw Size \ Traw the Address \ T \ n-");
for (DWORD NUM = 0; NUM <sectioncount; NUM ++)
{
/ * the printf ( " name:% S, the Virtual Size:% 08x, the Virtual the Address:% 08x, Raw Size:% 08x, Raw the Address: 08x% \ n-",
p_section-> the name, p_section-> Misc.VirtualSize, p_section-> the VirtualAddress, p_section -> the SizeOfRawData, p_section-> the PointerToRawData); * /
the printf ( "% S: \ T% 08x \ T% 08x \ T% 08x \ T% 08x \ n-", p_section-> the Name, p_section-> Misc.VirtualSize, p_section-> VirtualAddress, p_section-> SizeOfRawData,p_section->PointerToRawData);
p_section++;
}
printf("\n");


/ * Optional DataDirectory PE head array (the array is inside of IMAGE_DATA_DIRECTORY RVA and size of each table) * /
PIMAGE_OPTIONAL_HEADER ID_RVA = nullptr a; // import table

ID_RVA = GetOptionalHeader (stMapFile-> YXImageBase) ; // This will return out of the optional configuration of the first address of the NT header
printf ( "import table relative offset address is: 0x% 08x \ n", ID_RVA-> DataDirectory [ . 1] .VirtualAddress);
the printf ( "the size of the table is introduced: 0x% 08x \ n", ID_RVA-> DataDirectory [1] .Size); // contrast value was correctly

int dllcount; // dll quantity
int funccount; // dll number of functions in
Long d_dRVA = ID_RVA-> the DataDirectory [. 1] .VirtualAddress;
// get the first import table address
PIMAGE_IMPORT_DESCRIPTOR pdll = (PIMAGE_IMPORT_DESCRIPTOR) (( UCHAR *) RVAtoFA (stMapFile-> YXImageBase, d_dRVA));
rear / vertical 2 * Similarly, in the document are determined by VA RVA desired address, the one above obtained FVA file, manually add the image base address; directly below the piece returns FRVA (file address)
VA = virtual address RVA = IB relative virtual address base address of the file address FRVA = FVA = file offset addresses (relative to the start) FIB = mapped base (i.e. stMapFile- > YXImageBase) * /
// PIMAGE_IMPORT_DESCRIPTOR pdll2 = (PIMAGE_IMPORT_DESCRIPTOR) ImageRvaToVa (d_nt, d_nIB, CCC-> the DataDirectory [. 1] .VirtualAddress, NULL);

for (dllcount = 0; pdll-> the FirstThunk = NULL;! dllcount ++)
{
char * dllname = (char *) RVAtoFA (stMapFile-> YXImageBase, pdll-> the Name); // the name of the DLL storage address into a character pointer
the printf ( "the DLL the Name:% S \ T the INT: 08x 0x%, the RVA the Name: 0x% 08x, the IAT: 08x 0x% \ n-",
dllname, pdll-> in OriginalFirstThunk, pdll-> the Name, pdll-> the FirstThunk);

// table name input dll obtained by introducing OriginalFirstThunk table (INT of VRA) VA
// PIMAGE_THUNK_DATA f_thunk = (PIMAGE_THUNK_DATA) ImageRvaToVa (d_nt, d_nIB, pdll-> OriginalFirstThunk, NULL);
PIMAGE_THUNK_DATA f_thunk = (PIMAGE_THUNK_DATA) ( (UCHAR *) RVAtoFA (stMapFile-> YXImageBase, pdll-> in OriginalFirstThunk));
for (funccount = 0; f_thunk-> u1.Function = 0;! funccount ++)
{
IF (f_thunk-> u1.AddressOfData & 0x80000000) // If the import table name table input (INT) of the most significant bit is 1, was introduced by serial number
{
the printf ( "\ T [D%] \ T the IAT:% 04X \ T introduced ID:% 04x \ n", funccount , f_thunk-> u1.AddressOfData, f_thunk-> u1.AddressOfData & 0xFFFF);
} // here f_thunk-> & 0xffff is to make the final 32-bit to 16-bit binary displayed u1.AddressOfData
the else // is not 1, then in this case the function name as a string point RVA PIMAGE_IMPORT_BY_NAME structure becomes
{
PIMAGE_IMPORT_BY_NAME f_name = (PIMAGE_IMPORT_BY_NAME)RVAtoFA(stMapFile->YXImageBase, f_thunk->u1.AddressOfData);
printf("\t[%d]\t Hint:%04x\t Name:%s\n", funccount, f_name->Hint, f_name->Name);
}

++ f_thunk;
}
the printf ( "-------------------------------------------- --------------------------------------------- \ n ");
++ PDLL;
}
the printf ( "PE file import table of the total of the% d DLL \ n \ n", dllcount );

IMAGE_IMPORT_DESCRIPTOR ITDP; // Import table comprises an array of such structures, and finally to a structure are all 0 as the end marker
IMAGE_THUNK_DATA ITD2P; // the above-described configuration, there are two members introduced name table (INT) and Import Address Table ( IAT) is the type of structure
IMAGE_IMPORT_BY_NAME IIBN; // ITD when the most significant bit is 1, the value IAT directivity becomes such a configuration RVA

/ * Export table * /
PIMAGE_OPTIONAL_HEADER ED_RVA = GetOptionalHeader (stMapFile-> YXImageBase);
the printf ( "Export Table relative offset address: 08x 0x% \ n-", ED_RVA-> the DataDirectory [0] .VirtualAddress);
the printf ( "Export table length: 08x 0x% \ n-", ED_RVA-> the DataDirectory [0] .Size);
DWORD m_EDRva = ED_RVA-> the DataDirectory [0] .VirtualAddress; // offset address relative table derived
PIMAGE_EXPORT_DIRECTORY pEDFA = (PIMAGE_EXPORT_DIRECTORY) ( (UCHAR *) RVAtoFA (stMapFile-> YXImageBase, m_EDRva)); // obtain the list of exported file address
printf ( "----------------------- -------------------------------------------------- ------- \ n-");
the printf (" Member \ T \ T \ T Offset \ Size T \ T \ T the Value \ n-");
the printf (" ----------- -------------------------------------------------- ------------------- \ the n-");
printf ("Characteristics\t\t %08x\t Dword\t\t %08x\n", m_EDRva, pEDFA->Characteristics);
printf("TimeDateStamp\t\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD), pEDFA->TimeDateStamp);
printf("MajorVersion\t\t %08x\t Word\t\t %04x\n", m_EDRva + sizeof(DWORD)* 2, pEDFA->MajorVersion);
printf("MinorVersion\t\t %08x\t Word\t\t %04x\n", m_EDRva + sizeof(DWORD)* 2 + sizeof(WORD), pEDFA->MinorVersion);
printf("Name\t\t\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 2 + sizeof(WORD)* 2, pEDFA->Name);
printf("Base\t\t\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 3 + sizeof(WORD)* 2, pEDFA->Base);
printf("NumberOfFunctions\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 4 + sizeof(WORD)* 2, pEDFA->NumberOfFunctions);
printf("NumberOfNames\t\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 5 + sizeof(WORD)* 2, pEDFA->NumberOfNames);
printf("AddressOfFunctions\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 6 + sizeof(WORD)* 2, pEDFA->AddressOfFunctions);
printf("AddressOfNames\t\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 7 + sizeof(WORD)* 2, pEDFA->AddressOfNames);
printf("AddressOfNameOrdinals\t %08x\t Dword\t\t %08x\n", m_EDRva + sizeof(DWORD)* 8 + sizeof(WORD)* 2, pEDFA->AddressOfNameOrdinals);

DWORD addressFA = 0; // name of the function for receiving the RVA
char * addressName = NULL; // name of a function for outputting
for (DWORD EDcount = 0; EDcount <pEDFA-> NumberOfFunctions; EDcount ++) // number of not greater than derivation function derived values
{
DWORD pEDFA- EDB => Base + (* EDcount. 1); // number derived
DWORD EDAOF = pEDFA-> AddressOfFunctions + ( EDcount * sizeof (DWORD)); // address derivation function RVA
DWORD EDAON = pEDFA- > AddressOfNames + (EDcount * sizeof ( DWORD)); // the name of the derived function of rva rva
DWORD EDNB = pEDFA-> AddressOfNameOrdinals + (* EDcount the sizeof (WORD)); // number of functions exported name rva
addressFA = * (DWORD *) RVAtoFA (stMapFile- > YXImageBase, EDAON); // will store the function name of RVA RVA converted into a file address dereference function to get the name of RVA
addressName = (char *) (RVAtoFA (stMapFile-> YXImageBase, addressFA )); // function name and then converted into RVA address files, get file name
printf("Ordinals:%08x Functions RVA:%08x Name Ordinal:%08x Name RVA:%08X Name:%s\n\n", EDB, EDAOF, EDNB, EDAON, addressName);
}

/ * Relocation table * /
DWORD BR_RVA = p_oh-> the DataDirectory [. 5] .VirtualAddress; // relocation table RVA
DWORD BR_count = p_oh-> the DataDirectory [. 5] .Size; // relocation table size
printf ( "\ n relocation table offset address relative: 0x% 08x \ n ", p_oh-> DataDirectory [5 ] .VirtualAddress);
the printf (" the size of the relocation tables: 0x% 08x \ n ", p_oh-> DataDirectory [5 ] .Size);
IF (BR_RVA == 0)
{
the printf ( "this document does relocation table \ n-");
}
PIMAGE_BASE_RELOCATION the pBR; // address relocation table file
// not be greater than the current position of the relocation table RVA RVA last piece of data (the start position + size)
the while (BR_RVA <(p_oh-> the DataDirectory [. 5] + p_oh- .VirtualAddress> the DataDirectory [. 5] .Size))
{
the pBR = (PIMAGE_BASE_RELOCATION) (RVAtoFA (stMapFile-> YXImageBase, BR_RVA)); // get the current file block address
int BR_count = (pBR-> SizeOfBlock - 8) / 2; // the number of values required in the block relocation (first 8 bits of the block are the starting address and length)
the printf ( "the VirtualAddress:% 08x \ T SizeOfBlock:% 08x \ T ltems:% D \ n-", pBR-> the VirtualAddress, pBR-> SizeOfBlock, BR_count);
for (int NUM = 0; NUM <BR_count; NUM ++)
{
* = pBR_Chunk WORD (WORD *) RVAtoFA (stMapFile-> YXImageBase, BR_RVA + +. 8 the sizeof (WORD) * NUM);
IF (pBR_Chunk = 0!)
{
the printf ( "LTEM:% 04X \ T data relocation is required the RVA: 08x% \ n-", pBR_Chunk, (pBR_Chunk ^ 0x3000) + pBR-> the VirtualAddress);
/ * offset = relocatable addresses (2 bytes current value (required taken out by the file address) within a block of the current ^ 0x3000) + base address of the current block * /

}
}
printf("--------------------------------------------------------------\n");
BR_RVA = BR_RVA + pBR->SizeOfBlock;
}

}

 


MAP_FILE_STRUCT stMapFile = { nullptr, nullptr, nullptr };
int main()
{
LPTSTR filePath = TEXT("C:\\Users\\Admin\\Desktop\\kkk.dll");

if (LoadFile (filePath, & stMapFile )!) // load the contents of the file
{
return -1;
}


if // Check whether the file is a PE file (IsPEFile (stMapFile.YXImageBase)!)
{
UnLoadFile (& stMapFile);
return -1;
}

ShowFileHeaderInfo(&stMapFile);

UnLoadFile(&stMapFile);
system("pause");
}

 

 

 

Guess you like

Origin www.cnblogs.com/aaaguai/p/11780315.html