pe工具02-解析pe头信息
1.目标
点击PE查看按钮,选pe文件,然后将该pe文件的信息展示在另一个窗口中;
pe信息窗口:
2.需求分析
1)新窗口
需要一个新的窗口,可用资源脚本新建一个对话框,然后拖控件实现;
然后在pe查看按钮的点击事件中调用DialogBox(hAppInstance,MAKEINTRESOURCE(IDD_PE),hwndDlg,DialogPe)打开新窗口;
注意函数的第三个参数为父窗口句柄;
子窗口也需要有自己的回调函数DialogPe,在窗口加载事件中获取pe信息然后给文本框赋值即可;
2)按钮点击时弹框选文pe件
为了实现点击按钮时选择文件,需要用到GetOpenFileName()函数;
该函数只有一个out参数,为OPENFILENAME结构体;
OPENFILENAME结构:
typedef struct tagOFN { DWORD lStructSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpstrFilter; LPTSTR lpstrCustomFilter; DWORD nMaxCustFilter; DWORD nFilterIndex; LPTSTR lpstrFile; DWORD nMaxFile; LPTSTR lpstrFileTitle; DWORD nMaxFileTitle; LPCTSTR lpstrInitialDir; LPCTSTR lpstrTitle; DWORD Flags; WORD nFileOffset; WORD nFileExtension; LPCTSTR lpstrDefExt; LPARAM lCustData; LPOFNHOOKPROC lpfnHook; LPCTSTR lpTemplateName; #if (_WIN32_WINNT >= 0x0500) void * pvReserved; DWORD dwReserved; DWORD FlagsEx; #endif // (_WIN32_WINNT >= 0x0500) } OPENFILENAME, *LPOPENFILENAME;
调用函数后可以通过结构体得到所选文件的路径;
得到了pe文件的路径,就可以将文件读入内存然后分析pe头信息了;
按钮点击事件的部分代码:
OPENFILENAME openFile; //点击按钮打开文件要用到 TCHAR szPeFileExt[100] = TEXT("*.exe;*.dll;*.scr;*.drv;*.sys;"); TCHAR szFileName[256]; memset(szFileName, 0, sizeof(TCHAR)*256); memset(&openFile, 0, sizeof(OPENFILENAME)); openFile.lStructSize = sizeof(OPENFILENAME); openFile.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; openFile.hwndOwner = hwndDlg; openFile.lpstrFilter = szPeFileExt; openFile.lpstrFile = szFileName; openFile.nMaxFile = MAX_PATH; ::GetOpenFileName(&openFile); //::MessageBox(NULL, szFileName, 0, 0); //画子窗口 DialogBox( hAppInstance, MAKEINTRESOURCE(IDD_PE), hwndDlg, DialogPe );
3)解析pe文件并给子窗口赋值
在子窗口回调函数的加载事件中给子窗口赋值;
可以用SendMessage函数来实现;需要输入框的句柄可以用GetDlgItem来得到;
HWND hSectionsNum = GetDlgItem(hwndDlg,IDC_EDIT_SECNUM); TCHAR tSecNum[10]; sprintf(tSecNum,"%04X",pPEHeader->NumberOfSections); SendMessage(hSectionsNum,WM_SETTEXT,0,(long)tSecNum);
3.部分实现代码
读取pe文件:
//读取pe文件 DWORD readPeFile(IN LPSTR src, LPVOID* pFileBuffer){ FILE* pFile = fopen(src, "rb"); if(!pFile){ MessageBox(0, TEXT("打开文件失败"), 0, 0); return 0; } //获取文件大小 fseek(pFile, 0, SEEK_END); DWORD fileSize = ftell(pFile); fseek(pFile, 0, SEEK_SET); //分配缓冲区 LPVOID buf = malloc(fileSize); if(!buf){ MessageBox(0, TEXT("申请堆内存失败"), 0, 0); fclose(pFile); return 0; } //读入缓冲区 size_t n = fread(buf, fileSize, 1, pFile); if(!n){ MessageBox(0, TEXT("读入文件失败"), 0, 0); free(buf); fclose(pFile); return 0; } *pFileBuffer = buf; fclose(pFile); return fileSize; }
子窗口回调函数:
//pe信息回调函数 BOOL CALLBACK DialogPe( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { HICON hicon_big; HICON hicon_small; switch(uMsg) { case WM_INITDIALOG : //加载图标 hicon_big = ::LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_ICON_BIG)); hicon_small = ::LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_ICON_SMALL)); SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (DWORD)hicon_big); SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (DWORD)hicon_small); //解析pe文件 getPeInfo(hwndDlg); return TRUE; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BTN_CLOSE: EndDialog(hwndDlg, 0); return TRUE; return TRUE; } break ; case WM_CLOSE: EndDialog(hwndDlg, 0); return TRUE; } return FALSE ; }
解析pe:
//解析pe文件 BOOL getPeInfo(HWND hwndDlg){ LPVOID pFileBuffer = NULL; PIMAGE_DOS_HEADER pDosHeader = NULL; //dos头指针 PIMAGE_FILE_HEADER peHeader = NULL; //pe头指针 PIMAGE_OPTIONAL_HEADER32 opHeader = NULL; //可选pe头指针 //将文件读入内存 readPeFile(szFileName, &pFileBuffer); if(!pFileBuffer){ free(pFileBuffer); return FALSE; } pDosHeader = (PIMAGE_DOS_HEADER) pFileBuffer; //判断是否为有效MZ标记 if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE){ MessageBox(0, TEXT("不是有效mz标记"), 0, 0); free(pFileBuffer); return FALSE; } //判断是否是有效的PE标志 if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { MessageBox(0, TEXT("不是有效PE标记"), 0, 0); free(pFileBuffer); return FALSE; } //给pe头结构指针赋值 peHeader = (PIMAGE_FILE_HEADER)((DWORD)pFileBuffer + pDosHeader->e_lfanew + 4); opHeader = (PIMAGE_OPTIONAL_HEADER32) ((DWORD)peHeader + IMAGE_SIZEOF_FILE_HEADER); //给子窗口赋值 HWND hOEP = GetDlgItem(hwndDlg,IDC_TXT_OEP); TCHAR tOEP[10]={0}; sprintf(tOEP, "%08X", opHeader->AddressOfEntryPoint); SendMessage(hOEP,WM_SETTEXT,0,(long)tOEP); HWND hImageBase = GetDlgItem(hwndDlg,IDC_TXT_IMAGEBASE); TCHAR tIB[10]={0}; sprintf(tIB, "%08X", opHeader->ImageBase); SendMessage(hImageBase,WM_SETTEXT,0,(long)tIB); HWND hImageSize = GetDlgItem(hwndDlg,IDC_TXT_SIZEOFIMAGE); TCHAR tIZ[10]={0}; sprintf(tIZ, "%08X", opHeader->SizeOfImage); SendMessage(hImageSize,WM_SETTEXT,0,(long)tIZ); HWND hBaseOfCode = GetDlgItem(hwndDlg,IDC_TXT_BaseOfCode); TCHAR tBOC[10]={0}; sprintf(tBOC, "%08X", opHeader->BaseOfCode); SendMessage(hBaseOfCode,WM_SETTEXT,0,(long)tBOC); HWND hBaseOfData = GetDlgItem(hwndDlg,IDC_TXT_BaseOfData); TCHAR tBOD[10]={0}; sprintf(tBOD, "%08X", opHeader->BaseOfData); SendMessage(hBaseOfData,WM_SETTEXT,0,(long)tBOD); HWND hSectionAlign = GetDlgItem(hwndDlg,IDC_TXT_SectionAlign); TCHAR tSA[10]={0}; sprintf(tSA, "%08X", opHeader->SectionAlignment); SendMessage(hSectionAlign,WM_SETTEXT,0,(long)tSA); HWND hFileAlignment = GetDlgItem(hwndDlg,IDC_TXT_FileAlignment); TCHAR tFA[10]={0}; sprintf(tFA, "%08X", opHeader->FileAlignment); SendMessage(hFileAlignment,WM_SETTEXT,0,(long)tFA); HWND hMZ = GetDlgItem(hwndDlg,IDC_TXT_MZ); TCHAR tMZ[10]={0}; sprintf(tMZ, "%04X", pDosHeader->e_magic); SendMessage(hMZ,WM_SETTEXT,0,(long)tMZ); HWND hSubsystem = GetDlgItem(hwndDlg,IDC_TXT_Subsystem); TCHAR tSubsystem[10]={0}; sprintf(tSubsystem, "%04X", opHeader->Subsystem); SendMessage(hSubsystem,WM_SETTEXT,0,(long)tSubsystem); HWND hSectionsNum = GetDlgItem(hwndDlg,IDC_TXT_NumOfSec); TCHAR tSecNum[10]={0}; sprintf(tSecNum,"%04X",peHeader->NumberOfSections); SendMessage(hSectionsNum,WM_SETTEXT,0,(long)tSecNum); HWND hTime = GetDlgItem(hwndDlg,IDC_TXT_TIME); TCHAR tTime[10]={0}; sprintf(tTime,"%08X",peHeader->TimeDateStamp); SendMessage(hTime,WM_SETTEXT,0,(long)tTime); HWND hHead = GetDlgItem(hwndDlg,IDC_TXT_SizeOfHeader); TCHAR tHead[10]={0}; sprintf(tHead,"%08X",opHeader->SizeOfHeaders); SendMessage(hHead,WM_SETTEXT,0,(long)tHead); HWND hChar = GetDlgItem(hwndDlg,IDC_TXT_CHARACTER); TCHAR tChar[10]={0}; sprintf(tChar,"%04X",peHeader->Characteristics); SendMessage(hChar,WM_SETTEXT,0,(long)tChar); HWND hCheckSum = GetDlgItem(hwndDlg,IDC_TXT_CheckSum); TCHAR tCheckSum[10]={0}; sprintf(tCheckSum,"%08X",opHeader->CheckSum); SendMessage(hCheckSum,WM_SETTEXT,0,(long)tCheckSum); HWND hOpHead = GetDlgItem(hwndDlg,IDC_TXT_OPHeader); TCHAR tOpHead[10]={0}; sprintf(tOpHead,"%08X", (DWORD)opHeader); SendMessage(hOpHead,WM_SETTEXT,0,(long)tOpHead); HWND hNumOfRAS = GetDlgItem(hwndDlg,IDC_TXT_NumOfRAS); TCHAR tNumOfRAS[10]={0}; sprintf(tNumOfRAS,"%08X", opHeader->NumberOfRvaAndSizes); SendMessage(hNumOfRAS,WM_SETTEXT,0,(long)tNumOfRAS); free(pFileBuffer); return TRUE; }
程序运行结果: