主要界面如下:
主要代码如下:
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 }
下载地址如下: