1. void CMyPE::OnClickedButton1()
  2. {
  3. // TODO: 在此添加控件通知处理程序代码
  4.  
  5. // 打开一个文件夹选择对话框
  6. CFileDialog dlg(TRUE);
  7. dlg.DoModal();
  8. // 将文件路径显示到编辑框
  9. CString path = dlg.GetFolderPath();
  10. CString path1 = dlg.GetFileName();
  11. m_Edit.SetWindowText(path + L"\\" + path1);
  12.  
  13. // 将PE文件读到缓冲区
  14. HANDLE hFile = CreateFile(path + L"\\" + path1,
  15. GENERIC_WRITE | GENERIC_READ,
  16. FILE_SHARE_READ,
  17. NULL,
  18. OPEN_EXISTING,
  19. FILE_ATTRIBUTE_NORMAL,
  20. NULL);
  21. if (hFile == (HANDLE)-1)
  22. {
  23. printf("文件不存在!\n");
  24. return;
  25. }
  26. DWORD size = GetFileSize(hFile, NULL);
  27. LPBYTE pBuff = new BYTE[size];
  28. DWORD dwRead = 0;
  29. ReadFile(hFile, pBuff, size, &dwRead, 0);
  30.  
  31. // 使用对应的结构体解析内存中的数据
  32. IMAGE_DOS_HEADER* pDos = NULL;
  33. pDos = (IMAGE_DOS_HEADER*)pBuff;
  34. if (pDos->e_magic != IMAGE_DOS_SIGNATURE)
  35. {
  36. MessageBox(L"不是有效的PE格式!\n");
  37. return;
  38. }
  39. // 找到NT头
  40. IMAGE_NT_HEADERS* pNt = NULL;
  41. pNt = (IMAGE_NT_HEADERS*)(pDos->e_lfanew + pBuff);
  42. if (pNt->Signature != IMAGE_NT_SIGNATURE)
  43. {
  44. MessageBox(L"不是有效的PE格式!\n");
  45. return;
  46. }
  47. // 找到文件头
  48. IMAGE_FILE_HEADER pFile = pNt->FileHeader;
  49. m_FileTree.DeleteAllItems();
  50. // 添加区段数量
  51. CString str1;
  52. str1.Format(L"区段数量:%d", pFile.NumberOfSections);
  53. m_FileTree.InsertItem(str1, NULL, TVI_LAST);
  54. // 添加扩展头大小
  55. CString str2;
  56. str2.Format(L"扩展头大小:%d", pFile.SizeOfOptionalHeader);
  57. m_FileTree.InsertItem(str2, NULL, TVI_LAST);
  58.  
  59. // 找到扩展头
  60. IMAGE_OPTIONAL_HEADER pOptional = pNt->OptionalHeader;
  61. m_OptTree.DeleteAllItems();
  62. // OEP
  63. CString str3;
  64. str3.Format(L"OEP:%x", pOptional.AddressOfEntryPoint);
  65. m_OptTree.InsertItem(str3, NULL, TVI_LAST);
  66. // 镜像基址
  67. CString str4;
  68. str4.Format(L"镜像基址:%x", pOptional.ImageBase);
  69. m_OptTree.InsertItem(str4, NULL, TVI_LAST);
  70. // 块对齐数
  71. CString str5;
  72. str5.Format(L"块对齐数%x", pOptional.SectionAlignment);
  73. m_OptTree.InsertItem(str5, NULL, TVI_LAST);
  74. // 文件对齐数
  75. CString str6;
  76. str6.Format(L"文件对齐数:%x", pOptional.FileAlignment);
  77. m_OptTree.InsertItem(str6, NULL, TVI_LAST);
  78. // 内存大小
  79. CString str7;
  80. str7.Format(L"内存大小:%x", pOptional.SizeOfImage);
  81. m_OptTree.InsertItem(str7, NULL, TVI_LAST);
  82.  
  83. // 找到数据目录表
  84. m_List3.DeleteAllItems();
  85. PIMAGE_DATA_DIRECTORY dData = pOptional.DataDirectory;
  86. DWORD dwIndex2 = 0;
  87. for (DWORD i = 0; i < pOptional.NumberOfRvaAndSizes; i++)
  88. {
  89. // 先插入一个item 到列表
  90. m_List3.InsertItem(dwIndex2, L"");
  91. CString str8;
  92. str8.Format(L"%x", dData[i].VirtualAddress);
  93. m_List3.SetItemText(dwIndex2, 0, str8);
  94. CString str9;
  95. str9.Format(L"%x", dData[i].Size);
  96. m_List3.SetItemText(dwIndex2, 1, str9);
  97. dwIndex2++;
  98. }
  99.  
  100. // 区段表
  101. // 使用宏来找到区段头数组的首地址
  102. // 首地址 = NT头的首地址 + NT头的总字节数
  103. IMAGE_SECTION_HEADER* pScnHdr = NULL;
  104. // 使用宏来找到区段头数组的首地址
  105. pScnHdr = IMAGE_FIRST_SECTION(pNt);
  106. // 得到区段头的个数
  107. DWORD scnHdrCount = pNt->FileHeader.NumberOfSections;
  108. m_SCNTree.DeleteAllItems();
  109. for (DWORD i = 0; i < scnHdrCount; i++)
  110. {
  111. HTREEITEM hItem;
  112. CStringW str10(pScnHdr[i].Name);
  113. hItem = m_SCNTree.InsertItem(L"区段名称:" + str10, NULL, TVI_LAST);
  114.  
  115. CString str11;
  116. str11.Format(L"区段大小:%x", pScnHdr[i].Misc.VirtualSize);
  117. m_SCNTree.InsertItem(str11, hItem);
  118.  
  119. CString str12;
  120. str12.Format(L"RVA:%x", pScnHdr[i].VirtualAddress);
  121. m_SCNTree.InsertItem(str12, hItem);
  122.  
  123. CString str13;
  124. str13.Format(L"文件大小:%x", pScnHdr[i].SizeOfRawData);
  125. m_SCNTree.InsertItem(str13, hItem);
  126.  
  127. CString str14;
  128. str14.Format(L"文件偏移:%x", pScnHdr[i].PointerToRawData);
  129. m_SCNTree.InsertItem(str14, hItem);
  130. }
  131.  
  132. /*导入表*/
  133. // 1:获取导入表的首地址
  134. DWORD dwImpTabRva = pNt->OptionalHeader.DataDirectory[1].VirtualAddress;
  135. // 将RVA转换为FOA
  136. DWORD dwImpTabFoa = rva2foa(pNt, dwImpTabRva);
  137. // 得到导入表数组的首地址
  138. IMAGE_IMPORT_DESCRIPTOR* pImp =
  139. (IMAGE_IMPORT_DESCRIPTOR*)(dwImpTabFoa + pBuff);
  140. // 2:遍历导入表数组,数组以0结尾
  141. m_ImportTree.DeleteAllItems();
  142. while (pImp->Name != 0)
  143. {
  144. // 3:在遍历出每一个导入表后,遍历它的INT或者IAT
  145. // 3.1 获取导入表DLL的名字
  146. DWORD dwNameFoa = rva2foa(pNt, pImp->Name);
  147. char* pDllName = (char*)(dwNameFoa + pBuff);
  148. HTREEITEM hItem;
  149. CStringW str15(pDllName);
  150. hItem = m_ImportTree.InsertItem(L"模块名称:" + str15, NULL, TVI_LAST);
  151. // 3,2 从INT中得到所有的导入函数的名字/序号
  152. IMAGE_THUNK_DATA* pInt = 0;
  153. DWORD dwIntFoa = rva2foa(pNt, pImp->OriginalFirstThunk);
  154. pInt = (IMAGE_THUNK_DATA*)(dwIntFoa + pBuff);
  155.  
  156. while (pInt->u1.Function != 0)
  157. {
  158. // 判断导入的方式:序号导入还是名称导入
  159. if (IMAGE_SNAP_BY_ORDINAL(pInt->u1.Ordinal))
  160. {
  161. CString str16;
  162. str16.Format(L"函数序号:%x", pInt->u1.Ordinal & 0xFFFF);
  163. m_ImportTree.InsertItem(str16, hItem);
  164. }
  165. else
  166. {
  167. IMAGE_IMPORT_BY_NAME* pImpName = 0;
  168. DWORD dwNameFoa1 = rva2foa(pNt, pInt->u1.AddressOfData);
  169. pImpName = (IMAGE_IMPORT_BY_NAME*)(dwNameFoa1 + pBuff);
  170. CString str17(pImpName->Name);
  171. m_ImportTree.InsertItem(L"函数名称:" + str17, hItem);
  172. }
  173. ++pInt;
  174. }
  175. ++pImp;
  176. }
  177.  
  178. /*导出表*/
  179. // 获取导出表首地址
  180. DWORD dwExpTabFoa = rva2foa(pNt, pNt->OptionalHeader.DataDirectory[0].VirtualAddress);
  181. m_ExportTree.DeleteAllItems();
  182. if (pNt->OptionalHeader.DataDirectory[0].VirtualAddress)
  183. {
  184. // 定位到导出表结构
  185. IMAGE_EXPORT_DIRECTORY* pExpTab =
  186. (IMAGE_EXPORT_DIRECTORY*)(dwExpTabFoa + pBuff);
  187. // 定位函数名称表
  188. DWORD* pENT = (DWORD*)(rva2foa(pNt, pExpTab->AddressOfNames) + pBuff);
  189. // 定位函数序号表
  190. WORD* pEOT = (WORD*)(rva2foa(pNt, pExpTab->AddressOfNameOrdinals) + pBuff);
  191. for (DWORD i = 0; i < pExpTab->NumberOfNames; i++)
  192. {
  193. char* pName = (char*)(rva2foa(pNt, pENT[i]) + pBuff);
  194. HTREEITEM hItem;
  195. CString str19;
  196. str19.Format(L"函数序号:%d", pEOT[i]);
  197. hItem = m_ExportTree.InsertItem(str19, NULL, TVI_LAST);
  198. CString str18(pName);
  199. m_ExportTree.InsertItem(L"函数名称:" + str18, hItem);
  200. }
  201. }
  202.  
  203. /*资源表*/
  204. // 定位到第一层目录结构
  205. m_CtrlTree.DeleteAllItems();
  206. if (pNt->OptionalHeader.DataDirectory[2].VirtualAddress)
  207. {
  208. IMAGE_RESOURCE_DIRECTORY* pResDir = NULL;
  209. DWORD dwResTabRva = pNt->OptionalHeader.DataDirectory[2].VirtualAddress;
  210. DWORD dwResTabFoa = rva2foa(pNt, dwResTabRva);
  211. pResDir = (IMAGE_RESOURCE_DIRECTORY*)(dwResTabFoa + pBuff);
  212. parseResources((LPBYTE)pResDir, pResDir, m_CtrlTree, 1);
  213. }
  214.  
  215. /*重定位表*/
  216. // 定位到重定位快的首地址
  217. m_ReTree.DeleteAllItems();
  218. if (pNt->OptionalHeader.DataDirectory[5].VirtualAddress)
  219. {
  220. DWORD dwRelTabRva = pNt->OptionalHeader.DataDirectory[5].VirtualAddress;
  221. DWORD dwRelTabFoa = rva2foa(pNt, dwRelTabRva);
  222. IMAGE_BASE_RELOCATION* pRelTab =
  223. (IMAGE_BASE_RELOCATION*)(dwRelTabFoa + pBuff);
  224. while (pRelTab->SizeOfBlock != 0)
  225. {
  226. TypeOffset* pTypeOffset = NULL;
  227. pTypeOffset = (TypeOffset*)(pRelTab + 1);
  228. DWORD dwCount = (pRelTab->SizeOfBlock - 8) / 2;
  229. CString str30;
  230. str30.Format(L"区段RVA:%x", pRelTab->VirtualAddress);
  231. HTREEITEM hItem;
  232. hItem = m_ReTree.InsertItem(str30, NULL, TVI_LAST);
  233. for (DWORD i = 0; i < dwCount; ++i)
  234. {
  235. CString str31;
  236. str31.Format(L"属性:%x", pTypeOffset[i].Type);
  237. m_ReTree.InsertItem(str31, hItem);
  238. CString str32;
  239. str32.Format(L"偏移:%x", pTypeOffset[i].Offset);
  240. m_ReTree.InsertItem(str32, hItem);
  241. }
  242. // 得到下一个重定位快的首地址
  243. pRelTab = (IMAGE_BASE_RELOCATION*)((LPBYTE)pRelTab + pRelTab->SizeOfBlock);
  244.  
  245. }
  246. }
  247.  
  248. /*TLS表*/
  249. // 定位到TLS的首地址
  250. m_TLSTree.DeleteAllItems();
  251. if (pNt->OptionalHeader.DataDirectory[9].VirtualAddress)
  252. {
  253. DWORD dwTLSTabRva = pNt->OptionalHeader.DataDirectory[9].VirtualAddress;
  254. DWORD dwTLSTabFoa = rva2foa(pNt, dwTLSTabRva);
  255. IMAGE_TLS_DIRECTORY* pTLSTab =
  256. (IMAGE_TLS_DIRECTORY*)(dwTLSTabFoa + pBuff);
  257. CString str33;
  258. str33.Format(L"数据块开始VA:%x", pTLSTab->StartAddressOfRawData);
  259. m_TLSTree.InsertItem(str33, NULL, TVI_LAST);
  260. CString str34;
  261. str34.Format(L"数据块结束VA:%x", pTLSTab->EndAddressOfRawData);
  262. m_TLSTree.InsertItem(str34, NULL, TVI_LAST);
  263. CString str35;
  264. str35.Format(L"回调表VA:%x", pTLSTab->AddressOfCallBacks);
  265. m_TLSTree.InsertItem(str35, NULL, TVI_LAST);
  266. }
  267. }

  

WinPE基础知识之代码解析的更多相关文章

  1. PHP基础知识测试题及解析

      本试题共40道选择题,10道判断题,考试时间1个半小时 一:选择题(单项选择,每题2分): 1. LAMP具体结构不包含下面哪种(A ) A:Windows系统 B:Apache服务器 C:MyS ...

  2. WinPE基础知识之头部

    1.DOS头 // DOS MZ头,大小为64个字节 typedef struct _IMAGE_DOS_HEADER { WORD e_magic; // EXE标志,“MZ”(有用,解析时作为是否 ...

  3. oracle 基础知识(九)----SQL解析

    一,解析过程 二,硬解析,软解析,软软解析 01,硬解析 将SQL语句通过监听器发送到Oracle时, 会触发一个Server process生成,来对该客户进程服务.Server process得到 ...

  4. WinPE基础知识之重定位表

    typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; // (重要)需要重定位的位置,这是一个RVA DWORD SizeOfBl ...

  5. WinPE基础知识之导入表

    // 导入表 (结构体数组,以一个全零元素为结尾,每一个数组元素,代表一个PE文件导入信息) // 导入表存储的是从其它PE文件导入过来的函数名.序号,加载到内存之后,还存储这些函数的地址 typed ...

  6. WinPE基础知识之导出表

    // 导出的东西包括函数(变量.类)地址,序号,函数(变量.类)名 typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; // ...

  7. Struts2入门1 Struts2基础知识

    Struts2入门1 Struts2基础知识 20131130 代码下载: 链接: http://pan.baidu.com/s/11mYG1 密码: aua5 前言: 之前学习了Spring和Hib ...

  8. 浅析C++基础知识

    近期想对C++的面试题目进行一下更加详细的整理.事实上认真思考一下C++程序猿的面试,我们能够发现对程序猿的能力的考察总是万变不离当中,这些基础知识主要分为五部分:一. C/C++基础知识 二. C/ ...

  9. [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写

     一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...

随机推荐

  1. kotlin 之相等判断

    在kotlin 中存在二种相等的判断: 1.引用相等 也就是说,两个引用指向同一个对象,使用===操作 ,相反操作为!==来判断 2.结构相等 使用equals 函数相等和==操作符 a?.equal ...

  2. Flask模拟实现CSRF攻击的方法

    https://www.jb51.net/article/144371.htm https://www.cnblogs.com/888888CN/p/9489345.html http://xiaor ...

  3. android在点击EditText的时候始终不弹出软件键盘

    场景描述:正常情况下,当点击EditText时,软键盘会弹出来.现在的要求是当点击EditText时,弹日期选择对话框,选择的结果显示在EditText上.若不处理,当点击EditText时,软键盘和 ...

  4. breadwinner-养家之人_20190220

    " 在我们那里,人是最珍贵的.话要说的更有道理,而不是提高音量,毕竟滋养花朵的是雨水,而不是雷鸣“ ”我叫苏莱曼,我的爸爸是个教师,我的妈妈是个作家.有一天我在路上看到一个玩具,就把它捡起来 ...

  5. NuGet修改packages目录/迁移缓存文件夹

    如图,以下是NuGet默认配置 打开C:\Program Files (x86)\NuGet\Config目录的Microsoft.VisualStudio.Offline.config可以看见如下配 ...

  6. 分组卷积+squeezenet+mobilenet+shufflenet的参数及运算量计算

    来一发普通的二维卷积 1.输入feature map的格式为:m * m * h1 2.卷积核为 k * k 3.输出feature map的格式为: n * n * h2 参数量:k * k * h ...

  7. 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 ...

  8. 申请 Let's Encrypt 通配符 HTTPS 证书

    目录 一.背景知识 1.1.什么是通配符证书 1.2.什么是 Let's Encrypt 二.证书申请(certbot) 2.1.系统确定 2.2.工具安装 2.3.证书申请 2.4.证书查看 2.5 ...

  9. Flutter打包release版本安卓apk包真机安装无法请求网络的解决方法

    今天flutter build apk打包了一个release.apk包,在真机上安装后网络数据都不显示,但是在模拟器上没问题,然后又连接真机开debug各种测试,一切都正常!那这会是什么问题呢? 查 ...

  10. CVPapers - Computer Vision Resource

    To add links (PDF, project,...) you can use the online tool. Computer Vision Paper Indexes ICCV:  20 ...