48h //所需子系统主版本号
WORD MinorSubsystemVersion;// 4ah //所需子系统副版本号
DWORD Win32VersionValue;// 4ch //总是0
DWORD SizeOfImage;// 50h //pe文件在内存中的映像总大小
DWORD SizeOfHeaders;// 54h //从pe文件开始到节表(包含节表)的总大小
DWORD CheckSum;// 58h //pe文件CRC校验和
WORD Subsystem;// 5ch //用户界面使用的子系统类型
WORD DllCharacteristics;// 5eh //为0
DWORD SizeOfStackReserve;// 60h //为线程的栈初始保留的虚拟内存的默认值
DWORD SizeOfStackCommit;// 64h //为线程的栈初始提交的虚拟内存的大小
DWORD SizeOfHeapReserve;// 68h //为进程的堆保留的虚拟内存的大小
DWORD SizeOfHeapCommit;// 6ch //为进程的堆初始提交的虚拟内存的大小
DWORD LoaderFlags; // 70h //为0
DWORD NumberOfRvaAndSizes;// 74h //数据目录结构数组的项数,总为 00000010h
IMAGE_DATA_DIRECTORY DataDirectory[16]; //78h
/*_IMAGE_OPTIONAL_HEADER结束*/
};
struct stSECTION_HEADER
{
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 00h 块名,8个字节长
union {
DWORD PhysicalAddress; // 08h obj文件中,区段的实际地址
DWORD VirtualSize; // exe和dll文件中区段在文件中对齐前的大小
} Misc;
DWORD VirtualAddress; // 0ch 块的RVA(相对虚拟地址)
DWORD SizeOfRawData; // 10h 在文件中对齐后的大小
DWORD PointerToRawData; // 14h 在文件中的偏移
DWORD PointerToRelocations; // 18h 重定位的偏移(obj文件中使用)
DWORD PointerToLinenumbers; // 1ch 行号表的偏移(调试用)
WORD NumberOfRelocations; // 1eh 重定位项数目(obj文件中使用)
WORD NumberOfLinenumbers; // 20h 行号表中行号的数目
DWORD Characteristics; // 24h 块属性
};
struct stIMAGE_IMPORT_DESCRIPTOR
{
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
DWORD ForwarderChain; // -1 if no forwarders
DWORD Name;
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} ;
struct stIMAGE_THUNK_DATA
{
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} ;
struct stIMAGE_IMPORT_BY_NAME
{
WORD Hint; //指出函数在所在的dll的输出表中的序号
BYTE Name[1]; //指出要输入的函数的函数名
};
#endif
看下PE解析的主要函数;
void CPEToolDlg::OnBnClickedBtnbrowse()
{
WCHAR szFilter[] =L"可执行文件|*.exe";
CFileDialog fileDlg(TRUE,L"exe",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
if (fileDlg.DoModal()==IDOK)
{
m_strfilePathNeme = fileDlg.GetPathName();
}
m_FilepathEdit.SetWindowText(m_strfilePathNeme);
m_FilepathEdit.SetReadOnly(TRUE);
if (m_strfilePathNeme == L"")
{
MessageBox(L"请选择可执行文件!");
return;
}
((CButton*)GetDlgItem(IDC_BTNDOSHEAD))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDC_BTNPEHEAD))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDC_BTNDIC))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDC_BTNSEC))->EnableWindow(TRUE);
((CButton*)GetDlgItem(IDC_BTN_IMPORTTABLE))->EnableWindow(TRUE);
//开始解析PE
ParsePE();
}
装载PE文件,开始解析;通常的VC++打开文件对话框,过滤器为*.exe;
void CPEToolDlg::ParsePE()
{
_wfopen_s(&pFile,m_strfilePathNeme.GetBu