深入浅出PE文件格式---自己动手打造PE Show
作者:WiNrOOt
////////////////////////////////////////////////////////////////////
// 开篇 //
///////////////////////////////////////////////////////////////////
大家好!我一位菜鸟,学习加密解密已经有一段时间了,可是对于脱壳总是似懂非懂,心中甚是不爽。
于是就从PE结构开始,在学习的过程中我发现要真正了解PE文件结构就必须动手,只有动手您才能看懂他,
感受他,直到你应用他………………这是我的一点废话希望大家不要嫌烦。下面是是我的学习笔记,希望能给大家
带来一点提示,文中有不对的地方请各位大虾指正。谢谢!
//////////////////////////////////////////////////////////////////
// 准备 //
/////////////////////////////////////////////////////////////////
开篇之前我想大家起码要有几点准备:
1。Iczelion's Win32 Assembly的教程我们主要是围绕他的PE教程来实现我们的函数功能。
(其实Win32ASM Tutorial Resource Kit v1.00 Collected and packed by dREAMtHEATER就包含这些
还是翻译过的。下载地址WWW.PEDIY.COM )
下载回来希望您能看一下,这样大家就好交流:-)
2。一个开发环境。(我用的是VC++6.0)
3。一个适合你研究东西的环境。
////////////////////////////////////////////////////////////////
// 正文 //
///////////////////////////////////////////////////////////////
“ PE 的意思就是 Portable Executable(可移植的执行体)。它是 Win32环境自身所带的执行体文件格
式。它的一些特性继承自 Unix的 Coff (common object file format)文件格式。"portable executable"
(可移植的执行体)意味着此文件格式是跨win32平台的 :
即使Windows运行在非Intel的CPU上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不
同的CPU上PE执行体必然得有一些改变。所有 win32执行体
(除了VxD和16位的Dll)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode
drivers)。因而研究PE文件格式给了我们洞悉Windows结构的良机。“
好了,上面这段话就是我们为什么要研究PE文件结构。
看图 ,这张图我相信大家不陌生,第一块是DOS MZ header这是什么呢?
这张图的每一块都是什么意思呢?
从编程这方面说图中的每一块都代表着一个结构体,这些小块都包含有不同的子块,也是些结构体。
每个小块都有他自己的功能,我相信Iczelion's的教程中已经表达得很明白了。
那么我们就来开始动手。
我们要设计我们自己的PE TOOLS----PE Show
主要功能:1判断文件是否是PE文件。
2显示pe文件的相关信息。
1.打开文件代码如下:
if(FALSE==PEfile.Open(m_filename,CFile::typeBinary|CFile::shareDenyNone))
{
MessageBox("文件打不开!");
return;
}
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
IMAGE_NT_SIGNATURE供我们使用。
IMAGE_DOS_SIGNATURE equ 5A4Dh
IMAGE_OS2_SIGNATURE equ 454Eh
IMAGE_OS2_SIGNATURE_LE equ 454Ch
IMAGE_VXD_SIGNATURE equ 454Ch
IMAGE_NT_SIGNATURE equ 4550h
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
PEfile.Read(&stPEDosHeader,sizeof(_IMAGE_DOS_HEADER));
if(stPEDosHeader.e_magic!=IMAGE_DOS_SIGNATURE)//"MZ"
{
MessageBox("DOS MZ header无效!");
PEfile.Close();
return;
}
else
{
//-----------------------
//显示DOS Header
//-----------------------
UpdateData(true);
m_Magicnumber.Format(_T("0x%.4X"),stPEDosHeader.e_magic);
m_cblp.Format(_T("0x%.4X"),stPEDosHeader.e_cblp);
m_cp.Format(_T("0x%.4X"),stPEDosHeader.e_cp);
m_crlc.Format(_T("0x%.4X"),stPEDosHeader.e_crlc);
m_cparhdr.Format(_T("0x%.4X"),stPEDosHeader.e_cparhdr);
m_minalloc.Format(_T("0x%.4X"),stPEDosHeader.e_minalloc);
m_maxalloc.Format(_T("0x%.4X"),stPEDosHeader.e_maxalloc);
m_ss.Format(_T("0x%.4X"),stPEDosHeader.e_ss);
m_sp.Format(_T("0x%.4X"),stPEDosHeader.e_sp);
m_csum.Format(_T("0x%.4X"),stPEDosHeader.e_csum);
m_ip.Format(_T("0x%.4X"),stPEDosHeader.e_ip);
m_cs.Format(_T("0x%.4X"),stPEDosHeader.e_cs);
m_lfarlc.Format(_T("0x%.4X"),stPEDosHeader.e_lfarlc);
m_ovno.Format(_T("0x%.4X"),stPEDosHeader.e_ovno);
m_oemid.Format(_T("0x%.4X"),stPEDosHeader.e_oemid);
m_oeminfo.Format(_T("0x%.4X"),stPEDosHeader.e_oeminfo);
m_lfanew.Format(_T("0x%.8X"),stPEDosHeader.e_lfanew);
UpdateData(false);
}
buf=stPEDosHeader.e_lfanew; //确定_IMAGE_DOS_HEADER偏移
try{PEfile.Seek(buf,CFile::begin);}
catch(...)
{
MessageBox("_IMAGE_DOS_HEADER.e_lfanew不对!");
PEfile.Close();
return;
}
PEfile.Read(&stPEHeader,sizeof(_IMAGE_NT_HEADERS));//----------NT头
if(stPEHeader.Signature!=IMAGE_NT_SIGNATURE)//"PE\0\0"
{
MessageBox("该文件不是PE格式!");
PEfile.Close();
return;
}
else
{
MessageBox("该文件是PE格式!");
PEfile.Close();
return;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)