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;
}
 
程序运行结果:
 
 
 
posted @ 2020-01-15 09:48  L丶银甲闪闪  阅读(785)  评论(0编辑  收藏  举报