博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WinPE基础知识之代码解析
阅读量:4450 次
发布时间:2019-06-07

本文共 7370 字,大约阅读时间需要 24 分钟。

void CMyPE::OnClickedButton1(){	// TODO:  在此添加控件通知处理程序代码	// 打开一个文件夹选择对话框	CFileDialog dlg(TRUE);	dlg.DoModal();	// 将文件路径显示到编辑框	CString path = dlg.GetFolderPath();	CString path1 = dlg.GetFileName();	m_Edit.SetWindowText(path + L"\\" + path1);	// 将PE文件读到缓冲区	HANDLE hFile = CreateFile(path + L"\\" + path1,		GENERIC_WRITE | GENERIC_READ,		FILE_SHARE_READ,		NULL,		OPEN_EXISTING,		FILE_ATTRIBUTE_NORMAL,		NULL);	if (hFile == (HANDLE)-1)	{		printf("文件不存在!\n");		return;	}	DWORD size = GetFileSize(hFile, NULL);	LPBYTE pBuff = new BYTE[size];	DWORD dwRead = 0;	ReadFile(hFile, pBuff, size, &dwRead, 0);	// 使用对应的结构体解析内存中的数据	IMAGE_DOS_HEADER* pDos = NULL;	pDos = (IMAGE_DOS_HEADER*)pBuff;	if (pDos->e_magic != IMAGE_DOS_SIGNATURE)	{		MessageBox(L"不是有效的PE格式!\n");		return;	}	// 找到NT头	IMAGE_NT_HEADERS* pNt = NULL;	pNt = (IMAGE_NT_HEADERS*)(pDos->e_lfanew + pBuff);	if (pNt->Signature != IMAGE_NT_SIGNATURE)	{		MessageBox(L"不是有效的PE格式!\n");		return;	}	// 找到文件头	IMAGE_FILE_HEADER pFile = pNt->FileHeader;	m_FileTree.DeleteAllItems();	// 添加区段数量	CString str1;	str1.Format(L"区段数量:%d", pFile.NumberOfSections);	m_FileTree.InsertItem(str1, NULL, TVI_LAST);	// 添加扩展头大小	CString str2;	str2.Format(L"扩展头大小:%d", pFile.SizeOfOptionalHeader);	m_FileTree.InsertItem(str2, NULL, TVI_LAST);	// 找到扩展头	IMAGE_OPTIONAL_HEADER pOptional = pNt->OptionalHeader;	m_OptTree.DeleteAllItems();	// OEP	CString str3;	str3.Format(L"OEP:%x", pOptional.AddressOfEntryPoint);	m_OptTree.InsertItem(str3, NULL, TVI_LAST);	// 镜像基址	CString str4;	str4.Format(L"镜像基址:%x", pOptional.ImageBase);	m_OptTree.InsertItem(str4, NULL, TVI_LAST);	// 块对齐数	CString str5;	str5.Format(L"块对齐数%x", pOptional.SectionAlignment);	m_OptTree.InsertItem(str5, NULL, TVI_LAST);	// 文件对齐数	CString str6;	str6.Format(L"文件对齐数:%x", pOptional.FileAlignment);	m_OptTree.InsertItem(str6, NULL, TVI_LAST);	// 内存大小	CString str7;	str7.Format(L"内存大小:%x", pOptional.SizeOfImage);	m_OptTree.InsertItem(str7, NULL, TVI_LAST);	// 找到数据目录表	m_List3.DeleteAllItems();	PIMAGE_DATA_DIRECTORY dData = pOptional.DataDirectory;	DWORD dwIndex2 = 0;	for (DWORD i = 0; i < pOptional.NumberOfRvaAndSizes; i++)	{		// 先插入一个item 到列表		m_List3.InsertItem(dwIndex2, L"");		CString str8;		str8.Format(L"%x", dData[i].VirtualAddress);		m_List3.SetItemText(dwIndex2, 0, str8);		CString str9;		str9.Format(L"%x", dData[i].Size);		m_List3.SetItemText(dwIndex2, 1, str9);		dwIndex2++;	}	// 区段表	// 使用宏来找到区段头数组的首地址	// 首地址 = NT头的首地址 + NT头的总字节数	IMAGE_SECTION_HEADER* pScnHdr = NULL;	// 使用宏来找到区段头数组的首地址	pScnHdr = IMAGE_FIRST_SECTION(pNt);	// 得到区段头的个数	DWORD scnHdrCount = pNt->FileHeader.NumberOfSections;	m_SCNTree.DeleteAllItems();	for (DWORD i = 0; i < scnHdrCount; i++)	{		HTREEITEM hItem;		CStringW str10(pScnHdr[i].Name);		hItem = m_SCNTree.InsertItem(L"区段名称:" + str10, NULL, TVI_LAST);				CString str11;		str11.Format(L"区段大小:%x", pScnHdr[i].Misc.VirtualSize);		m_SCNTree.InsertItem(str11, hItem);		CString str12;		str12.Format(L"RVA:%x", pScnHdr[i].VirtualAddress);		m_SCNTree.InsertItem(str12, hItem);		CString str13;		str13.Format(L"文件大小:%x", pScnHdr[i].SizeOfRawData);		m_SCNTree.InsertItem(str13, hItem);		CString str14;		str14.Format(L"文件偏移:%x", pScnHdr[i].PointerToRawData);		m_SCNTree.InsertItem(str14, hItem);	}	/*导入表*/	// 1:获取导入表的首地址	DWORD dwImpTabRva = pNt->OptionalHeader.DataDirectory[1].VirtualAddress;	// 将RVA转换为FOA	DWORD dwImpTabFoa = rva2foa(pNt, dwImpTabRva);	// 得到导入表数组的首地址	IMAGE_IMPORT_DESCRIPTOR* pImp =		(IMAGE_IMPORT_DESCRIPTOR*)(dwImpTabFoa + pBuff);	// 2:遍历导入表数组,数组以0结尾	m_ImportTree.DeleteAllItems();	while (pImp->Name != 0)	{		// 3:在遍历出每一个导入表后,遍历它的INT或者IAT		// 3.1 获取导入表DLL的名字		DWORD dwNameFoa = rva2foa(pNt, pImp->Name);		char* pDllName = (char*)(dwNameFoa + pBuff);		HTREEITEM hItem;		CStringW str15(pDllName);		hItem = m_ImportTree.InsertItem(L"模块名称:" + str15, NULL, TVI_LAST);		// 3,2 从INT中得到所有的导入函数的名字/序号		IMAGE_THUNK_DATA* pInt = 0;		DWORD dwIntFoa = rva2foa(pNt, pImp->OriginalFirstThunk);		pInt = (IMAGE_THUNK_DATA*)(dwIntFoa + pBuff);		while (pInt->u1.Function != 0)		{			// 判断导入的方式:序号导入还是名称导入			if (IMAGE_SNAP_BY_ORDINAL(pInt->u1.Ordinal))			{				CString str16;				str16.Format(L"函数序号:%x", pInt->u1.Ordinal & 0xFFFF);				m_ImportTree.InsertItem(str16, hItem);			}			else			{				IMAGE_IMPORT_BY_NAME* pImpName = 0;				DWORD dwNameFoa1 = rva2foa(pNt, pInt->u1.AddressOfData);				pImpName = (IMAGE_IMPORT_BY_NAME*)(dwNameFoa1 + pBuff);				CString str17(pImpName->Name);				m_ImportTree.InsertItem(L"函数名称:" + str17, hItem);			}			++pInt;		}		++pImp;	}	/*导出表*/	// 获取导出表首地址	DWORD dwExpTabFoa = rva2foa(pNt, pNt->OptionalHeader.DataDirectory[0].VirtualAddress);	m_ExportTree.DeleteAllItems();	if (pNt->OptionalHeader.DataDirectory[0].VirtualAddress)	{		// 定位到导出表结构		IMAGE_EXPORT_DIRECTORY* pExpTab =			(IMAGE_EXPORT_DIRECTORY*)(dwExpTabFoa + pBuff);		// 定位函数名称表		DWORD* pENT = (DWORD*)(rva2foa(pNt, pExpTab->AddressOfNames) + pBuff);		// 定位函数序号表		WORD* pEOT = (WORD*)(rva2foa(pNt, pExpTab->AddressOfNameOrdinals) + pBuff);		for (DWORD i = 0; i < pExpTab->NumberOfNames; i++)		{			char* pName = (char*)(rva2foa(pNt, pENT[i]) + pBuff);			HTREEITEM hItem;			CString str19;			str19.Format(L"函数序号:%d", pEOT[i]);			hItem = m_ExportTree.InsertItem(str19, NULL, TVI_LAST);			CString str18(pName);			m_ExportTree.InsertItem(L"函数名称:" + str18, hItem);		}	}	/*资源表*/	// 定位到第一层目录结构	m_CtrlTree.DeleteAllItems();	if (pNt->OptionalHeader.DataDirectory[2].VirtualAddress)	{		IMAGE_RESOURCE_DIRECTORY* pResDir = NULL;		DWORD dwResTabRva = pNt->OptionalHeader.DataDirectory[2].VirtualAddress;		DWORD dwResTabFoa = rva2foa(pNt, dwResTabRva);		pResDir = (IMAGE_RESOURCE_DIRECTORY*)(dwResTabFoa + pBuff);		parseResources((LPBYTE)pResDir, pResDir, m_CtrlTree, 1);	}	/*重定位表*/	// 定位到重定位快的首地址	m_ReTree.DeleteAllItems();	if (pNt->OptionalHeader.DataDirectory[5].VirtualAddress)	{		DWORD dwRelTabRva = pNt->OptionalHeader.DataDirectory[5].VirtualAddress;		DWORD dwRelTabFoa = rva2foa(pNt, dwRelTabRva);		IMAGE_BASE_RELOCATION* pRelTab =			(IMAGE_BASE_RELOCATION*)(dwRelTabFoa + pBuff);		while (pRelTab->SizeOfBlock != 0)		{			TypeOffset* pTypeOffset = NULL;			pTypeOffset = (TypeOffset*)(pRelTab + 1);			DWORD dwCount = (pRelTab->SizeOfBlock - 8) / 2;			CString str30;			str30.Format(L"区段RVA:%x", pRelTab->VirtualAddress);			HTREEITEM hItem;			hItem = m_ReTree.InsertItem(str30, NULL, TVI_LAST);			for (DWORD i = 0; i < dwCount; ++i)			{				CString str31;				str31.Format(L"属性:%x", pTypeOffset[i].Type);				m_ReTree.InsertItem(str31, hItem);				CString str32;				str32.Format(L"偏移:%x", pTypeOffset[i].Offset);				m_ReTree.InsertItem(str32, hItem);			}			// 得到下一个重定位快的首地址			pRelTab = (IMAGE_BASE_RELOCATION*)((LPBYTE)pRelTab + pRelTab->SizeOfBlock);		}	}	/*TLS表*/	// 定位到TLS的首地址	m_TLSTree.DeleteAllItems();	if (pNt->OptionalHeader.DataDirectory[9].VirtualAddress)	{		DWORD dwTLSTabRva = pNt->OptionalHeader.DataDirectory[9].VirtualAddress;		DWORD dwTLSTabFoa = rva2foa(pNt, dwTLSTabRva);		IMAGE_TLS_DIRECTORY* pTLSTab =			(IMAGE_TLS_DIRECTORY*)(dwTLSTabFoa + pBuff);		CString str33;		str33.Format(L"数据块开始VA:%x", pTLSTab->StartAddressOfRawData);		m_TLSTree.InsertItem(str33, NULL, TVI_LAST);		CString str34;		str34.Format(L"数据块结束VA:%x", pTLSTab->EndAddressOfRawData);		m_TLSTree.InsertItem(str34, NULL, TVI_LAST);		CString str35;		str35.Format(L"回调表VA:%x", pTLSTab->AddressOfCallBacks);		m_TLSTree.InsertItem(str35, NULL, TVI_LAST);	}}

  

转载于:https://www.cnblogs.com/duxie/p/10857796.html

你可能感兴趣的文章
ASP.NET Session详解(转)
查看>>
[POJ1007]DNA Sorting
查看>>
Java读取文件
查看>>
物件识别与距离测量系统
查看>>
结对博客
查看>>
我在城市快节奏中的慢生活
查看>>
B1232 [Usaco2008Nov]安慰奶牛cheer 最小生成树
查看>>
使用 git push 出现error setting certificate verify locations问题记录
查看>>
真没想到VB也可以这样用之指针技术 --不详,向作者致敬  ,转
查看>>
2、在1.VMware虚拟机上安装ubantu系统
查看>>
vue
查看>>
用 eric6 与 PyQt5 实现python的极速GUI编程(系列01)--Hello world!
查看>>
java--线程的睡眠sleep()
查看>>
Python3.x:定时获取页面数据存入数据库
查看>>
洛谷 P1290 欧几里德的游戏 题解
查看>>
python 归纳 (十三)_队列Queue在多线程中使用
查看>>
idea管理tomcat
查看>>
System.Activator类
查看>>
ssis包
查看>>
Python的静态方法和类成员方法 分类: python基础学习 ...
查看>>