[大家好,在写输入表这一部分的时候,主要是为了自己能更加深入的理解PE文件格式; 输入表的部分代码参考了北极星2003老兄的一部分,然而发现,在北极星2003写的那个pe文件分析器导入表部分,它用了firstThunk 作为指针来输出Thunk rva 和函数名,由于在内存映射时改变FirstThunk中的数据,所以函数名就怎么都显示不出来了; 由于打算将这个PE文件分析器继续写下去,所以在完成每一部分后,我会将源代码发出;以便大家学习讨论,共同进步,也希望大家能对程序做些改进,而不是简单的复制粘贴代码,由于临近期末,所以时间不多,进度也就慢了点;大家多包涵;
这里给大家两个截图
源代码中Exe文件被剔除,为了减少空间;大家用Visual C++ 6.0 编译下就可以了;
代码:
#include<windows.h> #include <commctrl.h> #include "resource.h" #ifndef _IMAGEHLP_H #include "imagehlp.h" #pragma comment ( lib, "imagehlp.lib" ) #endif /*----------------------------- 全局变量定义 -----------------------------*/ HINSTANCE hInst; HANDLE hFile,hFileMap; LPVOID lpMemory; PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_NT_HEADERS pNtHeader = NULL; /*---------------------------------- 对话框函数说明 *---------------------------------*/ BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam); BOOL CALLBACK DataDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam); BOOL CALLBACK ImportDlgProc(HWND hDlg, UINT message,WPARAM wParam,LPARAM lparam); /*---------------------------------- 数据显示函数说明 *---------------------------------*/ void ShowSection(HWND hDlg); void ShowDataDirectoryInDlg ( HWND hwnd ); void ShowSectionTable(HWND hDlg,PIMAGE_FILE_HEADER pFileHeader,PIMAGE_SECTION_HEADER pSectionHeader); void ShowImportDescInfo(HWND hDlg); void ShowDllFunction( HWND hDlg, int index ); /*---------------------------------- 控件初始化函数说明 *---------------------------------*/ BOOL WINAPI InitListViewColumns(HWND hDlg); BOOL WINAPI InitImportDescriptor(HWND hDlg); /*---------------------------------- Pe文件处理函数函数说明 *---------------------------------*/ BOOL IsPeFile(LPVOID ImageBase); PIMAGE_NT_HEADERS GetNtHeader(LPVOID ImageBase); PIMAGE_FILE_HEADER WINAPI GetFileHeader(LPVOID Imagebase); PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase); PIMAGE_SECTION_HEADER GetFirstSectionHeader(PIMAGE_NT_HEADERS pNtHeader); PIMAGE_IMPORT_DESCRIPTOR GetFirstImportDesc(LPVOID ImageBase); /*---------------------------------- 主函数入口 *---------------------------------*/ int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowcmd) { hInst = hInstance; DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,DlgProc); return 0; } /*---------------------------------- 主程序对话框函数 *---------------------------------*/ BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) { HMENU hMenu = GetMenu(hDlg); OPENFILENAME FileName = {0,0,0}, *lpFileName = &FileName; TCHAR szPe[]="\"PE File(*.exe)\" \0*.exe;*.dll;*.scr;*.fon;*.drv;\0\"*.All File(*.*) \0*.*\0\0"; TCHAR szFileName[256]={""}; TCHAR buf[16]; LVITEM lvItem; ZeroMemory(&lvItem,sizeof(LVITEM)); switch(message) { case WM_INITDIALOG: EnableMenuItem(hMenu,IDM_DATA_DIRECTORY,MF_GRAYED); InitListViewColumns(hDlg); break; case WM_CLOSE: UnmapViewOfFile(lpMemory); CloseHandle(hFileMap); CloseHandle(hFile); EndDialog(hDlg,NULL); EndDialog(hDlg,NULL); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_DATA_DIRECTORY: DialogBox(hInst,MAKEINTRESOURCE(IDD_DATA_DIRECTORY),hDlg,DataDlgProc); break; case IDM_EXIT: UnmapViewOfFile(lpMemory); CloseHandle(hFileMap); CloseHandle(hFile); EndDialog(hDlg,NULL); break; case IDM_OPEN: FileName.hInstance = (HINSTANCE)hDlg; FileName.hwndOwner = hDlg; FileName.lStructSize = sizeof(OPENFILENAME); FileName.lpstrFilter = szPe; FileName.lpstrFile = szFileName; FileName.Flags = OFN_FILEMUSTEXIST||OFN_PATHMUSTEXIST; FileName.nMaxFile = sizeof(szFileName); if(!GetOpenFileName(lpFileName)) { MessageBox(hDlg,"GetOpenFileName 调用失败","ERROR",NULL); break; } SetDlgItemText(hDlg,IDC_FILENAME,szFileName); hFile = CreateFile(FileName.lpstrFile, // open pe file GENERIC_READ, // open for reading FILE_SHARE_READ|| FILE_SHARE_WRITE, // share for reading NULL, // no security OPEN_EXISTING, // existing file only FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attr. template if (hFile == INVALID_HANDLE_VALUE) { MessageBox(hDlg,"Could not open file.","ERROR",MB_ICONERROR); break;// process error } if(GetFileSize(hFile,NULL)!=0) { hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); if(hFileMap!=0) { lpMemory = MapViewOfFile(hFileMap,FILE_MAP_READ,NULL,NULL,NULL); } } if(IsPeFile(lpMemory)) { pNtHeader = GetNtHeader(lpMemory); pFileHeader = GetFileHeader(lpMemory); pOptionHeader = GetOptionalHeader(lpMemory); pSectionHeader = GetFirstSectionHeader(pNtHeader); if(!(pFileHeader&&pOptionHeader)) { MessageBox(hDlg,"获取文件头指针失败","PEINFO",MB_ICONERROR); break; } else { wsprintf(buf,"%04lX",pFileHeader->Machine); SetDlgItemText(hDlg,IDC_MACHINE,buf); wsprintf(buf,"%04lX",pFileHeader->NumberOfSections); SetDlgItemText(hDlg,IDC_NUMSECTION,buf); wsprintf(buf,"%04lX",pOptionHeader->Magic); SetDlgItemText(hDlg,IDC_MAGIC,buf); wsprintf(buf,"%08lX",pOptionHeader->AddressOfEntryPoint); SetDlgItemText(hDlg,IDC_ENTERPOINT,buf); ShowSectionTable(hDlg,pFileHeader,pSectionHeader); } } else { MessageBox(hDlg,"你选择的不是PE文件","error",MB_ICONERROR); SendMessage(hDlg,WM_CLOSE,NULL,NULL); } EnableMenuItem(hMenu,IDM_DATA_DIRECTORY,MF_ENABLED); break; } } return FALSE; } /*-------------------------------- 数据目录对话框的关联函数, ------------------------------*/ BOOL CALLBACK DataDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: ShowDataDirectoryInDlg ( hDlg ); break; case WM_CLOSE: EndDialog(hDlg,NULL); break; case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_IMDLG: DialogBox((HINSTANCE)GetModuleHandle(0),MAKEINTRESOURCE(IDD_IMPORT_DLG),hDlg,ImportDlgProc); break; } } return FALSE; } BOOL CALLBACK ImportDlgProc(HWND hDlg, UINT message,WPARAM wParam,LPARAM lparam) { switch(message) { case WM_INITDIALOG: InitImportDescriptor( hDlg); ShowImportDescInfo(hDlg); break; case WM_CLOSE: EndDialog(hDlg,NULL); break; case WM_NOTIFY: switch ( LOWORD(wParam) ) { case IDC_IMPORT_DESCRIPTOR: switch ( ((LPNMHDR)lparam)->code) { case LVN_ITEMCHANGED: LPNMLISTVIEW temp = ( (LPNMLISTVIEW)lparam ) ; if( temp->uNewState ) { ShowDllFunction ( hDlg, ( (LPNMLISTVIEW)lparam )->iItem ) ; } break ; } return TRUE ; } break ; } return FALSE; } /*------------------------------------ 用于显示数据目录表的函数 --------------------------------*/ void ShowDataDirectoryInDlg ( HWND hDlg ) { typedef struct { UINT ID_RVA; UINT ID_SIZE; } DataDir_EditID; DataDir_EditID DataDirEditId[]= { { IDC_EXPORT_RAV, IDC_EXPORT_SIZE }, { IDC_IMPORT_RVA, IDC_IMPORT_SIZE }, { IDC_RES_RVA, IDC_RES_SIZE }, { IDC_EXCEPTION_RVA, IDC_EXCEPTION_SIZE }, { IDC_SECURITY_RVA, IDC_SECURITY_SIZE }, { IDC_BASE_RVA, IDC_BASE_SIZE }, { IDC_DEBUG_RVA, IDC_DEBUG_SIZE }, { IDC_COPYRIGHT_RVA, IDC_COPYRIGHT_SIZE }, { IDC_GLOBAL_RVA, IDC_GLOBAL_SIZE }, { IDC_THREAD_RVA, IDC_THREAD_SIZE }, { IDC_LOAD_RVA, IDC_LOAD_SIZE }, { IDC_BOUND_RVA, IDC_BOUND_SIZE }, { IDC_IAT_RVA, IDC_IAT_SIZE }, { IDC_DELAY_RVA, IDC_DELAY_SIZE }, { IDC_COM_RVA, IDC_COM_SIZE } }; /*---------------------------- 循环显示数据目录表 ------------------------------*/ TCHAR buff[16]; for (int j=0; j< 15; j++ ) { wsprintf ( buff, "%08lX", pOptionHeader->DataDirectory[j].VirtualAddress ) ; SetWindowText ( GetDlgItem ( hDlg, DataDirEditId[j].ID_RVA ), buff ) ; wsprintf ( buff, "%08lX", pOptionHeader->DataDirectory[j].Size ) ; SetWindowText ( GetDlgItem ( hDlg, DataDirEditId[j].ID_SIZE ), buff ) ; } } PIMAGE_IMPORT_DESCRIPTOR GetFirstImportDesc(LPVOID ImageBase) { DWORD pImportOffset = (pOptionHeader->DataDirectory[1]).VirtualAddress ; PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) \ ImageRvaToVa ( pNtHeader, ImageBase, pImportOffset, &pSectionHeader ) ; if(!pImportDesc) { return NULL; } return pImportDesc; } void ShowImportDescInfo(HWND hDlg) { HWND hList = GetDlgItem(hDlg,IDC_IMPORT_DESCRIPTOR); LVITEM lvi; TCHAR cBuff[10], szDllName[256]; PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetFirstImportDesc(lpMemory); DWORD dwErrorCode = GetLastError(); for(int i=0;pImportDesc->FirstThunk;i++) { ZeroMemory(cBuff,sizeof(cBuff)); ZeroMemory(&lvi,sizeof(LVITEM)); memset(szDllName,0,sizeof(szDllName)); lvi.mask = LVIF_TEXT; lvi.iItem = i; lvi.pszText = szDllName; lvi.iSubItem = 0; LPVOID pDllName = (PIMAGE_IMPORT_DESCRIPTOR)(ImageRvaToVa(pNtHeader,lpMemory,(DWORD)pImportDesc->Name,&pSectionHeader)); wsprintf ( szDllName, "%s", (char*)pDllName ) ; ListView_InsertItem(hList,&lvi); lvi.pszText = cBuff; lvi.iSubItem =1; wsprintf(cBuff,"%08lX",pImportDesc->OriginalFirstThunk); SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ; lvi.pszText = cBuff; lvi.iSubItem =2; wsprintf(cBuff,"%08lX",pImportDesc->TimeDateStamp); SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ; lvi.pszText = cBuff; lvi.iSubItem =3; wsprintf(cBuff,"%08lX",pImportDesc->ForwarderChain); SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ; pImportDesc++ ; lvi.pszText = cBuff; lvi.iSubItem =4; wsprintf(cBuff,"%08lX",pImportDesc->Name); SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ; lvi.pszText = cBuff; lvi.iSubItem =5; wsprintf(cBuff,"%08lX",pImportDesc->FirstThunk); SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ; } } void ShowDllFunction( HWND hDlg, int index ) { HWND hList = GetDlgItem(hDlg,IDC_THUNK); ListView_SetExtendedListViewStyle(hList,LVS_EX_FULLROWSELECT); ListView_DeleteAllItems(hList); LVITEM lvi; TCHAR cBuff[10], szFunName[256]; PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetFirstImportDesc(lpMemory); DWORD dwErrorCode = GetLastError(); PIMAGE_IMPORT_DESCRIPTOR pCurrentImportDesc =&pImportDesc[index]; DWORD *INTEntry = (DWORD*)ImageRvaToVa ( pNtHeader, \ lpMemory, (DWORD)pCurrentImportDesc->OriginalFirstThunk, &pSectionHeader ) ; DWORD *IATEntry = (DWORD*)ImageRvaToVa ( pNtHeader, \ lpMemory, (DWORD)pCurrentImportDesc->FirstThunk, &pSectionHeader ) ; for(int i=0;((DWORD)(*INTEntry))||((DWORD)(*IATEntry));i++) { ZeroMemory(&lvi,sizeof(LVITEM)); ZeroMemory(cBuff,sizeof(cBuff)); ZeroMemory(szFunName,sizeof(szFunName)); lvi.mask = LVIF_TEXT; lvi.iItem = i; lvi.pszText = cBuff; lvi.iSubItem = 0; wsprintf(cBuff,"%08lX",(DWORD)(*INTEntry)); ListView_InsertItem(hList,&lvi); lvi.iSubItem = 1; wsprintf(cBuff,"%08lX",(DWORD)(*IATEntry)); SendDlgItemMessage ( hDlg, IDC_THUNK, LVM_SETITEM, 0, (LPARAM)&lvi); if(HIWORD(*INTEntry)&0x8000) { wsprintf ( szFunName, "ord:%08lX", (DWORD)(LOWORD(*INTEntry)) ) ; strcpy ( cBuff, "--" ) ; } else { PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)ImageRvaToVa \ (pNtHeader, lpMemory, (DWORD)(*INTEntry), &pSectionHeader ) ; if ( pByName ) { wsprintf ( cBuff, "%04lX", pByName->Hint ) ; wsprintf ( szFunName, "%s", (char*)pByName->Name ) ; } } lvi.pszText = cBuff; lvi.iSubItem = 2 ; SendDlgItemMessage (hDlg, IDC_THUNK, LVM_SETITEM, 0, (LPARAM)&lvi ) ; lvi.pszText = szFunName ; lvi.iSubItem = 3 ; SendDlgItemMessage ( hDlg, IDC_THUNK, LVM_SETITEM, 0, (LPARAM)&lvi ) ; INTEntry++; IATEntry++; } } /*----------------------------- 初始化输入表列表 *-------------------------------*/ BOOL WINAPI InitImportDescriptor(HWND hDlg) { HWND hList = GetDlgItem(hDlg,IDC_IMPORT_DESCRIPTOR); SendMessage(hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0, (LPARAM)LVS_EX_FULLROWSELECT ); HWND hList1 = GetDlgItem(hDlg,IDC_THUNK); SendMessage(hList1,LVM_SETEXTENDEDLISTVIEWSTYLE,0, (LPARAM)LVS_EX_FULLROWSELECT ); TCHAR IID[][20] ={"DLL名称","OriginalFirstThunk","时间日期标志","ForwarderChain","Name of RVA","FirstThunk"}; TCHAR THUNK[][10] ={"ThunkRVA","Thunk值","Hint","API名称"}; LVCOLUMN lvc; ZeroMemory(&lvc,sizeof(LVCOLUMN)); int iCol; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.cx = 80; for(iCol = 0;iCol<6;iCol++) { lvc.iSubItem = iCol; lvc.pszText = IID[iCol]; if (ListView_InsertColumn(hList, iCol, &lvc) == -1) return FALSE; } for(iCol = 0;iCol<4;iCol++) { lvc.iSubItem = iCol; lvc.pszText =THUNK[iCol]; if (ListView_InsertColumn(hList1, iCol, &lvc) == -1) return FALSE; } return TRUE; } /*---------------------------------- 区块列表控件初始化 *---------------------------------*/ BOOL WINAPI InitListViewColumns(HWND hDlg) { HWND hList = GetDlgItem(hDlg,IDC_SECTION_LIST); SendMessage(hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0, (LPARAM)LVS_EX_FULLROWSELECT ); //设置树形控件的扩展样式 TCHAR section_header[][8]={"Name","VOffset","Vsize","ROffset","RSize","Flags"}; // temporary buffer LVCOLUMN lvc; ZeroMemory(&lvc,sizeof(LVCOLUMN)); int iCol; // Initialize the LVCOLUMN structure. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.cx = 80; // Add the columns. for (iCol = 0; iCol < 6; iCol++) { lvc.iSubItem = iCol; lvc.pszText = section_header[iCol]; if (ListView_InsertColumn(hList, iCol, &lvc) == -1) return FALSE; } return TRUE; } /*---------------------------- 显示区块信息 *----------------------------*/ void ShowSectionTable(HWND hDlg,PIMAGE_FILE_HEADER pFileHeader,PIMAGE_SECTION_HEADER pSectionHeader) { LVITEM lvItem; ZeroMemory(&lvItem,sizeof(LVITEM)); TCHAR buf[16]; for ( int i = 0; i < pFileHeader->NumberOfSections; i++ ) { ZeroMemory( &lvItem, sizeof ( lvItem ) ) ; lvItem.mask = LVIF_TEXT ; lvItem.iItem = i ; ZeroMemory(buf,sizeof(buf)); CopyMemory(buf, pSectionHeader->Name, 8 ) ; lvItem.pszText = buf ; SendDlgItemMessage ( hDlg, IDC_SECTION_LIST, LVM_INSERTITEM, 0, (LPARAM)&lvItem ) ; lvItem.pszText = buf; wsprintf ( buf, "%08lX", pSectionHeader->VirtualAddress); lvItem.iSubItem = 1; SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem); wsprintf ( buf, "%08lX", pSectionHeader->Misc.VirtualSize); lvItem.iSubItem = 2; SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem); wsprintf ( buf, "%08lX", pSectionHeader->PointerToRawData); lvItem.iSubItem = 3; SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem); wsprintf ( buf, "%08lX", pSectionHeader->SizeOfRawData); lvItem.iSubItem = 4; SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem); wsprintf ( buf, "%08lX", pSectionHeader->Characteristics); lvItem.iSubItem = 5; SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem); pSectionHeader++ ; } } //判断是否是PE文件结构 BOOL IsPeFile(LPVOID ImageBase) { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNtHeader = NULL; if(!ImageBase) return FALSE; pDosHeader = (PIMAGE_DOS_HEADER) ImageBase; if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) return FALSE; pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew); if(pNtHeader->Signature != IMAGE_NT_SIGNATURE ) return FALSE; return TRUE; } //FileHeader 内容的读取 PIMAGE_NT_HEADERS GetNtHeader(LPVOID ImageBase) //获取NT结构指针 { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNtHeader = NULL; if(!IsPeFile(ImageBase)) return NULL; pDosHeader = (PIMAGE_DOS_HEADER)ImageBase; pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew); return pNtHeader; } PIMAGE_FILE_HEADER WINAPI GetFileHeader(LPVOID Imagebase) { PIMAGE_FILE_HEADER pFileHeader; PIMAGE_NT_HEADERS pNtHeader = NULL; pNtHeader = GetNtHeader(Imagebase); if(!pNtHeader) return NULL; pFileHeader = & pNtHeader->FileHeader; return pFileHeader; } PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase) { PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL; PIMAGE_NT_HEADERS pNtHeader = NULL; pNtHeader = GetNtHeader(ImageBase); if(!pNtHeader) return NULL; pOptionHeader = & pNtHeader->OptionalHeader; return pOptionHeader; } PIMAGE_SECTION_HEADER GetFirstSectionHeader(PIMAGE_NT_HEADERS pNtHeader) { PIMAGE_SECTION_HEADER pSectionHeader; pSectionHeader =IMAGE_FIRST_SECTION(pNtHeader); return pSectionHeader; }