加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
PE查看器Dlg.cpp 13.55 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
// PE查看器Dlg.cpp : 实现文件
//
#include "stdafx.h"
#include "PE查看器.h"
#include "PE查看器Dlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CPE查看器Dlg 对话框
CPE查看器Dlg::CPE查看器Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_PE_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CPE查看器Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_SectionList);
}
BEGIN_MESSAGE_MAP(CPE查看器Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_OPENFILE, &CPE查看器Dlg::OnBnClickedBtnOpenfile)
ON_BN_CLICKED(IDC_BTN_SEE, &CPE查看器Dlg::OnBnClickedBtnSee)
ON_BN_CLICKED(IDC_BTN_EXIT, &CPE查看器Dlg::OnBnClickedBtnExit)
ON_BN_CLICKED(IDC_RADIO_VirAddr, &CPE查看器Dlg::OnBnClickedRadioViraddr)
ON_BN_CLICKED(IDC_RADIO_OppVIrAddr, &CPE查看器Dlg::OnBnClickedRadioOppviraddr)
ON_BN_CLICKED(IDC_RADIO_FileOffset, &CPE查看器Dlg::OnBnClickedRadioFileoffset)
ON_BN_CLICKED(IDC_BTN_CAl, &CPE查看器Dlg::OnBnClickedBtnCal)
ON_BN_CLICKED(IDC_BNTADD, &CPE查看器Dlg::OnBnClickedBntadd)
END_MESSAGE_MAP()
// CPE查看器Dlg 消息处理程序
BOOL CPE查看器Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
InitSectionList();
m_hFile = NULL;
m_hMap = NULL;
m_lpBase = NULL;
m_pNTHdr = NULL;
m_pSecHdr = NULL;
m_pDosHdr = NULL;
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CPE查看器Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CPE查看器Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CPE查看器Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CPE查看器Dlg::OnBnClickedBtnOpenfile()
{
CFileDialog file(TRUE);
file.DoModal();
CString fileName=file.GetPathName();
if (fileName.IsEmpty())
{
AfxMessageBox(L"请选择文件路径");
return;
}
GetDlgItem(IDC_EDIT_FILEROOT)->SetWindowTextW(fileName);
FileCreate(fileName);
}
VOID CPE查看器Dlg::EnumSections()
{
int nSecNum = m_pNTHdr->FileHeader.NumberOfSections;
int i = 0;
CString StrTmp;
WCHAR SecName[8] = { 0 };
for (i = 0;i < nSecNum;++i)
{
MultiByteToWideChar(CP_ACP, 0, (LPCCH)m_pSecHdr[i].Name,sizeof(m_pSecHdr[i].Name), SecName, 7);
m_SectionList.InsertItem(i,SecName);
StrTmp.Format(L"%08X", m_pSecHdr[i].VirtualAddress);
m_SectionList.SetItemText(i, 1, StrTmp);
StrTmp.Format(L"%08X", m_pSecHdr[i].Misc.VirtualSize);
m_SectionList.SetItemText(i, 2, StrTmp);
StrTmp.Format(L"%08X", m_pSecHdr[i].PointerToRawData);
m_SectionList.SetItemText(i, 3, StrTmp);
StrTmp.Format(L"%08X", m_pSecHdr[i].SizeOfRawData);
m_SectionList.SetItemText(i, 4, StrTmp);
StrTmp.Format(L"%08X", m_pSecHdr[i].Characteristics);
m_SectionList.SetItemText(i, 5, StrTmp);
}
return VOID();
}
VOID CPE查看器Dlg::PaseBasePe()
{
CString StrTmp;
//入口地址
StrTmp.Format(L"%08X", m_pNTHdr->OptionalHeader.AddressOfEntryPoint);
SetDlgItemText(IDC_EDIT_ENTRY, StrTmp);
//映像基地址
StrTmp.Format(L"%08X", m_pNTHdr->OptionalHeader.ImageBase);
SetDlgItemText(IDC_EDIT_IMAEGBASE, StrTmp);
//连接器版本号
StrTmp.Format(L"%d.%d", m_pNTHdr->OptionalHeader.MajorLinkerVersion,
m_pNTHdr->OptionalHeader.MinorLinkerVersion);
SetDlgItemText(IDC_EDIT_VISION, StrTmp);
//节表数量
StrTmp.Format(L"%02X", m_pNTHdr->FileHeader.NumberOfSections);
SetDlgItemText(IDC_EDIT_SECTIONNUM,StrTmp);
//文件对齐值大小
StrTmp.Format(L"%08X", m_pNTHdr->OptionalHeader.FileAlignment);
SetDlgItemText(IDC_EDIT_FILEALIGN, StrTmp);
//内存对齐值大小
StrTmp.Format(L"%08X", m_pNTHdr->OptionalHeader.SectionAlignment);
SetDlgItemText(IDC_EDIT_MEMORYALIGN, StrTmp);
return VOID();
}
BOOL CPE查看器Dlg::FileCreate(CString szFileName)
{
m_hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (m_hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox(L"打开文件失败");
return FALSE;
}
m_hMap = CreateFileMapping(m_hFile, NULL,
PAGE_READWRITE /*| SEC_IMAGE*/,
NULL, NULL, NULL);
if (m_hMap == INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
AfxMessageBox(L"创建文件映射失败");
return FALSE;
}
m_lpBase = MapViewOfFile(m_hMap,
FILE_MAP_READ | FILE_SHARE_WRITE,
NULL, NULL, NULL);
if (m_lpBase == NULL)
{
CloseHandle(m_hMap);
CloseHandle(m_hFile);
AfxMessageBox(L"获取文件基址失败");
return FALSE;
}
return TRUE;
}
BOOL CPE查看器Dlg::IsPeFileAndGetPePionter()
{
m_pDosHdr = (PIMAGE_DOS_HEADER)m_lpBase;
if (m_pDosHdr->e_magic != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
m_pNTHdr = (PIMAGE_NT_HEADERS)((DWORD)m_lpBase + m_pDosHdr->e_lfanew);
if (m_pNTHdr->Signature != IMAGE_NT_SIGNATURE)
{
return FALSE;
}
m_pSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)&(m_pNTHdr->
OptionalHeader) + m_pNTHdr->
FileHeader.SizeOfOptionalHeader);
return TRUE;
}
VOID CPE查看器Dlg::InitSectionList()
{
m_SectionList.SetExtendedStyle(m_SectionList.GetExtendedStyle()
| LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
m_SectionList.InsertColumn(0, L"节名");
m_SectionList.InsertColumn(1, L"V.偏移");
m_SectionList.InsertColumn(2, L"V.大小");
m_SectionList.InsertColumn(3, L"R.偏移");
m_SectionList.InsertColumn(4, L"R.大小");
m_SectionList.InsertColumn(5, L"标志");
m_SectionList.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
m_SectionList.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
m_SectionList.SetColumnWidth(2, LVSCW_AUTOSIZE_USEHEADER);
m_SectionList.SetColumnWidth(3, LVSCW_AUTOSIZE_USEHEADER);
m_SectionList.SetColumnWidth(4, LVSCW_AUTOSIZE_USEHEADER);
m_SectionList.SetColumnWidth(5, LVSCW_AUTOSIZE_USEHEADER);
return VOID();
}
void CPE查看器Dlg::OnBnClickedBtnSee()
{
if (m_hMap == NULL || m_hFile == NULL || m_lpBase == NULL)
{
return;
}
if (!IsPeFileAndGetPePionter())
{
AfxMessageBox(L"错误");
return;
}
PaseBasePe();
EnumSections();
}
void CPE查看器Dlg::OnBnClickedBtnExit()
{
OnCancel();
}
void CPE查看器Dlg::OnCancel()
{
CloseHandle(m_hFile);
CloseHandle(m_hMap);
UnmapViewOfFile(m_lpBase);
CDialogEx::OnCancel();
}
void CPE查看器Dlg::OnBnClickedRadioViraddr()
{
m_nSelect=VIRADDR;
}
void CPE查看器Dlg::OnBnClickedRadioOppviraddr()
{
m_nSelect = OPPVIRADDR;
}
void CPE查看器Dlg::OnBnClickedRadioFileoffset()
{
m_nSelect = FILEOFFSET;
}
void CPE查看器Dlg::OnBnClickedBtnCal()
{
if (m_pNTHdr == NULL || m_pSecHdr == NULL)
{
return;
}
DWORD dwAddr;
dwAddr = GetAddr();
int nNum = GetAddrInSecNum(dwAddr);
ClaAddr(nNum,dwAddr);
}
DWORD CPE查看器Dlg::GetAddr()
{
CString szAddr;
DWORD dwAddr = 0;
switch (m_nSelect)
{
case VIRADDR:
GetDlgItemText(IDC_EDIT_VirAddr, szAddr);
HexStrToInt(szAddr,&dwAddr);
break;
case OPPVIRADDR:
GetDlgItemText(IDC_EDIT_OppVirAddr, szAddr);
HexStrToInt(szAddr, &dwAddr);
break;
case FILEOFFSET:
GetDlgItemText(IDC_EDIT_FileOffset, szAddr);
HexStrToInt(szAddr, &dwAddr);
break;
default:
break;
}
return dwAddr;
}
void CPE查看器Dlg::ClaAddr(int nSelNum, DWORD dwAddr)
{
DWORD dwVa = 0;
DWORD dwRva = 0;
DWORD dwFileOffset = 0;
switch(m_nSelect)
{
case VIRADDR:
dwVa = dwAddr;
if (dwVa<m_pNTHdr->OptionalHeader.ImageBase)
{
AfxMessageBox(L"虚拟地址输入错误!虚拟地址不可能比映像基址小");
return;
}
dwRva = dwVa - m_pNTHdr->OptionalHeader.ImageBase;
dwFileOffset = m_pSecHdr[nSelNum].PointerToRawData + (dwRva - m_pSecHdr[nSelNum].VirtualAddress);
break;
case OPPVIRADDR:
dwVa = dwAddr + m_pNTHdr->OptionalHeader.ImageBase;
dwRva = dwAddr;
dwFileOffset = m_pSecHdr[nSelNum].PointerToRawData + (dwRva - m_pSecHdr[nSelNum].VirtualAddress);
break;
case FILEOFFSET:
dwFileOffset = dwAddr;
dwRva = m_pSecHdr[nSelNum].VirtualAddress + (dwFileOffset - m_pSecHdr[nSelNum].PointerToRawData);
dwRva = dwVa - m_pNTHdr->OptionalHeader.ImageBase;
break;
default:
break;
}
WCHAR Name[8] = { 0 };
MultiByteToWideChar(CP_ACP, 0, (LPCCH)m_pSecHdr[nSelNum].Name, sizeof(m_pSecHdr[nSelNum].Name), Name, 7);
SetDlgItemText(IDC_EDIT_Section,Name);
CString str;
str.Format(L"%08X", dwVa);
SetDlgItemText(IDC_EDIT_VirAddr, str);
str.Format(L"%08X", dwRva);
SetDlgItemText(IDC_EDIT_OppVirAddr, str);
str.Format(L"%08X", dwFileOffset);
SetDlgItemText(IDC_EDIT_FileOffset, str);
}
int CPE查看器Dlg::GetAddrInSecNum(DWORD dwAddr)
{
int nInNum = 0;
int nSecNun = m_pNTHdr->FileHeader.NumberOfSections;
DWORD dwImageBase = 0;
switch (m_nSelect)
{
case VIRADDR:
dwImageBase = m_pNTHdr->OptionalHeader.ImageBase;
for (nInNum = 0;nInNum < nSecNun;nInNum++)
{
if (dwAddr >= dwImageBase + m_pSecHdr[nInNum].VirtualAddress&&
dwAddr <= dwImageBase + m_pSecHdr[nInNum].VirtualAddress +
m_pSecHdr[nInNum].Misc.VirtualSize)
return nInNum;
}
break;
case OPPVIRADDR:
for (nInNum = 0;nInNum < nSecNun;nInNum++)
{
if (dwAddr >= m_pSecHdr[nInNum].VirtualAddress&&
dwAddr <= m_pSecHdr[nInNum].VirtualAddress +
m_pSecHdr[nInNum].Misc.VirtualSize)
return nInNum;
}
break;
case FILEOFFSET:
for (nInNum = 0;nInNum < nSecNun;nInNum++)
{
if (dwAddr >= m_pSecHdr[nInNum].PointerToRawData&&
dwAddr <= m_pSecHdr[nInNum].PointerToRawData +
m_pSecHdr[nInNum].SizeOfRawData)
return nInNum;
}
break;
default:
break;
}
return -1;
}
void CPE查看器Dlg::HexStrToInt(CString szAddr, DWORD * dwAddr)
{
DWORD Addr = 0;
for (int i = 0;i < szAddr.GetLength();i++)
{
Addr += ((szAddr[i]>='A'&&szAddr[i]<='F'|| szAddr[i] >= 'a'&&szAddr[i] <= 'f')?szAddr[i]-'A'+10:szAddr[i]-'0')*
pow(16, szAddr.GetLength() - i - 1);
}
*dwAddr = Addr;
}
void CPE查看器Dlg::OnBnClickedBntadd()
{
WCHAR szSecName[8] = { 0 };
int nSize = 0;
GetDlgItemText(IDC_EDIT_SECNAME, szSecName, 8);
nSize = GetDlgItemInt(IDC_EDIT_SECSIZE, FALSE, TRUE);
AddSec(szSecName, nSize);
}
void CPE查看器Dlg::AddSec(WCHAR * szSecName, int nSecSIze)
{
int nSecNum = m_pNTHdr->FileHeader.NumberOfSections;
DWORD dwFileAligment = m_pNTHdr->OptionalHeader.FileAlignment;
DWORD dwSecAlignment = m_pNTHdr->OptionalHeader.SectionAlignment;
PIMAGE_SECTION_HEADER pTmpSec = m_pSecHdr + nSecNum;
char SecName[8] = { 0 };
//MultiByteToWideChar(CP_ACP, 0, (LPCCH)m_pSecHdr[nSelNum].Name, sizeof(m_pSecHdr[nSelNum].Name), Name, 7);
WideCharToMultiByte(CP_ACP, 0, szSecName, 7, SecName,7, NULL, FALSE);
strncpy((char*)pTmpSec->Name, SecName, 8);
pTmpSec->Misc.VirtualSize = AlignSIze(nSecSIze, dwSecAlignment);
pTmpSec->VirtualAddress = m_pSecHdr[nSecNum - 1].VirtualAddress + AlignSIze(m_pSecHdr[nSecNum - 1].Misc.VirtualSize, dwSecAlignment);
pTmpSec->SizeOfRawData = AlignSIze(nSecSIze, dwFileAligment);
pTmpSec->PointerToRawData = m_pSecHdr[nSecNum - 1].PointerToRawData + AlignSIze(m_pSecHdr[nSecNum - 1].SizeOfRawData, dwSecAlignment);
m_pNTHdr->FileHeader.NumberOfSections++;
m_pNTHdr->OptionalHeader.SizeOfImage += pTmpSec->Misc.VirtualSize;
FlushViewOfFile(m_lpBase, 0);
AddSecData(pTmpSec->SizeOfRawData);
EnumSections();
}
void CPE查看器Dlg::AddSecData(DWORD Size)
{
PBYTE pByte = NULL;
pByte = (PBYTE)malloc(Size);
ZeroMemory(pByte, Size);
DWORD dwNum = 0;
SetFilePointer(m_hFile, 0, 0, FILE_END);
WriteFile(m_hFile, pByte, Size, &dwNum, NULL);
FlushFileBuffers(m_hFile);
free(pByte);
}
DWORD CPE查看器Dlg::AlignSIze(int nSecSIze, DWORD dwAlignment)
{
int nSize = nSecSIze;
if (nSize%dwAlignment != 0)
{
nSecSIze = (nSize / dwAlignment + 1) * dwAlignment;
}
return nSecSIze;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化