#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;
#define Print_Directory_Entry(name) \
cout<<#name<<endl; \
cout><< iNh->OptionalHeader.DataDirectory[name].size << endl; \
cout<<iNh->OptionalHeader.DataDirectory[name].VirtualAddress<<endl;
#define NewCharArray(n) \
cPtr = new char[sizeof(n)]; \
file.read(cPtr, sizeof(n));
int main(void)
{
IMAGE_DOS_HEADER* iDh = 0;
IMAGE_NT_HEADERS* iNh = 0;
ifstream file("C:\\Garena.exe", ios::in | ios::binary);
char* cPtr = NULL;
NewCharArray(IMAGE_DOS_HEADER);
iDh = (IMAGE_DOS_HEADER*)cPtr;
file.seekg(iDh->e_lfanew, ios::beg);
/***************************************/
/**************NT HEADER****************/
/***************************************/
NewCharArray(IMAGE_NT_HEADERS);
iNh = (IMAGE_NT_HEADERS*)cPtr;
cout<<"Number of section: " << iNh->FileHeader.NumberOfSections<<endl;
cout><<"Entry Point " << iNh->OptionalHeader.AddressOfEntryPoint<<endl;
cout><< iNh->OptionalHeader.NumberOfRvaAndsizes<<endl;
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_EXPORT);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_IMPORT);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_RESOURCE);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_EXCEPTION);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_SECURITY);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_BASERELOC);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_DEBUG);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_ARCHITECTURE);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_GLOBALPTR);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_TLS);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_IAT);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
Print_Directory_Entry(IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR);
IMAGE_SECTION_HEADER* iSh;
cPtr = new char[sizeof(IMAGE_SECTION_HEADER)*iNh->FileHeader.NumberOfSections];
file.read(cPtr, sizeof(IMAGE_SECTION_HEADER)*iNh->FileHeader.NumberOfSections);
iSh = (IMAGE_SECTION_HEADER*)cPtr;
for(int i = 0; i < iNh->FileHeader.NumberOfSections; i++)
{
cout<<iSh[i].Name><<endl;
cout<<hex><<iSh[i].VirtualAddress<<endl;
}
cout><<"Virtual Offset: " << hex<<iSh[1].VirtualAddress><<endl;
cout<<"Raw Offset: " <<hex><<iSh[1].PointerToRawData<<endl;
unsigned long delta = iSh[1].VirtualAddress - iSh[1].PointerToRawData;
unsigned long x = iNh->OptionalHeader.DataDirectory[0].VirtualAddress;
unsigned long y = iNh->OptionalHeader.DataDirectory[0].size;
file.seekg(x - delta, ios::beg);
cPtr = new char[y];
file.read(cPtr, y);
IMAGE_EXPORT_DIRECTORY* iEd = (IMAGE_EXPORT_DIRECTORY*)cPtr;
cout<<"Address of Name: "<<hex><<iEd->Name<<endl;
cout><<iEd->AddressOfNames - delta<<endl;
file.close();
return 0;
}
Có vẻ mọi thứ đều tốt nhưng cái lệnh cout cuối cùng thì tui nghĩ là gặp vấn đề. Vì nó xuất ra là 1EDC48, trong khi nếu coi dưới dạng Hex bằng một chương trình khác, như WinHex, TotalCommander, (ở đây tui xài FreeCommander) thì cái chỗ đúng phải là 1EDCFB. Tui có gởi hình, anh em có thể coi để hiểu ý tui.