WinPE基础知识之代码解析
- 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);
- }
- }
WinPE基础知识之代码解析的更多相关文章
- PHP基础知识测试题及解析
本试题共40道选择题,10道判断题,考试时间1个半小时 一:选择题(单项选择,每题2分): 1. LAMP具体结构不包含下面哪种(A ) A:Windows系统 B:Apache服务器 C:MyS ...
- WinPE基础知识之头部
1.DOS头 // DOS MZ头,大小为64个字节 typedef struct _IMAGE_DOS_HEADER { WORD e_magic; // EXE标志,“MZ”(有用,解析时作为是否 ...
- oracle 基础知识(九)----SQL解析
一,解析过程 二,硬解析,软解析,软软解析 01,硬解析 将SQL语句通过监听器发送到Oracle时, 会触发一个Server process生成,来对该客户进程服务.Server process得到 ...
- WinPE基础知识之重定位表
typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; // (重要)需要重定位的位置,这是一个RVA DWORD SizeOfBl ...
- WinPE基础知识之导入表
// 导入表 (结构体数组,以一个全零元素为结尾,每一个数组元素,代表一个PE文件导入信息) // 导入表存储的是从其它PE文件导入过来的函数名.序号,加载到内存之后,还存储这些函数的地址 typed ...
- WinPE基础知识之导出表
// 导出的东西包括函数(变量.类)地址,序号,函数(变量.类)名 typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; // ...
- Struts2入门1 Struts2基础知识
Struts2入门1 Struts2基础知识 20131130 代码下载: 链接: http://pan.baidu.com/s/11mYG1 密码: aua5 前言: 之前学习了Spring和Hib ...
- 浅析C++基础知识
近期想对C++的面试题目进行一下更加详细的整理.事实上认真思考一下C++程序猿的面试,我们能够发现对程序猿的能力的考察总是万变不离当中,这些基础知识主要分为五部分:一. C/C++基础知识 二. C/ ...
- [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写
一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...
随机推荐
- kotlin 之相等判断
在kotlin 中存在二种相等的判断: 1.引用相等 也就是说,两个引用指向同一个对象,使用===操作 ,相反操作为!==来判断 2.结构相等 使用equals 函数相等和==操作符 a?.equal ...
- Flask模拟实现CSRF攻击的方法
https://www.jb51.net/article/144371.htm https://www.cnblogs.com/888888CN/p/9489345.html http://xiaor ...
- android在点击EditText的时候始终不弹出软件键盘
场景描述:正常情况下,当点击EditText时,软键盘会弹出来.现在的要求是当点击EditText时,弹日期选择对话框,选择的结果显示在EditText上.若不处理,当点击EditText时,软键盘和 ...
- breadwinner-养家之人_20190220
" 在我们那里,人是最珍贵的.话要说的更有道理,而不是提高音量,毕竟滋养花朵的是雨水,而不是雷鸣“ ”我叫苏莱曼,我的爸爸是个教师,我的妈妈是个作家.有一天我在路上看到一个玩具,就把它捡起来 ...
- NuGet修改packages目录/迁移缓存文件夹
如图,以下是NuGet默认配置 打开C:\Program Files (x86)\NuGet\Config目录的Microsoft.VisualStudio.Offline.config可以看见如下配 ...
- 分组卷积+squeezenet+mobilenet+shufflenet的参数及运算量计算
来一发普通的二维卷积 1.输入feature map的格式为:m * m * h1 2.卷积核为 k * k 3.输出feature map的格式为: n * n * h2 参数量:k * k * h ...
- es6 map()和filter()详解【转】
原文地址:http://www.zhangxinxu.com/wordpress/2013/04/es5%e6%96%b0%e5%a2%9e%e6%95%b0%e7%bb%84%e6%96%b9%e6 ...
- 申请 Let's Encrypt 通配符 HTTPS 证书
目录 一.背景知识 1.1.什么是通配符证书 1.2.什么是 Let's Encrypt 二.证书申请(certbot) 2.1.系统确定 2.2.工具安装 2.3.证书申请 2.4.证书查看 2.5 ...
- Flutter打包release版本安卓apk包真机安装无法请求网络的解决方法
今天flutter build apk打包了一个release.apk包,在真机上安装后网络数据都不显示,但是在模拟器上没问题,然后又连接真机开debug各种测试,一切都正常!那这会是什么问题呢? 查 ...
- CVPapers - Computer Vision Resource
To add links (PDF, project,...) you can use the online tool. Computer Vision Paper Indexes ICCV: 20 ...