PE 文件自己码查看器的编写
#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);//往文本框中追加文本
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"系统错误", 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)&szDllEdit);
hInstance = GetModuleHandle(NULL);
DialogBoxParam(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgProc, (LPARAM)0);
FreeLibrary(hRichEdit);
return 0;
}
//初始化窗口函数
void init()
{
CHARFORMAT stCf;
TCHAR szClassEdit[] = TEXT("RichEdit20A");
TCHAR szFont[] = TEXT("宋体");
HINSTANCE hInstance;
hWinEdit = GetDlgItem(hWinMain, IDC_INFO);
//为窗口程序设置图标
hInstance = GetModuleHandle(NULL);
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ICO_MAIN));
SendMessage(hWinMain, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
//设置编辑控件
SendMessage(hWinEdit, EM_SETTEXTMODE, TM_PLAINTEXT, 0);
RtlZeroMemory(&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)&szFont);
SendMessage(hWinEdit, EM_SETCHARFORMAT, 0, (LPARAM)&stCf);
SendMessage(hWinEdit, EM_EXLIMITTEXT, 0, -1);
}
//富文本框回调函数
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();//初始化
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;
}
//往文本框中追加文本
void _AppendInfo(const TCHAR* lpsz)
{
CHARRANGE stCR;
//检索文本控件内文本的长度
stCR.cpMin = GetWindowTextLength(hWinEdit);
stCR.cpMax = stCR.cpMin;
//选择并替换文本控件的选定内容
SendMessage(hWinEdit, EM_EXSETSEL, 0, (LPARAM)&stCR);
SendMessage(hWinEdit, EM_REPLACESEL, FALSE, (LPARAM)lpsz);
}
//异常回调函数
int CALLBACK _Handler(EXCEPTION_POINTERS* lpExceptionPoint)
{
const TCHAR szMsg[] = TEXT("异常发生位置:%08X,异常代码:%08X,标志:%08X");
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 我已经处理了异常,可以优雅的结束
//EXCEPTION_EXECUTE_HANDLER equ 0 我不处理,其他人来处理吧
//EXCEPTION_EXECUTE_HANDLER equ -1 我修复,从异常处继续执行
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("文件格式错误!");
const TCHAR szErrFormat[] = TEXT("操作文件时出现错误!");
static TCHAR szFileName[MAX_PATH];
//初始化打开文件对话框
RtlZeroMemory(&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;
//让用户选择打开的文件
if (!GetOpenFileName(&stOF))
{
return 0;
}
//第1步:打开pe文件
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("打开文件失败"), NULL, MB_ICONWARNING);
}
else
{
//第2步:获取文件大小
totalSize = GetFileSize(hFile, NULL);
//创建内存映射文件
if (totalSize)
{
//第3步:创建内存映射文件
if (hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL))
{
//异常处理方法1:注册异常处理回调函数---运行exe程序进行异常处理,VS中运行不会进行
SetUnhandledExceptionFilter(_Handler);
//获取文件在内存的映射起始位置
//第3步:创建视图
lpMemory = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
//异常处理2:
if (!lpMemory)
{
atexit(Exception);
exit(EXIT_FAILURE);
}
_Processing();//开始处理文件
//错误检查
//ShowErrMsg();
goto _ErrorExit;
_ErrFormat:
MessageBox(hWinMain, szErrFormat, NULL, MB_OK);
_ErrorExit:
UnmapViewOfFile(lpMemory);
}
CloseHandle(hMapFile);
}
CloseHandle(hFile);
}
return 0;
}
//异常处理
void Exception(void)
{
MessageBox(hWinMain, TEXT("获取文件在内存的映象起始位置失败!"), NULL, MB_OK);
}
ProcessPeFile.c代码
#include<Windows.h>
#include<ctype.h>
extern int dwStop;
extern int totalSize;
extern char* lpMemory;
void _AppendInfo(const TCHAR* lpsz);//往文本框中追加文本
void _Processing()
{
TCHAR lpServicesBuffer[100]; //每行的缓冲区
TCHAR bufDisplay[50]; //第3行ASCII码字符显示
//TCHAR szBuffer[200]; //临时缓冲区
TCHAR lpszFilterFmt4[] = TEXT("%08X "); //第一列地址+两个空格
TCHAR lpszFilterFmt3[] = TEXT("%02X "); //第一列地址+1个空格
TCHAR lpszManyBlanks[] = TEXT(" "); //列间空格
TCHAR lpszBlank[] = TEXT(" "); //空格符
TCHAR lpszScanFmt[] = TEXT("%02X"); //未使用
TCHAR lpszHexArr[] = TEXT("0123456789ABCDEF");
TCHAR lpszDoubleReturn[]= TEXT("\r\n\r\n"); //
TCHAR lpszReturn[] = TEXT("\r\n");
TCHAR lpszOut1[] = TEXT("文件大小:%d");
TCHAR bufTemp1[10]; //16进制字节码
TCHAR bufTemp2[20]; //第1列
int dwCount; //计数,0-16的范围重复
int dwCountaddr; //地址序号
int dwBlanks; //最后一行的空格数
char ch = '.';
//缓冲区初始化
RtlZeroMemory(bufTemp1, 10);
RtlZeroMemory(bufTemp2, 20);
RtlZeroMemory(lpServicesBuffer, 100); //每行的缓冲区
RtlZeroMemory(bufDisplay, 50); //第三列ASCII码字符显示
TCHAR* lpDisplay = bufDisplay;
dwCount = 1;
//将第一列写入lpServicesBuffer
dwCountaddr = 0;
wsprintf(bufTemp2, lpszFilterFmt4, dwCountaddr);//第一列地址+两个空格
lstrcat(lpServicesBuffer, bufTemp2);
//求最后一行的空格数(16-长度%16)*3
dwBlanks = (16 - totalSize % 16) * 3;
//显示文件大小
//wsprintf(szBuffer, lpszOut1, totalSize);
//MessageBox(NULL, szBuffer, NULL, MB_OK);
while (TRUE)
{
if (totalSize == 0)//最后一行
{
//填充空格
while (dwBlanks == 0)
{
lstrcat(lpServicesBuffer, lpszBlank);
dwBlanks--;
}
//第二列与第三列中间的空格
lstrcat(lpServicesBuffer, lpszManyBlanks);
//第三行内容
lstrcat(lpServicesBuffer, bufDisplay);
//回车换行符
lstrcat(lpServicesBuffer, lpszReturn);
break;
}
//将字节码翻译成可以显示的ASCII码字符,注意不能破坏字节码的值
//
//
if ((char)(*lpMemory) > 0x20 && (char)(*lpMemory) < 0x7e)
{
*lpDisplay = (char)(*lpMemory);
}
else
{
*lpDisplay = ch;
}
//将第二列写入lpServicesBuffer
wsprintf(bufTemp1, lpszFilterFmt3, (BYTE)*lpMemory);
lstrcat(lpServicesBuffer, bufTemp1);
if (dwCount == 16)//已经16字节
{
//第二列与第三列中间的空格
lstrcat(lpServicesBuffer, lpszManyBlanks);
//显示第三列的字符
lstrcat(lpServicesBuffer, bufDisplay);
//回车换行
lstrcat(lpServicesBuffer, lpszReturn);
//写入内容
_AppendInfo(lpServicesBuffer);
RtlZeroMemory(lpServicesBuffer, 100);
if (dwStop == 1)
{
break;
}
//显示下一行的地址
dwCountaddr++;
wsprintf(bufTemp2, lpszFilterFmt4, dwCountaddr);
lstrcat(lpServicesBuffer, bufTemp2);
dwCountaddr--;
dwCount = 0;
RtlZeroMemory(bufDisplay, 50);
//为了能和后面的inc edi配合使用edi争取定位到bufDisplay处
lpDisplay = bufDisplay;
lpDisplay--;
}
totalSize--;
lpMemory++;
lpDisplay++;
dwCount++;
dwCountaddr++;
}
//添加最后一行
lstrcat(lpServicesBuffer, lpszDoubleReturn);
_AppendInfo(lpServicesBuffer);
}
resource.h 文件内容
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by PEforC1.rc
// 新对象的下一组默认值
//
#define ICO_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
#define IDM_2 4001
#define IDM_3 4002
#define IDM_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
资源文件内容
// 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
/
// 中文(简体,中国) 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\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\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 "文件(&F)"
BEGIN
menuitem "打开文件(&O)...",IDM_OPEN
menuitem separator
menuitem "退出(&x)",IDM_EXIT
END
POPUP "编辑(&E)"
BEGIN
menuitem separator
END
POPUP "格式(&O)"
BEGIN
menuitem separator
END
POPUP "查看(&V)"
BEGIN
menuitem "停止Dump...",IDM_1
menuitem "窗口透明度",IDM_2
menuitem separator
menuitem "大小",IDM_3
menuitem "宽度",IDM_4
END
POPUP "帮助(&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 // 中文(简体,中国) resources
/
#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//
/
#endif // not APSTUDIO_INVOKED