现在的位置: 首页 > 综合 > 正文

毕业时候写的一个PE解析小工具(MFC源码)

2013年12月02日 ⁄ 综合 ⁄ 共 29136字 ⁄ 字号 评论关闭

这么快就成了前年毕业的老家伙了。在整理硬盘里的代码和文档的时候翻出刚毕业时候写的一个小东西,想起来那时候在武汉的小河西村,暗无天日的租房里屌丝的写着程序的日子。一晃这么久了。还是混的这鸟样。悲伤逆流成河a..大哭

        还是上图说话吧。界面有些搓...大神们贱笑了。

代码地址  http://download.csdn.net/detail/witch_soya/4979587

貌似也没什么高深的技术性可言。仅仅是根据微软的Pe格式来解析exe文件而已。作为新手学习PE的一个参考吧。。

核心代码如下

/************************************************************************/
/*  此函数用来载入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();	
}

/************************************************************************/
/* ParsePe函数   用来加载各个字段到结构体中                             */
/************************************************************************/
void CPEToolDlg::ParsePE()
{	
	_wfopen_s(&pFile,m_strfilePathNeme.GetBuffer(0),L"r+");
	fread_s(&m_stMsDos.e_magic,sizeof(DWORD),sizeof(DWORD),1,pFile);
	if (m_stMsDos.e_magic != IMAGE_DOS_SIGNATURE)
	{
		MessageBox(L"不是有效的PE文件,因为emagic的值不为0x5A4D\n");
		return ;
	}

	
	//解析 IMAGE_NT_HEADERS
	ParseImageNTHeaders();
	
	//解析_IMAGE_OPTION_HEADERS32
	ParseImageOptionHeaders();	

	//解析节表
	ParseSectionHeder();
}

/************************************************************************/
/* 解析映像文件头                                                       */
/************************************************************************/
void CPEToolDlg::ParseImageNTHeaders()
{
	//文件偏移到3C处,获得e_lfanew的值 读取IMAGE_NT_HEADERS
	fseek(pFile,0x3c,SEEK_SET);
	fread_s(&m_stMsDos.e_lfanew,sizeof(DWORD),sizeof(DWORD),1,pFile);	
	if (m_stMsDos.e_lfanew == 0 )
	{
		MessageBox(L"获取IMAGE_NT_HEADERS的偏移位置失败!\n");
		return ;
	}
	fseek(pFile,m_stMsDos.e_lfanew,SEEK_SET);	
	fread(&m_stPeHeader,sizeof(stPE_HEADER),1,pFile);
	if (m_stPeHeader.Signature != IMAGE_NT_SIGNATURE)
	{
		MessageBox(L"不是有效的PE文件,因为Signature值不等于0x00004550(即是ASCII的'PE')");
		return;
	}

}
/************************************************************************/
/* 解析可选头                                                                     */
/************************************************************************/
void CPEToolDlg::ParseImageOptionHeaders()
{
	//读取IMAGE_OPTION_HEADER
	fread(&m_stExtPeHeader,sizeof(stPE_ExtHeader),1,pFile);
	//幻数(魔数)
	if (m_stExtPeHeader.Magic !=  IMAGE_NT_OPTIONAL_HDR32_MAGIC)
	{
		MessageBox(L"不是Win32PE文件,因为幻数不等于0x010b\n");
		return ;
	}

	//解析输入数据目录
	//输出表从PE头处偏移78h 输入表从PE头处偏移80h
	//偏移到输出表
	iLocation = m_stMsDos.e_lfanew;//PE头
	iLocation += 0x78;
	fseek(pFile,iLocation,SEEK_SET);
	//第一个IMAGE_DATA_DIRECTORY是输出表
	fread(&m_stExtPeHeader.DataDirectory[0].VirtualAddress,sizeof(DWORD),1,pFile); //输出表的RVA
	fread(&m_stExtPeHeader.DataDirectory[0].Size,sizeof(DWORD),1,pFile);//输出表大小

	//第二个IMAGE_DATA_DIRECTORY是输入表
	fread(&m_stExtPeHeader.DataDirectory[1].VirtualAddress,sizeof(DWORD),1,pFile); //输入表RVA
	fread(&m_stExtPeHeader.DataDirectory[1].Size,sizeof(DWORD),1,pFile);//输入表大小

	//第三个是ResourceDirectory
	fread(&m_stExtPeHeader.DataDirectory[2].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[2].Size,sizeof(DWORD),1,pFile);

	//第四个是ExceptionDirectory
	fread(&m_stExtPeHeader.DataDirectory[3].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[3].Size,sizeof(DWORD),1,pFile);

	//第五个是SecurityDirectory
	fread(&m_stExtPeHeader.DataDirectory[4].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[4].Size,sizeof(DWORD),1,pFile);

	//第六个是Base Relocation table
	fread(&m_stExtPeHeader.DataDirectory[5].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[5].Size,sizeof(DWORD),1,pFile);

	//第7个是DebugDirectory
	fread(&m_stExtPeHeader.DataDirectory[6].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[6].Size,sizeof(DWORD),1,pFile);

	//第8个是ArchitetureSpecificData
	fread(&m_stExtPeHeader.DataDirectory[7].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[7].Size,sizeof(DWORD),1,pFile);
	
	//第9个是GlobalPtr
	fread(&m_stExtPeHeader.DataDirectory[8].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[8].Size,sizeof(DWORD),1,pFile);

	//第10个是TLSDirectory
	fread(&m_stExtPeHeader.DataDirectory[9].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[9].Size,sizeof(DWORD),1,pFile);
	
	//第11个是LoadConfigationDirectory
	fread(&m_stExtPeHeader.DataDirectory[10].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[10].Size,sizeof(DWORD),1,pFile);

	//第12个是BoundImport
	fread(&m_stExtPeHeader.DataDirectory[11].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[11].Size,sizeof(DWORD),1,pFile);

	//第13个是ImportAddressTable
	fread(&m_stExtPeHeader.DataDirectory[12].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[12].Size,sizeof(DWORD),1,pFile);

	//第14个是DelayImportDescriptor
	fread(&m_stExtPeHeader.DataDirectory[13].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[13].Size,sizeof(DWORD),1,pFile);

	//第15个是CLIHeader
	fread(&m_stExtPeHeader.DataDirectory[14].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[14].Size,sizeof(DWORD),1,pFile);

	//第16个是Reserved
	fread(&m_stExtPeHeader.DataDirectory[15].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[15].Size,sizeof(DWORD),1,pFile);

}

void CPEToolDlg::ParseSectionHeder()
{
	//偏移到节表位置
	iLocation = m_stMsDos.e_lfanew + sizeof(stPE_HEADER) + m_stPeHeader.SizeOfOptionalHeader;//PE头+PE头的大小(IMAGE_FILE_HEADER)_+PE可选头的大小(IMAGE_OPTION_HEADER)
	fseek(pFile,iLocation,SEEK_SET);
	for (WORD i=0;i<m_stPeHeader.NumberOfSections;i++)
	{
		stSECTION_HEADER m_stSectionHeader;					
		fread(&m_stSectionHeader,sizeof(stSECTION_HEADER),1,pFile);
		vct_SectionHeader.push_back(m_stSectionHeader);

		iLocation+=sizeof(stSECTION_HEADER);
		fseek(pFile,iLocation,SEEK_SET);
		memset(&m_stSectionHeader,0,sizeof(stSECTION_HEADER));	
	}
}
void CPEToolDlg::OnBnClickedBTN_MZ_DOS()
{	
	//显示IMAGE_DOS_HEADER
	dlg1 = new Cdialog1;
	dlg1->Create(IDD_DIALOG1,this);
	dlg1->OnInitCtrlList();
	dlg1->ShowWindow(SW_SHOW);

	CString strE_Magic;
	strE_Magic.Format(L"0x%02x",m_stMsDos.e_magic);
	dlg1->AddToCtrlList(L"1.e_magic",strE_Magic,L"00h IMAGE_DOS_HEADER",L"magic number DOS头标记--IMAGE_DOS_HEADER结构第一个成员 偏移0x00h");
	
	CString strE_lfanew;
	strE_lfanew.Format(L"0x%04x",m_stMsDos.e_lfanew);
	dlg1->AddToCtrlList(L"2. e_lfanew",strE_lfanew,L"3ch IMAGE_DOS_HEADER",L"PE头的偏移地址--IMAGE_DOS_HEADER结构的最后一个成员 偏移0x3ch");	
	
}

void CPEToolDlg::OnBnClickedBTN_PEHEADER()
{
	//_IMAGE_NT_HEADER   SIGNATURE IMAGE_FILE_HEADER IMAGE_OPTION_HEADER
	dlg1 = new Cdialog1;
	dlg1->Create(IDD_DIALOG1,this);
	dlg1->OnInitCtrlList();
	dlg1->ShowWindow(SW_SHOW);
	
	CString strSignature;
	strSignature.Format(L"0x%08x",m_stPeHeader.Signature);
	dlg1->AddToCtrlList(L"00.Signature(dword)",strSignature,L"00h IMAGE_NT_HEADER",L"PE文件标识");

	CString strMachine;
	strMachine.Format(L"0x%04x",m_stPeHeader.Machine);
	dlg1->AddToCtrlList(L"01.Machine(word)",strMachine,L"04h IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"指定该PE运行的平台");

	CString strNumberofSections;
	strNumberofSections.Format(L"0x%04x",m_stPeHeader.NumberOfSections);
	dlg1->AddToCtrlList(L"02.NumberOfSections(word)",strNumberofSections,L"06h IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"PE文件中区块的数量");

	CString strTimeDateStamp;
	strTimeDateStamp.Format(L"0x%08x",m_stPeHeader.TimeDateStamp);
	dlg1->AddToCtrlList(L"03.TimeDateStamp(dword)",strTimeDateStamp,L"08h IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"文件日期时间戳,指定PE文件生成的时间 它的值是从1969年12月31日16:00:00以来的秒数");

	CString strPointerToSymbolTable;
	strPointerToSymbolTable.Format(L"0x%08x",m_stPeHeader.PointerToSymbolTable);
	dlg1->AddToCtrlList(L"04.PointerToSymbolTable(dword)",strPointerToSymbolTable,L"0ch IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"Coff调试符号表的偏移地址");

	CString strNumberOfSymbols;
	strNumberOfSymbols.Format(L"0x%08x",m_stPeHeader.NumberOfSymbols);
	dlg1->AddToCtrlList(L"05.NumberOfSymbols(dword)",strNumberOfSymbols,L"10h IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"Coff符号表中符号的个数. 这个域和前个域在release版本的程序里是0.");

	CString strSizeOfOptionalHeader;
	strSizeOfOptionalHeader.Format(L"0x%04x",m_stPeHeader.SizeOfOptionalHeader);
	dlg1->AddToCtrlList(L"06.SizeOfOptionalHeader(word)",strSizeOfOptionalHeader,L"14h IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"IMAGE_OPTIONAL_HEADER32结构的大小(即多少字节)");

	CString strCharacteristics;
	strCharacteristics.Format(L"0x%04x",m_stPeHeader.Characteristics);
	dlg1->AddToCtrlList(L"07.Characteristics(word)",strCharacteristics,L"16h IMAGE_NT_HEADER->IMAGE_FILE_HEADER",L"这个域描述pe文件的一些属性信息");

	//IMAGE_OPTION_HEADER	
	CString strMagic;
	strMagic.Format(L"0x%04x",m_stExtPeHeader.Magic);
	dlg1->AddToCtrlList(L"08.Magic(word)",strMagic,L"18h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"幻数,32位pe文件总为010bh");


	CString strMajorLinkerVersion;
	strMajorLinkerVersion.Format(L"0x%0x",m_stExtPeHeader.MajorLinkerVersion);
	dlg1->AddToCtrlList(L"09.MajorLinkerVersion(word)",strMajorLinkerVersion,L"1ah IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"连接器主版本号");

	CString strMinorLinkerVersion;
	strMinorLinkerVersion.Format(L"0x%0x",m_stExtPeHeader.MinorLinkerVersion);
	dlg1->AddToCtrlList(L"10.MinorLinkerVersion(word)",strMinorLinkerVersion,L"1bh IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"连接器副版本号");

	CString strSizeOfCode;
	strSizeOfCode.Format(L"0x%08x",m_stExtPeHeader.SizeOfCode);
	dlg1->AddToCtrlList(L"11.SizeOfCode(dword)",strSizeOfCode,L"1ch IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"代码段总大小");

	CString strSizeOfInitializedData;
	strSizeOfInitializedData.Format(L"0x%08x",m_stExtPeHeader.SizeOfInitializedData);
	dlg1->AddToCtrlList(L"12.SizeOfInitializedData(dword)",strSizeOfInitializedData,L"20h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"已初始化数据段总大小");

	CString strSizeOfUninitializedData;
	strSizeOfUninitializedData.Format(L"0x%08x",m_stExtPeHeader.SizeOfUninitializedData);
	dlg1->AddToCtrlList(L"13.SizeOfUninitializedData(dword)",strSizeOfUninitializedData,L"24h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"未初始化数据段总大小");

	CString strAddressOfEntryPoint;
	strAddressOfEntryPoint.Format(L"0x%08x",m_stExtPeHeader.AddressOfEntryPoint);
	dlg1->AddToCtrlList(L"14.AddressOfEntryPoint(dword)",strAddressOfEntryPoint,L"28h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"程序执行入口地址(RVA)  入口点");

	CString strBaseOfCode;
	strBaseOfCode.Format(L"0x%08x",m_stExtPeHeader.BaseOfCode);
	dlg1->AddToCtrlList(L"15.BaseOfCode(dword)",strBaseOfCode,L"2ch IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"代码段起始地址(RVA)");

	CString strBaseOfData;
	strBaseOfData.Format(L"0x%08x",m_stExtPeHeader.BaseOfData);
	dlg1->AddToCtrlList(L"16.BaseOfData(dword)",strBaseOfData,L"30h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"数据段起始地址(RVA)");

	// NT additional fields.
	CString strImageBase;
	strImageBase.Format(L"0x%08x",m_stExtPeHeader.ImageBase);
	dlg1->AddToCtrlList(L"17.ImageBase(dword)",strImageBase,L"34h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"程序默认的装入起始地址");

	CString strSectionAlignment;
	strSectionAlignment.Format(L"0x%08x",m_stExtPeHeader.SectionAlignment);
	dlg1->AddToCtrlList(L"18.SectionAlignment(dword)",strSectionAlignment,L"38h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"内存中区块的对齐单位");

	CString strFileAlignment;
	strFileAlignment.Format(L"0x%08x",m_stExtPeHeader.FileAlignment);
	dlg1->AddToCtrlList(L"19.FileAlignment(dword)",strFileAlignment,L"3ch IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"文件中区块的对齐单位");

	CString strMajorOperatingSystemVersion;
	strMajorOperatingSystemVersion.Format(L"0x%04x",m_stExtPeHeader.MajorOperatingSystemVersion);
	dlg1->AddToCtrlList(L"20.MajorOperatingSystemVersion(word)",strMajorOperatingSystemVersion,L"40h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"所需操作系统主版本号");

	CString strMinorOperatingSystemVersion;
	strMinorOperatingSystemVersion.Format(L"0x%04x",m_stExtPeHeader.MinorOperatingSystemVersion);
	dlg1->AddToCtrlList(L"21.MinorOperatingSystemVersion(word)",strMinorOperatingSystemVersion,L"42h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"所需操作系统副版本号");

	CString strMajorImageVersion;
	strMajorImageVersion.Format(L"0x%04x",m_stExtPeHeader.MajorImageVersion);
	dlg1->AddToCtrlList(L"22.MajorImageVersion(word)",strMajorImageVersion,L"44h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"自定义操作系统主版本号");

	CString strMinorImageVersion;
	strMinorImageVersion.Format(L"0x%04x",m_stExtPeHeader.MinorImageVersion);
	dlg1->AddToCtrlList(L"23.MinorImageVersion(word)",strMinorImageVersion,L"46h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"自定义操作系统副版本号");

	CString strMajorSubsystemVersion;
	strMajorSubsystemVersion.Format(L"0x%04x",m_stExtPeHeader.MajorSubsystemVersion);
	dlg1->AddToCtrlList(L"24.MajorSubsystemVersion(word)",strMajorSubsystemVersion,L"48h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"所需子操作系统主版本号");

	CString strMinorSubsystemVersion;
	strMinorSubsystemVersion.Format(L"0x%04x",m_stExtPeHeader.MinorSubsystemVersion);
	dlg1->AddToCtrlList(L"25.MinorSubsystemVersion(word)",strMinorSubsystemVersion,L"4ah IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"所需子操作系统副版本号");

	CString strWin32VersionValue;
	strWin32VersionValue.Format(L"0x%08x",m_stExtPeHeader.Win32VersionValue);
	dlg1->AddToCtrlList(L"26.Win32VersionValue(dword)",strWin32VersionValue,L"4ch IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"总是0");

	CString strSizeOfImage;
	strSizeOfImage.Format(L"0x%08x",m_stExtPeHeader.SizeOfImage);
	dlg1->AddToCtrlList(L"27.SizeOfImage(dword)",strSizeOfImage,L"50h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"pe文件在内存中的映像总大小");
	
	CString strSizeOfHeaders;
	strSizeOfHeaders.Format(L"0x%08x",m_stExtPeHeader.SizeOfHeaders);
	dlg1->AddToCtrlList(L"28.SizeOfHeaders(dword)",strSizeOfHeaders,L"54h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"pe文件开始到节表(包含节表)的总大小");

	CString strCheckSum;
	strCheckSum.Format(L"0x%08x",m_stExtPeHeader.CheckSum);
	dlg1->AddToCtrlList(L"29.CheckSum(dword)",strCheckSum,L"58h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"pe文件CRC校验和");

	CString strSubsystem;
	strSubsystem.Format(L"0x%04x",m_stExtPeHeader.Subsystem);
	dlg1->AddToCtrlList(L"30.Subsystem(word)",strSubsystem,L"5ch IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"用户界面使用的子系统类型");

	CString strDllCharacteristics;
	strDllCharacteristics.Format(L"0x%04x",m_stExtPeHeader.DllCharacteristics);
	dlg1->AddToCtrlList(L"31.DllCharacteristics(word)",strDllCharacteristics,L"5eh IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"总是0");

	CString strSizeOfStackReserve;
	strSizeOfStackReserve.Format(L"0x%08x",m_stExtPeHeader.SizeOfStackReserve);
	dlg1->AddToCtrlList(L"32.SizeOfStackReserve(dword)",strSizeOfStackReserve,L"60h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"为线程的栈初始保留的虚拟内存的默认值");

	CString strSizeOfStackCommit;
	strSizeOfStackCommit.Format(L"0x%08x",m_stExtPeHeader.SizeOfStackCommit);
	dlg1->AddToCtrlList(L"33.SizeOfStackCommit(dword)",strSizeOfStackCommit,L"64h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"为线程的栈初始提交的虚拟内存的大小");

	CString strSizeOfHeapReserve;
	strSizeOfHeapReserve.Format(L"0x%08x",m_stExtPeHeader.SizeOfHeapReserve);
	dlg1->AddToCtrlList(L"34.SizeOfHeapReserve(dword)",strSizeOfHeapReserve,L"68h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"为进程的堆保留的虚拟内存的大小");

	CString strSizeOfHeapCommit;
	strSizeOfHeapCommit.Format(L"0x%08x",m_stExtPeHeader.SizeOfHeapCommit);
	dlg1->AddToCtrlList(L"35.SizeOfHeapCommit(dword)",strSizeOfHeapCommit,L"6ch IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"为进程的堆初始提交的虚拟内存的大小");

	CString strLoaderFlags;
	strLoaderFlags.Format(L"0x%08x",m_stExtPeHeader.LoaderFlags);
	dlg1->AddToCtrlList(L"36.LoaderFlags(dword)",strLoaderFlags,L"70h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"总是0");

	CString strNumberOfRvaAndSizes;
	strNumberOfRvaAndSizes.Format(L"0x%08x",m_stExtPeHeader.NumberOfRvaAndSizes);
	dlg1->AddToCtrlList(L"37.NumberOfRvaAndSizes(dword)",strNumberOfRvaAndSizes,L"74h IMAGE_NT_HEADER->_IMAGE_OPTIONAL_HEADER",L"数据目录结构数组的项数,总为 00000010h");
}



/************************************************************************/
/* 解析节表                                                             */
/************************************************************************/
void CPEToolDlg::OnBnClickedBTN_SECTION()
{
	//查看节表
	dlgSection = new Cdialog1;
	dlgSection->Create(IDD_DIALOG1,this);	
	dlgSection->OnInitCtrlList();
	dlgSection->ShowWindow(SW_SHOW);	
	
	//读取_IMAGE_SECTION_HEADER 
	if (vct_SectionHeader.size() != 0)
	{
		for (UINT i=0;i<vct_SectionHeader.size();i++)
		{
			stSECTION_HEADER m_stSectionHeader = vct_SectionHeader.at(i);

			CString strNum("Section");
			CString strtmp;
			int iTmp = i;
			strtmp.Format(L"%d  ",++iTmp);
			strNum += strtmp;
			strtmp = L"                ";

			CString strName(m_stSectionHeader.Name);
			dlgSection->AddToCtrlList(strNum+L"01.Name",strName,L"SECTION_HEADER",L"节表名称");

			CString strPhysicalAddressOrVirtualSize;
			strPhysicalAddressOrVirtualSize.Format(L"0x%08x",m_stSectionHeader.Misc.VirtualSize);
			dlgSection->AddToCtrlList(strtmp+L"02.VirtualSize",strPhysicalAddressOrVirtualSize,L"SECTION_HEADER",L"obj文件中,区段的实际地址,exe和dll文件中区段在文件中对齐前的大小");

			CString strVirtualAddress;
			strVirtualAddress.Format(L"0x%08x",m_stSectionHeader.VirtualAddress);
			dlgSection->AddToCtrlList(strtmp+L"03,VirtualAddress",strVirtualAddress,L"SECTION_HEADER",L"块的RVA(相对虚拟地址)");

			CString strSizeOfRawData;
			strSizeOfRawData.Format(L"0x%08x",m_stSectionHeader.SizeOfRawData);
			dlgSection->AddToCtrlList(strtmp+L"04.SizeOfRawData",strSizeOfRawData,L"SECTION_HEADER",L"在文件中对齐后的大小");

			CString strPointerToRawData;;
			strPointerToRawData.Format(L"0x%08x",m_stSectionHeader.PointerToRawData);
			dlgSection->AddToCtrlList(strtmp+L"05.PointerToRawData",strPointerToRawData,L"SECTION_HEADER",L"在文件中的偏移");

			CString strPointerToRelocations;
			strPointerToRelocations.Format(L"0x%08x",m_stSectionHeader.PointerToRelocations);
			dlgSection->AddToCtrlList(strtmp+L"06.PointerToRelocations",strPointerToRelocations,L"SECTION_HEADER",L"重定位的偏移(obj文件中使用)");

			CString strPointerToLinenumbers;
			strPointerToLinenumbers.Format(L"0x%08x",m_stSectionHeader.PointerToLinenumbers);
			dlgSection->AddToCtrlList(strtmp+L"07.PointerToLinenumbers",strPointerToLinenumbers,L"SECTION_HEADER",L"行号表的偏移(调试用)");

			CString strNumberOfRelocations;
			strNumberOfRelocations.Format(L"0x%04x",m_stSectionHeader.NumberOfRelocations);
			dlgSection->AddToCtrlList(strtmp+L"08.NumberOfRelocations",strNumberOfRelocations,L"SECTION_HEADER",L"重定位项数目(obj文件中使用)");

			CString strNumberOfLinenumbers;
			strNumberOfLinenumbers.Format(L"0x%04x",m_stSectionHeader.NumberOfLinenumbers);
			dlgSection->AddToCtrlList(strtmp+L"09.NumberOfLinenumbers",strNumberOfLinenumbers,L"SECTION_HEADER",L"行号表中行号的数目");

			CString strCharacteristics;
			strCharacteristics.Format(L"0x%04x",m_stSectionHeader.Characteristics);
			dlgSection->AddToCtrlList(strtmp+L"10.Characteristics",strCharacteristics,L"SECTION_HEADER",L"块属性");
			
		}
	}
			
		


}

void CPEToolDlg::OnBnClickedBTN_DATADIC()
{
	//数据目录
	dlgDirectoryDate = new Cdialog1;
	dlgDirectoryDate->Create(IDD_DIALOG1,this);	
	dlgDirectoryDate->OnInitCtrlList();
	dlgDirectoryDate->ShowWindow(SW_SHOW);	
	//输出可选头里的数据目录IMAGE_DATA_DIRECTORY
	//1导出表
	CString strExportSymbol,strExportSymbolSize;
	strExportSymbol.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[0].VirtualAddress,m_stExtPeHeader.DataDirectory[0].VirtualAddress);
	strExportSymbolSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[0].Size,m_stExtPeHeader.DataDirectory[0].Size);
	dlgDirectoryDate->AddToCtrlList(L"01 .edata 导出表",L"偏移"+strExportSymbol,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strExportSymbolSize);

	//2导入表
	CString strImportSymbol,strImportSymbolSize;
	strExportSymbol.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[1].VirtualAddress,m_stExtPeHeader.DataDirectory[1].VirtualAddress);
	strImportSymbolSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[1].Size,m_stExtPeHeader.DataDirectory[1].Size);
	dlgDirectoryDate->AddToCtrlList(L"02 .idata 导入表",L"偏移"+strExportSymbol,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strImportSymbolSize);

	//3资源表
	CString strResource,strResourceSize;
	strResource.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[2].VirtualAddress,m_stExtPeHeader.DataDirectory[2].VirtualAddress);
	strResourceSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[2].Size,m_stExtPeHeader.DataDirectory[2].Size);
	dlgDirectoryDate->AddToCtrlList(L"03 .rsrc 资源表",L"偏移"+strResource,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strResourceSize);

	//4异常表
	CString strException,strExceptionSize;
	strException.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[3].VirtualAddress,m_stExtPeHeader.DataDirectory[3].VirtualAddress);
	strExceptionSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[3].Size,m_stExtPeHeader.DataDirectory[3].Size);
	dlgDirectoryDate->AddToCtrlList(L"04 .pdata 异常表",L"偏移"+strException,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strExceptionSize);

	//5属性证书表
	CString strSecurity,strSecuritySize;
	strSecurity.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[4].VirtualAddress,m_stExtPeHeader.DataDirectory[4].VirtualAddress);
	strSecuritySize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[4].Size,m_stExtPeHeader.DataDirectory[4].Size);
	dlgDirectoryDate->AddToCtrlList(L"05 .属性证书表",L"偏移"+strSecurity,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strSecuritySize);

	//6	基址重定位表
	CString strBaseReloation,strBaseReloationSize;
	strBaseReloation.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[5].VirtualAddress,m_stExtPeHeader.DataDirectory[5].VirtualAddress);
	strBaseReloationSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[5].Size,m_stExtPeHeader.DataDirectory[5].Size);
	dlgDirectoryDate->AddToCtrlList(L"06 .reloc 基址重定位表",L"偏移"+strBaseReloation,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strBaseReloationSize);

	//7	调试目录	
	CString strDebug,strDebugSize;
	strDebug.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[6].VirtualAddress,m_stExtPeHeader.DataDirectory[6].VirtualAddress);
	strSecuritySize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[6].Size,m_stExtPeHeader.DataDirectory[6].Size);
	dlgDirectoryDate->AddToCtrlList(L"07 .debug 调试目录",L"偏移"+strDebug,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strSecuritySize);

	//8 指定结构数据
	CString strArchitectureData,strArchitectureDataSize;
	strArchitectureData.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[7].VirtualAddress,m_stExtPeHeader.DataDirectory[7].VirtualAddress);
	strArchitectureDataSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[7].Size,m_stExtPeHeader.DataDirectory[7].Size);
	dlgDirectoryDate->AddToCtrlList(L"08.(保留必须为0)  指定结构数据",L"偏移"+strArchitectureData,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strArchitectureDataSize);

	//9 全局指针
	CString strGlobalPtr,strGlobalPtrSize;
	strGlobalPtr.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[8].VirtualAddress,m_stExtPeHeader.DataDirectory[8].VirtualAddress);
	strGlobalPtrSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[8].Size,m_stExtPeHeader.DataDirectory[8].Size);
	dlgDirectoryDate->AddToCtrlList(L"09 .全局指针",L"偏移"+strGlobalPtr,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strGlobalPtrSize);

	//10 TLS
	CString strTLS,strTLSsize;
	strTLS.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[9].VirtualAddress,m_stExtPeHeader.DataDirectory[9].VirtualAddress);
	strTLSsize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[9].Size,m_stExtPeHeader.DataDirectory[9].Size);
	dlgDirectoryDate->AddToCtrlList(L"10 .tls TLS",L"偏移"+strTLS,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strTLSsize);

	//11 加载配置
	CString strLoadConfig,strLoadConfigSize;
	strLoadConfig.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[10].VirtualAddress,m_stExtPeHeader.DataDirectory[10].VirtualAddress);
	strLoadConfigSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[10].Size,m_stExtPeHeader.DataDirectory[10].Size);
	dlgDirectoryDate->AddToCtrlList(L"11.加载配置",L"偏移"+strLoadConfig,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strLoadConfigSize);

	//12 绑定导入表
	CString strBound,strBoundsize;
	strBound.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[11].VirtualAddress,m_stExtPeHeader.DataDirectory[11].VirtualAddress);
	strBoundsize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[11].Size,m_stExtPeHeader.DataDirectory[11].Size);
	dlgDirectoryDate->AddToCtrlList(L"12.绑定导入表",L"偏移"+strBound,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strBoundsize);

	//13 引入表地址
	CString strImportTableAddress,strImportTableAddressSize;
	strImportTableAddress.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[12].VirtualAddress,m_stExtPeHeader.DataDirectory[12].VirtualAddress);
	strImportTableAddressSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[12].Size,m_stExtPeHeader.DataDirectory[12].Size);
	dlgDirectoryDate->AddToCtrlList(L"13 .引入表地址",L"偏移"+strImportTableAddress,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strImportTableAddressSize);

	//14 延迟导入描述符
	CString strDelayImportTable,strDelayImportTableSize;
	strDelayImportTable.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[13].VirtualAddress,m_stExtPeHeader.DataDirectory[13].VirtualAddress);
	strDelayImportTableSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[13].Size,m_stExtPeHeader.DataDirectory[13].Size);
	dlgDirectoryDate->AddToCtrlList(L"14 .延迟导入表描述符",L"偏移"+strDelayImportTable,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strDelayImportTableSize);
	
	//15 CLIheader
	CString strCLIheader,strCLIheaderSize;
	strCLIheader.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[14].VirtualAddress,m_stExtPeHeader.DataDirectory[14].VirtualAddress);
	strCLIheaderSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[14].Size,m_stExtPeHeader.DataDirectory[14].Size);
	dlgDirectoryDate->AddToCtrlList(L"15 .cormeta CLI HEADER",L"偏移"+strCLIheader,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strCLIheaderSize);

	//16 Reserved
	CString strReserved,strReservedSize;
	strReserved.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[15].VirtualAddress,m_stExtPeHeader.DataDirectory[15].VirtualAddress);
	strReservedSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[15].Size,m_stExtPeHeader.DataDirectory[15].Size);
	dlgDirectoryDate->AddToCtrlList(L"15.保留值",L"偏移"+strReserved,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strReservedSize);

}
/************************************************************************/
/*解析输入表 (导入表)                                                        */
/************************************************************************/
void CPEToolDlg::OnBnClickedBtnImporttable()
{
	//偏移到输入表的地址
	DWORD iImportTable_VAoffset = m_stExtPeHeader.DataDirectory[1].VirtualAddress;
	DWORD iImportTableSize = m_stExtPeHeader.DataDirectory[1].Size;	
	if (!iImportTable_VAoffset)
	{
		MessageBox(L"输入表为空!");
		return;		
	}
	//判断输出表是位于那一个节中	
	int iThe_Section;
	for( iThe_Section=0 ;iThe_Section<m_stPeHeader.NumberOfSections;iThe_Section++ )
	{
		if ( iImportTable_VAoffset >= vct_SectionHeader.at(iThe_Section).VirtualAddress 
			&& iImportTable_VAoffset < vct_SectionHeader.at(iThe_Section).SizeOfRawData + vct_SectionHeader.at(iThe_Section).VirtualAddress)
		{					
			break;
		}
	}
	
	//输入表
	dlgImportTbale = new Cdialog1;
	dlgImportTbale->Create(IDD_DIALOG1,this);	
	dlgImportTbale->OnInitCtrlList();
	dlgImportTbale->ShowWindow(SW_SHOW);	

	CString strTmpSectionName(L"输入表位于");
	CString strSectionName(vct_SectionHeader.at(iThe_Section).Name);
	strTmpSectionName += strSectionName;	
	dlgImportTbale->AddToCtrlList(strTmpSectionName+L"",L"",L"",L"");

	fseek(pFile,iImportTable_VAoffset,SEEK_SET);
	int iid_Count = iImportTableSize/sizeof(stIMAGE_IMPORT_DESCRIPTOR) ;//iid 的个数 也就是导入dll的个数
	for (int i=0;i<iid_Count;i++)
	{
		stIMAGE_IMPORT_DESCRIPTOR m_stImage_descriptor;
		fread(&m_stImage_descriptor,sizeof(stIMAGE_IMPORT_DESCRIPTOR),1,pFile);
		vct_ImportDescriptor.push_back(m_stImage_descriptor);
		
		int itmp = i;
		itmp++;
		CString strTmp;
		strTmp.Format(L"第%d个iid",itmp);
		dlgImportTbale->AddToCtrlList(strTmp,L"",L"",L"");

		CString strOriginalFirstThunk;
		strOriginalFirstThunk.Format(L"0x%08x/%ld(十进制)",m_stImage_descriptor.OriginalFirstThunk,m_stImage_descriptor.OriginalFirstThunk);
		dlgImportTbale->AddToCtrlList(L"OriginalFirstThunk",strOriginalFirstThunk,L"IMAGE_IMPORT_DESCRIPTOR",L"这个联合指向一个 IMAGE_THUNK_DATA 类型的结构数组");
		
		CString strTimeDateStamp;
		strTimeDateStamp.Format(L"0x%08x/%ld(十进制)",m_stImage_descriptor.TimeDateStamp,m_stImage_descriptor.TimeDateStamp);
		dlgImportTbale->AddToCtrlList(L"TimeDateStamp",strTimeDateStamp,L"IMAGE_IMPORT_DESCRIPTOR",L"该dll的时间日期戳,一般为0.");

		CString strForwarderChain;
		strForwarderChain.Format(L"0x%08x/%ld(十进制)",m_stImage_descriptor.ForwarderChain,m_stImage_descriptor.ForwarderChain);
		dlgImportTbale->AddToCtrlList(L"ForwarderChain",strForwarderChain,L"IMAGE_IMPORT_DESCRIPTOR",L"正向连接索引.一般为0.");

		CString strName;
		strName.Format(L"0x%08x/%ld(十进制)",m_stImage_descriptor.Name,m_stImage_descriptor.Name);
		//添加解析Dll名称的代码
		//保存当前文件指针位置
		fpos_t fPos_Cur;
		fgetpos(pFile,&fPos_Cur);
		//获取相对偏移
		DWORD dwDllNameRAV_Offset = m_stImage_descriptor.Name;
		//转换到文件偏移
		DWORD dwDllNameFile_Offset = RVAtoFileOffset(iThe_Section,dwDllNameRAV_Offset);
		//偏移到Dll名称位置
		fseek(pFile,dwDllNameFile_Offset,SEEK_SET);
		char szDllname[MAX_PATH] = {0};
		fread(&szDllname,MAX_PATH,1,pFile);
		CString strDllname(szDllname);
		//返回文件指针
		fseek(pFile,fPos_Cur,SEEK_SET);
		dlgImportTbale->AddToCtrlList(L"Name",strName,L"IMAGE_IMPORT_DESCRIPTOR",L"dll名字的RVA.DLL名称为:"+strDllname);
		

		CString strFirstThunk;
		strFirstThunk.Format(L"0x%08x/%ld(十进制)",m_stImage_descriptor.FirstThunk,m_stImage_descriptor.FirstThunk);
		dlgImportTbale->AddToCtrlList(L"FirstThunk",strFirstThunk,L"IMAGE_IMPORT_DESCRIPTOR",L"这个域也是一个RVA,指向一个DWORD数组,数组以NULL结束.数组中的每个DWORD实际上是一个IMAGE_THUNK_DATA结构的联合体。IMAGE_THUNK_DATA联合体通常被解释为一个指向IMAGE_IMPORT_BY_NAME结构的RVA.");
	}
}

DWORD CPEToolDlg :: RVAtoFileOffset(int iThe_Section,const DWORD& RVAOffset)
{
	DWORD dwFileOffset = 0;
	//传入的RavOffset先要转换成相对于节(比如.idata 或.text)的偏移RVA
	//第iThe_Section个节中
	DWORD dwVrk_TheSection = vct_SectionHeader.at(iThe_Section).VirtualAddress - vct_SectionHeader.at(iThe_Section).PointerToRawData;//虚拟地址和物理地址之间的差值
	dwFileOffset = RVAOffset - dwVrk_TheSection;
	return dwFileOffset;
}

抱歉!评论已关闭.