PE查看器

主要界面如下:

主要代码如下:

  1 BOOL CPEParseDlg::OnInitDialog()
  2 {
  3     CDialog::OnInitDialog();
  4 
  5     // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
  6     //  执行此操作
  7     SetIcon(m_hIcon, TRUE);            // 设置大图标
  8     SetIcon(m_hIcon, FALSE);        // 设置小图标
  9 
 10     // TODO: 在此添加额外的初始化代码
 11     InitSectionList();
 12 
 13     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
 14 }
 15 
 16 // 如果向对话框添加最小化按钮,则需要下面的代码
 17 //  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
 18 //  这将由框架自动完成。
 19 
 20 void CPEParseDlg::OnPaint()
 21 {
 22     if (IsIconic())
 23     {
 24         CPaintDC dc(this); // 用于绘制的设备上下文
 25 
 26         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 27 
 28         // 使图标在工作区矩形中居中
 29         int cxIcon = GetSystemMetrics(SM_CXICON);
 30         int cyIcon = GetSystemMetrics(SM_CYICON);
 31         CRect rect;
 32         GetClientRect(&rect);
 33         int x = (rect.Width() - cxIcon + 1) / 2;
 34         int y = (rect.Height() - cyIcon + 1) / 2;
 35 
 36         // 绘制图标
 37         dc.DrawIcon(x, y, m_hIcon);
 38     }
 39     else
 40     {
 41         CDialog::OnPaint();
 42     }
 43 }
 44 
 45 //当用户拖动最小化窗口时系统调用此函数取得光标
 46 //显示。
 47 HCURSOR CPEParseDlg::OnQueryDragIcon()
 48 {
 49     return static_cast<HCURSOR>(m_hIcon);
 50 }
 51 
 52 
 53 void CPEParseDlg::OnBnClickedButtonLook()
 54 {
 55     // TODO: 在此添加控件通知处理程序代码
 56     ((CEdit*)GetDlgItem(IDC_EDIT_FILEPATH))->GetWindowText(m_strPathName);
 57     m_strPathName = m_strPathName.Trim();
 58     if (m_strPathName.IsEmpty())
 59     {
 60         AfxMessageBox(_T("请选择要查看的文件!"));
 61         return;
 62     }
 63 
 64     FileCreate();
 65     if (FALSE == IsPeFileAndGetPePointer())
 66     {
 67         AfxMessageBox(_T("该文件不是PE文件!"));
 68         return;
 69     }
 70     ParseBasePe();
 71     EnumSections();
 72 }
 73 
 74 void CPEParseDlg::OnBnClickedButtonExit()
 75 {
 76     // TODO: 在此添加控件通知处理程序代码
 77     OnOK();
 78 }
 79 
 80 void CPEParseDlg::OnBnClickedButtonBrowse()
 81 {
 82     // TODO: 在此添加控件通知处理程序代码
 83     CFileDialog FileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, _T("Executeable Files (*.exe)|*.exe|Dynamic Linker Library Files (*.dll)|*.dll|OCX Files (*.ocx)|*.ocx|Driver Files (*.sys)|*.sys||"));
 84     FileDlg.DoModal();
 85     CString strPathName = FileDlg.GetPathName();
 86     ((CEdit*)GetDlgItem(IDC_EDIT_FILEPATH))->SetWindowText(strPathName);
 87 }
 88 
 89 BOOL CPEParseDlg::FileCreate(void)
 90 {
 91     BOOL bRet = FALSE;
 92 
 93     m_hFile = CreateFile(m_strPathName.GetBuffer(0), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 94     if (INVALID_HANDLE_VALUE == m_hFile)
 95     {
 96         return bRet;
 97     }
 98 
 99     m_hMap = CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
100     if (NULL == m_hMap)
101     {
102         CloseHandle(m_hFile);
103         return bRet;
104     }
105 
106     m_lpBase = MapViewOfFile(m_hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
107     if (NULL == m_lpBase)
108     {
109         CloseHandle(m_hMap);
110         CloseHandle(m_hFile);
111         return bRet;
112     }
113 
114     bRet = TRUE;
115     return bRet;
116 }
117 
118 void CPEParseDlg::InitSectionList(void)
119 {
120     CRect Rect;
121     m_ctrlSections.GetClientRect(&Rect);
122     m_ctrlSections.SetExtendedStyle(m_ctrlSections.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
123     m_ctrlSections.InsertColumn(0, _T("节名"));
124     m_ctrlSections.InsertColumn(1, _T("V.偏移"));
125     m_ctrlSections.InsertColumn(2, _T("V.大小"));
126     m_ctrlSections.InsertColumn(3, _T("R.偏移"));
127     m_ctrlSections.InsertColumn(4, _T("R.大小"));
128     m_ctrlSections.InsertColumn(5, _T("标志"));
129     m_ctrlSections.SetColumnWidth(0, Rect.Width() / 6);
130     m_ctrlSections.SetColumnWidth(1, Rect.Width() / 6);
131     m_ctrlSections.SetColumnWidth(2, Rect.Width() / 6);
132     m_ctrlSections.SetColumnWidth(3, Rect.Width() / 6);
133     m_ctrlSections.SetColumnWidth(4, Rect.Width() / 6);
134     m_ctrlSections.SetColumnWidth(5, Rect.Width() / 6);
135 }
136 
137 BOOL CPEParseDlg::IsPeFileAndGetPePointer(void)
138 {
139     BOOL bRet = FALSE;
140 
141     m_pDosHeader = (PIMAGE_DOS_HEADER)m_lpBase;
142     if (IMAGE_DOS_SIGNATURE != m_pDosHeader->e_magic)
143     {
144         return bRet;
145     }
146 
147     m_pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)m_lpBase + m_pDosHeader->e_lfanew);
148     if (IMAGE_NT_SIGNATURE != m_pNtHeaders->Signature)
149     {
150         return bRet;
151     }
152 
153     m_pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)&(m_pNtHeaders->OptionalHeader) + m_pNtHeaders->FileHeader.SizeOfOptionalHeader);
154 
155     bRet = TRUE;
156     return bRet;
157 }
158 
159 void CPEParseDlg::ParseBasePe(void)
160 {
161     m_strEntryPoint.Format(_T("%08X"), m_pNtHeaders->OptionalHeader.AddressOfEntryPoint);
162     m_strImageBase.Format(_T("%08X"), m_pNtHeaders->OptionalHeader.ImageBase);
163     m_strLinkerVersion.Format(_T("%d.%d"), m_pNtHeaders->OptionalHeader.MajorLinkerVersion, m_pNtHeaders->OptionalHeader.MinorLinkerVersion);
164     m_strSectionNum.Format(_T("%02X"), m_pNtHeaders->FileHeader.NumberOfSections);
165     m_strFileAlignment.Format(_T("%08X"), m_pNtHeaders->OptionalHeader.FileAlignment);
166     m_strSectionAlignment.Format(_T("%08X"), m_pNtHeaders->OptionalHeader.SectionAlignment);
167     UpdateData(FALSE);
168 }
169 
170 void CPEParseDlg::EnumSections(void)
171 {
172     m_ctrlSections.DeleteAllItems();
173 
174     CString strTemp;
175     int iSectionNumber = m_pNtHeaders->FileHeader.NumberOfSections;
176     
177     for (int i = 0; i < iSectionNumber; ++i)
178     {
179         strTemp = m_pSectionHeader[i].Name;
180         m_ctrlSections.InsertItem(i, strTemp);
181 
182         strTemp.Format(_T("%08X"), m_pSectionHeader[i].VirtualAddress);
183         m_ctrlSections.SetItemText(i, 1, strTemp);
184 
185         strTemp.Format(_T("%08X"), m_pSectionHeader[i].Misc.VirtualSize);
186         m_ctrlSections.SetItemText(i, 2, strTemp);
187 
188         strTemp.Format(_T("%08X"), m_pSectionHeader[i].PointerToRawData);
189         m_ctrlSections.SetItemText(i, 3, strTemp);
190 
191         strTemp.Format(_T("%08X"), m_pSectionHeader[i].SizeOfRawData);
192         m_ctrlSections.SetItemText(i, 4, strTemp);
193 
194         strTemp.Format(_T("%08X"), m_pSectionHeader[i].Characteristics);
195         m_ctrlSections.SetItemText(i, 5, strTemp);
196     }
197 }
198 
199 void CPEParseDlg::OnBnClickedRadioVa()
200 {
201     // TODO: 在此添加控件通知处理程序代码
202     m_nSelected = 1;
203     ((CEdit*)GetDlgItem(IDC_EDIT_VA))->SetWindowText(_T(""));
204     ((CEdit*)GetDlgItem(IDC_EDIT_RVA))->SetWindowText(_T(""));
205     ((CEdit*)GetDlgItem(IDC_EDIT_FILEOFFSET))->SetWindowText(_T(""));
206     ((CEdit*)GetDlgItem(IDC_EDIT_VA))->SetReadOnly(FALSE);
207     ((CEdit*)GetDlgItem(IDC_EDIT_RVA))->SetReadOnly(TRUE);
208     ((CEdit*)GetDlgItem(IDC_EDIT_FILEOFFSET))->SetReadOnly(TRUE);
209 }
210 
211 void CPEParseDlg::OnBnClickedRadioRva()
212 {
213     // TODO: 在此添加控件通知处理程序代码
214     m_nSelected = 2;
215     ((CEdit*)GetDlgItem(IDC_EDIT_VA))->SetWindowText(_T(""));
216     ((CEdit*)GetDlgItem(IDC_EDIT_RVA))->SetWindowText(_T(""));
217     ((CEdit*)GetDlgItem(IDC_EDIT_FILEOFFSET))->SetWindowText(_T(""));
218     ((CEdit*)GetDlgItem(IDC_EDIT_VA))->SetReadOnly(TRUE);
219     ((CEdit*)GetDlgItem(IDC_EDIT_RVA))->SetReadOnly(FALSE);
220     ((CEdit*)GetDlgItem(IDC_EDIT_FILEOFFSET))->SetReadOnly(TRUE);
221 }
222 
223 void CPEParseDlg::OnBnClickedRadioFileoffset()
224 {
225     // TODO: 在此添加控件通知处理程序代码
226     m_nSelected = 3;
227     ((CEdit*)GetDlgItem(IDC_EDIT_VA))->SetWindowText(_T(""));
228     ((CEdit*)GetDlgItem(IDC_EDIT_RVA))->SetWindowText(_T(""));
229     ((CEdit*)GetDlgItem(IDC_EDIT_FILEOFFSET))->SetWindowText(_T(""));
230     ((CEdit*)GetDlgItem(IDC_EDIT_VA))->SetReadOnly(TRUE);
231     ((CEdit*)GetDlgItem(IDC_EDIT_RVA))->SetReadOnly(TRUE);
232     ((CEdit*)GetDlgItem(IDC_EDIT_FILEOFFSET))->SetReadOnly(FALSE);
233 }
234 
235 void CPEParseDlg::OnBnClickedButtonCalc()
236 {
237     // TODO: 在此添加控件通知处理程序代码
238     m_strImageBase = m_strImageBase.Trim();
239     if (m_strImageBase.IsEmpty())
240     {
241         AfxMessageBox(_T("请先点击查看按钮!"));
242         return;
243     }
244 
245     CString strPathName;
246     ((CEdit*)GetDlgItem(IDC_EDIT_FILEPATH))->GetWindowText(strPathName);
247     if (strPathName != m_strPathName)
248     {
249         AfxMessageBox(_T("你已经更换了PE文件,请先点击查看按钮!"));
250         return;
251     }
252 
253     DWORD dwAddr = 0;
254     dwAddr = GetAddr();
255     int nInNum = GetAddrInSectionNum(dwAddr);
256     CalcAddr(nInNum, dwAddr);
257 }
258 
259 DWORD CPEParseDlg::GetAddr(void)
260 {
261     TCHAR szAddr[10] = {0};
262     DWORD dwAddr = 0;
263     switch (m_nSelected)
264     {
265     case 1:
266         GetDlgItemText(IDC_EDIT_VA, szAddr, 10);
267         HexStrToInt(szAddr, &dwAddr);
268         break;
269     case 2:
270         GetDlgItemText(IDC_EDIT_RVA, szAddr, 10);
271         HexStrToInt(szAddr, &dwAddr);
272         break;
273     case 3:
274         GetDlgItemText(IDC_EDIT_FILEOFFSET, szAddr, 10);
275         HexStrToInt(szAddr, &dwAddr);
276         break;
277     }
278 
279     return dwAddr;
280 }
281 
282 int CPEParseDlg::GetAddrInSectionNum(DWORD dwAddr)
283 {
284     int nInNum = 0;
285     int nSectionNum = m_pNtHeaders->FileHeader.NumberOfSections;
286     switch (m_nSelected)
287     {
288     case 1:
289         {
290             DWORD dwImageBase = m_pNtHeaders->OptionalHeader.ImageBase;
291             for (nInNum = 0; nInNum < nSectionNum; nInNum++)
292             {
293                 if (dwAddr >= dwImageBase + m_pSectionHeader[nInNum].VirtualAddress
294                     && dwAddr <= dwImageBase + m_pSectionHeader[nInNum].VirtualAddress
295                     + m_pSectionHeader[nInNum].Misc.VirtualSize)
296                 {
297                     return nInNum;
298                 }
299             }
300             break;
301         }
302     case 2:
303         for (nInNum = 0; nInNum < nSectionNum; nInNum++)
304         {
305             if (dwAddr >= m_pSectionHeader[nInNum].VirtualAddress
306                 && dwAddr <= m_pSectionHeader[nInNum].VirtualAddress
307                 + m_pSectionHeader[nInNum].Misc.VirtualSize)
308             {
309                 return nInNum;
310             }
311         }
312         break;
313     case 3:
314         for (nInNum = 0; nInNum < nSectionNum; nInNum++)
315         {
316             if (dwAddr >= m_pSectionHeader[nInNum].PointerToRawData
317                 && dwAddr <= m_pSectionHeader[nInNum].PointerToRawData
318                 + m_pSectionHeader[nInNum].SizeOfRawData)
319             {
320                 return nInNum;
321             }
322         }
323         break;
324     }
325 
326     return -1;
327 }
328 
329 void CPEParseDlg::CalcAddr(int nInNum, DWORD dwAddr)
330 {
331     DWORD dwVa = 0;
332     DWORD dwRva = 0;
333     DWORD dwFileOffset = 0;
334 
335     switch (m_nSelected)
336     {
337     case 1:
338         dwVa = dwAddr;
339         dwRva = dwVa - m_pNtHeaders->OptionalHeader.ImageBase;
340         dwFileOffset = m_pSectionHeader[nInNum].PointerToRawData + (dwRva - m_pSectionHeader[nInNum].VirtualAddress);
341         break;
342     case 2:
343         dwVa = dwAddr + m_pNtHeaders->OptionalHeader.ImageBase;
344         dwRva = dwAddr;
345         dwFileOffset = m_pSectionHeader[nInNum].PointerToRawData + (dwRva - m_pSectionHeader[nInNum].VirtualAddress);
346         break;
347     case 3:
348         dwFileOffset = dwAddr;
349         dwRva = m_pSectionHeader[nInNum].VirtualAddress + (dwFileOffset - m_pSectionHeader[nInNum].PointerToRawData);
350         dwVa = dwRva + m_pNtHeaders->OptionalHeader.ImageBase;
351         break;
352     }
353 
354     SetDlgItemText(IDC_EDIT_SECTION, CString(m_pSectionHeader[nInNum].Name));
355 
356     CString str;
357     str.Format(_T("%08X"), dwVa);
358     SetDlgItemText(IDC_EDIT_VA, str);
359 
360     str.Format(_T("%08X"), dwRva);
361     SetDlgItemText(IDC_EDIT_RVA, str);
362 
363     str.Format(_T("%08X"), dwFileOffset);
364     SetDlgItemText(IDC_EDIT_FILEOFFSET, str);
365 }
366 
367 void CPEParseDlg::HexStrToInt(TCHAR* szAddr, DWORD* pdwAddr)
368 {
369     int iLen = lstrlen(szAddr);
370     *pdwAddr = 0;
371 
372     for (int i = 0; i < iLen; i++)
373     {
374         if (szAddr[i] >= _T('0') && szAddr[i] <= _T('9'))
375         {
376             *pdwAddr = ((*pdwAddr) << 4) | (szAddr[i] - _T('0'));
377         }
378         else if (szAddr[i] >= _T('A') && szAddr[i] <= _T('F'))
379         {
380             *pdwAddr = ((*pdwAddr) << 4) | (szAddr[i] - _T('A') + 0xA);
381         }
382         else if (szAddr[i] >= _T('a') && szAddr[i] <= _T('f'))
383         {
384             *pdwAddr = ((*pdwAddr) << 4) | (szAddr[i] - _T('a') + 0xA);
385         }
386     }
387 }
388 
389 void CPEParseDlg::OnDestroy()
390 {
391     CDialog::OnDestroy();
392 
393     // TODO: 在此处添加消息处理程序代码
394     if (NULL != m_lpBase)
395     {
396         UnmapViewOfFile(m_lpBase);
397     }
398     
399     if (NULL != m_hMap)
400     {
401         CloseHandle(m_hMap);
402     }
403 
404     if (INVALID_HANDLE_VALUE != m_hFile)
405     {
406         CloseHandle(m_hFile);
407     }
408 }
409 
410 HBRUSH CPEParseDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
411 {
412     HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
413 
414     // TODO:  在此更改 DC 的任何属性
415     //if (nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_STATIC || nCtlColor == CTLCOLOR_EDIT)
416     //{
417     //    pDC->SetBkMode(TRANSPARENT);
418     //    return CreateSolidBrush(RGB(0x2F, 0x4F, 0x4F));
419     //}
420 
421     // TODO:  如果默认的不是所需画笔,则返回另一个画笔
422     return hbr;
423 }
424 
425 void CPEParseDlg::OnBnClickedButtonAddsection()
426 {
427     // TODO: 在此添加控件通知处理程序代码
428     m_strImageBase = m_strImageBase.Trim();
429     if (m_strImageBase.IsEmpty())
430     {
431         AfxMessageBox(_T("请先点击查看按钮!"));
432         return;
433     }
434 
435     CString strPathName;
436     ((CEdit*)GetDlgItem(IDC_EDIT_FILEPATH))->GetWindowText(strPathName);
437     if (strPathName != m_strPathName)
438     {
439         AfxMessageBox(_T("你已经更换了PE文件,请先点击查看按钮!"));
440         return;
441     }
442 
443     TCHAR szSectionName[8] = {0};
444     int nSectionSize = 0;
445 
446     GetDlgItemText(IDC_EDIT_SECTIONNAME, szSectionName, 8);
447     nSectionSize = GetDlgItemInt(IDC_EDIT_SECTIONSIZE, FALSE, TRUE);
448 
449     AddSection(szSectionName, nSectionSize);
450 }
451 
452 void CPEParseDlg::AddSection(TCHAR* szSectionName, int nSectionSize)
453 {
454     int nSectionNum = m_pNtHeaders->FileHeader.NumberOfSections;
455     DWORD dwFileAlignment = m_pNtHeaders->OptionalHeader.FileAlignment;
456     DWORD dwSectionAlignment = m_pNtHeaders->OptionalHeader.SectionAlignment;
457 
458     PIMAGE_SECTION_HEADER pTempSection = m_pSectionHeader + nSectionNum;
459 
460     int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)szSectionName, -1, NULL, 0, NULL, NULL);
461     char *pszSectionNameA = new char[nLen];
462     WideCharToMultiByte(CP_ACP, 0, szSectionName, -1, pszSectionNameA, nLen * sizeof(char), NULL, NULL);
463     //拷贝节名
464     strncpy((char*)(pTempSection->Name), pszSectionNameA, 7);
465     delete[] pszSectionNameA;
466     pszSectionNameA = NULL;
467     //节的内存大小
468     pTempSection->Misc.VirtualSize = AlignSize(nSectionSize, dwSectionAlignment);
469     //节的内存起始位置
470     pTempSection->VirtualAddress = m_pSectionHeader[nSectionNum - 1].VirtualAddress 
471         + AlignSize(m_pSectionHeader[nSectionNum - 1].Misc.VirtualSize, dwSectionAlignment);
472     //节的文件大小
473     pTempSection->SizeOfRawData = AlignSize(nSectionSize, dwFileAlignment);
474     //节的文件起始位置
475     pTempSection->PointerToRawData = m_pSectionHeader[nSectionNum - 1].PointerToRawData
476         + AlignSize(m_pSectionHeader[nSectionNum - 1].SizeOfRawData, dwFileAlignment);
477     //修正节数量
478     m_pNtHeaders->FileHeader.NumberOfSections++;
479     //修正映像大小
480     m_pNtHeaders->OptionalHeader.SizeOfImage += pTempSection->Misc.VirtualSize;
481     //填充内存映射
482     FlushViewOfFile(m_lpBase, 0);
483     //添加节数据
484     AddSectionData(pTempSection->SizeOfRawData);
485 
486     CString str;
487     str.Format(_T("%02X"), m_pNtHeaders->FileHeader.NumberOfSections);
488     ((CEdit*)GetDlgItem(IDC_EDIT_SECTIONNUM))->SetWindowText(str);
489     EnumSections();
490 }
491 
492 DWORD CPEParseDlg::AlignSize(int nSectionSize, DWORD dwAlignment)
493 {
494     int nSize = nSectionSize;
495     if (nSize % dwAlignment != 0)
496     {
497         nSectionSize = (nSize / dwAlignment + 1) * dwAlignment;
498     }
499 
500     return nSectionSize;
501 }
502 
503 void CPEParseDlg::AddSectionData(int nSectionSize)
504 {
505     PBYTE pByte = NULL;
506     pByte = (PBYTE)malloc(nSectionSize);
507     ZeroMemory(pByte, nSectionSize);
508 
509     DWORD dwNum = 0;
510     SetFilePointer(m_hFile, 0, 0, FILE_END);
511     WriteFile(m_hFile, pByte, nSectionSize, &dwNum, NULL);
512     FlushFileBuffers(m_hFile);
513 
514     free(pByte);
515 }

下载地址如下:

http://pan.baidu.com/s/1hqBR06S

原文地址:https://www.cnblogs.com/qiyueliuguang/p/3544144.html