Writing of own code viewer for PE files
#include<Windows.h> #include<Richedit.h> #include<CommCtrl.h> #pragma comment(lib,"comctl32.lib") #include<strsafe.h> #include<stdio.h> #include"resource.h" //TCHAR szAppName[MAX_PATH] = TEXT("PE"); HANDLE hInstance, hWinMain, hWinEdit, hRichEdit; int dwStop, totalSize; char* lpMemory; DWORD WINAPI _OpenFile(LPVOID); void _Processing(); void _AppendInfo(const TCHAR* lpsz);//Append text to the text box void init(); void Exception(void); BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); void ShowErrMsg() { LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); MessageBox(NULL, lpMsgBuf, L"System Error", MB_OK | MB_ICONSTOP); LocalFree(lpMsgBuf); } int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { TCHAR szDllEdit[] = TEXT("RichEd20.dll"); hRichEdit = LoadLibrary((LPCWSTR) & amp;szDllEdit); hInstance = GetModuleHandle(NULL); DialogBoxParam(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgProc, (LPARAM)0); FreeLibrary(hRichEdit); return 0; } //Initialize window function void init() { CHARFORMAT stCf; TCHAR szClassEdit[] = TEXT("RichEdit20A"); TCHAR szFont[] = TEXT("宋体"); HINSTANCE hInstance; hWinEdit = GetDlgItem(hWinMain, IDC_INFO); //Set the icon for the window program hInstance = GetModuleHandle(NULL); HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ICO_MAIN)); SendMessage(hWinMain, WM_SETICON, ICON_BIG, (LPARAM)hIcon); //Set the edit control SendMessage(hWinEdit, EM_SETTEXTMODE, TM_PLAINTEXT, 0); RtlZeroMemory( & amp;stCf, sizeof(stCf)); stCf.cbSize = sizeof(stCf); stCf.yHeight = 9 * 20; stCf.dwMask = CFM_FACE | CFM_SIZE | CFM_BOLD; StringCchCopy((LPTSTR)stCf.szFaceName, lstrlen(szFont) + 1, (LPCTSTR) & amp;szFont); SendMessage(hWinEdit, EM_SETCHARFORMAT, 0, (LPARAM) & amp;stCf); SendMessage(hWinEdit, EM_EXLIMITTEXT, 0, -1); } //Rich text box callback function BOOL CALLBACK DlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) { LPVOID sClient = NULL; switch(wMsg) { case WM_CLOSE: EndDialog(hWnd, 0); return TRUE; case WM_INITDIALOG: hWinMain = hWnd; init();//Initialization return TRUE; case WM_COMMAND: switch(wParam) { case IDM_EXIT: EndDialog(hWnd, 0); return TRUE; case IDM_OPEN: dwStop = 0; CreateThread(NULL, 0, _OpenFile, &sClient, 0, NULL); return TRUE; case IDM_1: dwStop = 1; return TRUE; case IDM_2: case IDM_3: return TRUE; } } return FALSE; } //Append text to the text box void _AppendInfo(const TCHAR* lpsz) { CHARRANGE stCR; //Retrieve the length of the text in the text control stCR.cpMin = GetWindowTextLength(hWinEdit); stCR.cpMax = stCR.cpMin; //Select and replace the selected content of the text control SendMessage(hWinEdit, EM_EXSETSEL, 0, (LPARAM) & amp;stCR); SendMessage(hWinEdit, EM_REPLACESEL, FALSE, (LPARAM)lpsz); } //Exception callback function int CALLBACK _Handler(EXCEPTION_POINTERS* lpExceptionPoint) { const TCHAR szMsg[] = TEXT("Exception location: X, exception code: X, flag: X"); static TCHAR szBuffer[256]; PCONTEXT pContext; PEXCEPTION_RECORD pException; pContext = lpExceptionPoint->ContextRecord; pException = lpExceptionPoint->ExceptionRecord; wsprintf(szBuffer, szMsg, pContext->Eip, pException->ExceptionCode, pException->ExceptionFlags); //EXCEPTION_EXECUTE_HANDLER equ 1 I have handled the exception and can end gracefully //EXCEPTION_EXECUTE_HANDLER equ 0 I don’t handle it, let others handle it //EXCEPTION_EXECUTE_HANDLER equ -1 I fix it and continue execution from the exception return EXCEPTION_EXECUTE_HANDLER; } DWORD WINAPI _OpenFile(LPVOID lpParam) { OPENFILENAME stOF; HANDLE hFile, hMapFile; const TCHAR szExtPe[] = TEXT("PE File (*.exe)\0*.exe\0")\ TEXT("DLL File(*.dll)\0*.dll\0")\ TEXT("SCR File(*.scr)\0*.scr\0")\ TEXT("FON File(*.fon)\0*.fon\0")\ TEXT("DRV File(*.drv)\0*.drv\0")\ TEXT("ALL File(*.all)\0*.*\0"); const TCHAR szErr[] = TEXT("File format error!"); const TCHAR szErrFormat[] = TEXT("An error occurred while operating the file!"); static TCHAR szFileName[MAX_PATH]; //Initialize the open file dialog box RtlZeroMemory( & amp;stOF, sizeof(stOF)); stOF.lStructSize = sizeof(stOF); stOF.hwndOwner = hWinMain; stOF.lpstrFilter = szExtPe; stOF.lpstrFile = szFileName; stOF.nMaxFile = MAX_PATH; stOF.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; //Let the user select the file to open if (!GetOpenFileName( & amp;stOF)) { return 0; } //Step 1: Open the pe file hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); if (hFile == INVALID_HANDLE_VALUE) { MessageBox(NULL, TEXT("Failed to open file"), NULL, MB_ICONWARNING); } else { //Step 2: Get the file size totalSize = GetFileSize(hFile, NULL); //Create memory mapped file if(totalSize) { //Step 3: Create memory mapped file if (hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) { //Exception handling method 1: Register the exception handling callback function---run the exe program for exception handling, which will not be executed in VS. SetUnhandledExceptionFilter(_Handler); //Get the mapping starting position of the file in memory //Step 3: Create the view lpMemory = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); //Exception handling 2: if (!lpMemory) { atexit(Exception); exit(EXIT_FAILURE); } _Processing();//Start processing the file //error checking //ShowErrMsg(); goto _ErrorExit; _ErrFormat: MessageBox(hWinMain, szErrFormat, NULL, MB_OK); _ErrorExit: UnmapViewOfFile(lpMemory); } CloseHandle(hMapFile); } CloseHandle(hFile); } return 0; } //Exception handling voidException(void) { MessageBox(hWinMain, TEXT("Failed to obtain the starting position of the file image in the memory!"), NULL, MB_OK); }
ProcessPeFile.c code
#include<Windows.h> #include<ctype.h> extern int dwStop; extern int totalSize; extern char* lpMemory; void _AppendInfo(const TCHAR* lpsz);//Append text to the text box void _Processing() { TCHAR lpServicesBuffer[100]; //Buffer for each line TCHAR bufDisplay[50]; //The third line of ASCII code character display //TCHAR szBuffer[200]; //Temporary buffer TCHAR lpszFilterFmt4[] = TEXT(" X "); //First column address + two spaces TCHAR lpszFilterFmt3[] = TEXT(" X "); //First column address + 1 space TCHAR lpszManyBlanks[] = TEXT(" "); //spaces between columns TCHAR lpszBlank[] = TEXT(" "); //space character TCHAR lpszScanFmt[] = TEXT(" X"); //Not used TCHAR lpszHexArr[] = TEXT("0123456789ABCDEF"); TCHAR lpszDoubleReturn[]= TEXT("\r\\ \r\\ "); // TCHAR lpszReturn[] = TEXT("\r\\ "); TCHAR lpszOut1[] = TEXT("File size: %d"); TCHAR bufTemp1[10]; //16 hexadecimal bytecode TCHAR bufTemp2[20]; //Column 1 int dwCount; //Counting, the range of 0-16 is repeated int dwCountaddr; //address serial number int dwBlanks; //Number of spaces in the last line char ch = '.'; //Buffer initialization RtlZeroMemory(bufTemp1, 10); RtlZeroMemory(bufTemp2, 20); RtlZeroMemory(lpServicesBuffer, 100); //Buffer for each line RtlZeroMemory(bufDisplay, 50); //The third column of ASCII code character display TCHAR* lpDisplay = bufDisplay; \t dwCount = 1; //Write the first column to lpServicesBuffer dwCountaddr = 0; wsprintf(bufTemp2, lpszFilterFmt4, dwCountaddr);//First column address + two spaces lstrcat(lpServicesBuffer, bufTemp2); //Find the number of spaces in the last line (16-length)*3 dwBlanks = (16 - totalSize % 16) * 3; //Display file size //wsprintf(szBuffer, lpszOut1, totalSize); //MessageBox(NULL, szBuffer, NULL, MB_OK); \t while(TRUE) { if (totalSize == 0)//Last line { //Fill in spaces while (dwBlanks == 0) { lstrcat(lpServicesBuffer, lpszBlank); dwBlanks--; } //The space between the second and third columns lstrcat(lpServicesBuffer, lpszManyBlanks); //Third line content lstrcat(lpServicesBuffer, bufDisplay); //carriage return and line feed lstrcat(lpServicesBuffer, lpszReturn); break; } //Translate the bytecode into ASCII characters that can be displayed. Be careful not to destroy the value of the bytecode. // // if ((char)(*lpMemory) > 0x20 & amp; & amp; (char)(*lpMemory) < 0x7e) { *lpDisplay = (char)(*lpMemory); } else { *lpDisplay = ch; } //Write the second column to lpServicesBuffer wsprintf(bufTemp1, lpszFilterFmt3, (BYTE)*lpMemory); lstrcat(lpServicesBuffer, bufTemp1); if (dwCount == 16)//Already 16 bytes { //The space between the second and third columns lstrcat(lpServicesBuffer, lpszManyBlanks); //Display the characters in the third column lstrcat(lpServicesBuffer, bufDisplay); //carriage return and line feed lstrcat(lpServicesBuffer, lpszReturn); //write content _AppendInfo(lpServicesBuffer); RtlZeroMemory(lpServicesBuffer, 100); if (dwStop == 1) { break; } //Display the address of the next line dwCountaddr + + ; wsprintf(bufTemp2, lpszFilterFmt4, dwCountaddr); lstrcat(lpServicesBuffer, bufTemp2); dwCountaddr--; dwCount = 0; RtlZeroMemory(bufDisplay, 50); //In order to use edi with the later inc edi, try to locate it at bufDisplay lpDisplay = bufDisplay; lpDisplay--; } totalSize--; lpMemory + + ; lpDisplay + + ; dwCount + + ; dwCountaddr + + ; } //Add last line lstrcat(lpServicesBuffer, lpszDoubleReturn); _AppendInfo(lpServicesBuffer); }
resource.h file content
//{<!-- -->{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by PEforC1.rc // The next set of default values for the new object // #defineICO_MAIN 1000 #define DLG_MAIN 1000 #define IDC_INFO 1001 #define IDM_MAIN 2000 #define IDM_OPEN 2001 #define IDM_EXIT 2002 #define IDM_1 4000 #defineIDM_2 4001 #defineIDM_3 4002 #defineIDM_4 4003 #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
Resource file content
// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS / // // Generated from the TEXTINCLUDE 2 resource. // #include "winres.h" / #undef APSTUDIO_READONLY_SYMBOLS / // Chinese (Simplified, China) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED #pragma code_page(936) #ifdef APSTUDIO_INVOKED / // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\\ " "\0" END 3 TEXTINCLUDE BEGIN "\r\\ " "\0" END #endif // APSTUDIO_INVOKED / // //Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. ICO_MAIN ICON "main.ico" / // //Dialog DLG_MAIN DIALOG 50,50,544,399 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "PEDump by ZhangYJ" MENU IDM_MAIN FONT 9,"宋体" BEGIN CONTROL "",IDC_INFO,"RichEdit20A",196 | ES_WANTRETURN | WS_CHILD | ES_READONLY | WS_VISIBLE |WS_BORDER | WS_VSCROLL | WS_TABSTOP,0,0,540,396 END IDM_MAIN menu discardable BEGIN POPUP "File(&F)" BEGIN menuitem "Open file(&O)...",IDM_OPEN menuitem separator menuitem "Exit(&x)",IDM_EXIT END POPUP "Edit(&E)" BEGIN menuitem separator END POPUP "Format(&O)" BEGIN menuitem separator END POPUP "View( & amp;V)" BEGIN menuitem "Stop Dump...",IDM_1 menuitem "Window transparency",IDM_2 menuitem separator menuitem "size",IDM_3 menuitem "width",IDM_4 END POPUP "Help( & amp;H)" BEGIN menuitem separator END END / // //DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN DLG_MAIN, DIALOG BEGIN END END #endif // APSTUDIO_INVOKED / // //AFX_DIALOG_LAYOUT // DLG_MAIN AFX_DIALOG_LAYOUT BEGIN 0 END #endif // Chinese (Simplified, China) resources / #ifndef APSTUDIO_INVOKED / // // Generated from the TEXTINCLUDE 3 resource. // / #endif // not APSTUDIO_INVOKED