PE dump bytecode viewer

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