吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 5301|回复: 20

[精品软件] PE查看器+源代码。快速学习PE格式

  [复制链接]
yl1003 发表于 2015-4-5 18:33 | 显示全部楼层 |阅读模式

             大家好。
            先说几句题外话,是关于《恶意代码拦截插件1.1》的问题,由于一些问题。导致我并没有什么时间更新和修改BUG。
       可能部分用户会不能正常拦截。楼主有空的话再进行更新和修复。最近两天在学习PE格式。
本次的软件非常简单,只是学习PE格式顺手写下来的小软件。强烈建议论坛开一个编程板块。。。。好吧,牢骚结束。下面开始介绍。此篇文章与其说软件发布,不与说是PE格式的学习。
        软件界面:
2.jpg

           下面看看示意图,
图片1.png
这是PE的头部示意图。
看下面几个结构
PE文件中的DOS部分由MZ格式的文件头和可执行代码部分组成,可执行代码被称为“DOS块”(DOS stub)。MZ格式的文件头由IMAGE_DOS_HEADER结构定义:
  IMAGE_DOS_HEADER STRUCT
   e_magic WORD ? ;DOS可执行文件标记,为“MZ”
   e_cblp WORD ?
   e_cp WORD ?
   e_crlc WORD ?
   e_cparhdr WORD ?
   e_minalloc WORD ?
   e_maxalloc WORD ?
   e_ss WORD ? ;DOS代码的初始化堆栈段
   e_sp WORD ? ;DOS代码的初始化堆栈指针
   e_csum WORD ?
   e_ip WORD ? ;DOS代码的入口IP
   e_cs WORD ? ;DOS代码的入口CS
   e_lfarlc WORD ?
   e_ovno WORD ?
   e_res WORD  4 dup(?)
   e_oemid WORD ?
   e_oeminfo WORD ?
   e_res2 WORD 10 dup(?)
   e_lfanew DWORD ? ;指向PE文件头
  IMAGE_DOS_HEADER ENDS
DOS文件头的前面部分并不陌生,第一个字段e_magic被定义成字符“MZ”(在Windows.inc文件中已经预定义为IMAGE_DOS_SIGNATURE)作为识别标志,后面的一些字段指明了入口地址、堆栈位置和重定位表位置等。

  其中我们还要关心的是e_lfanew这个字段,e_lfanew字段是真正PE文件头的相对偏移(RVA),其指出真正PE头的文件偏移位置,它占用四个字节,位于文件开始偏移3Ch字节中。
IMAGE_NT_HEADERS STRUCT
Signature DWORD ? ;PE文件标识
FileHeader    IMAGE_FILE_HEADER    <>
OptionalHeader   IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS
而里面的IMAGE_OPTIONAL_HEADER32有如下值
IMAGE_OPTIONAL_HEADER32 STRUCT
Magic WORD ? ;0018h 107h=ROM Image,10Bh=exe Image
MajorLinkerVersion BYTE ? ;001ah 链接器版本号
MinorLinkerVersion BYTE ? ;001bh
SizeOfCode DWORD ? ;001ch 所有含代码的节的总大小
SizeOfInitializedData DWORD? ;0020h所有含已初始化数据的节的总大小
SizeOfUninitializedData DWORD ? ;0024h 所有含未初始化数据的节的大小
AddressOfEntryPoint DWORD ? ;0028h 程序执行入口RVA
BaseOfCode DWORD ? ;002ch 代码的节的起始RVA
BaseOfData DWORD ? ;0030h 数据的节的起始RVA
ImageBase DWORD ? ;0034h 程序的建议装载地址
SectionAlignment DWORD ? ;0038h 内存中的节的对齐粒度
FileAlignment DWORD ? ;003ch 文件中的节的对齐粒度
MajorOperatingSystemVersion WORD ? ;0040h 操作系统主版本号
MinorOperatingSystemVersion WORD ? ;0042h 操作系统副版本号
MajorImageVersion WORD ? ;0044h可运行于操作系统的最小版本号
MinorImageVersion WORD ? ;0046h
MajorSubsystemVersion WORD ?;0048h 可运行于操作系统的最小子版本号
MinorSubsystemVersion WORD ? ;004ah
Win32VersionValue DWORD ? ;004ch 未用
SizeOfImage DWORD ? ;0050h 内存中整个PE映像尺寸
SizeOfHeaders DWORD ? ;0054h 所有头+节表的大小
CheckSum DWORD ? ;0058h
Subsystem WORD ? ;005ch 文件的子系统
DllCharacteristics WORD ? ;005eh
SizeOfStackReserve DWORD ? ;0060h 初始化时的堆栈大小
SizeOfStackCommit DWORD ? ;0064h 初始化时实际提交的堆栈大小
SizeOfHeapReserve DWORD ? ;0068h 初始化时保留的堆大小
SizeOfHeapCommit DWORD ? ;006ch 初始化时实际提交的堆大小
LoaderFlags DWORD ? ;0070h 未用
NumberOfRvaAndSizes DWORD ? ;0074h 下面的数据目录结构的数量
DataDirectory    IMAGE_DATA_DIRECTORY 16 dup(<>) ;0078h
IMAGE_OPTIONAL_HEADER32 ENDS


IMAGE_SECTION_HEADERS结构
IMAGE_SECTION_HEADER STRUCT
  Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?) ;8个字节的节区名称
  union Misc
  PhysicalAddress dd ?
  VirtualSize dd ? ;节区的尺寸
  ends
  VirtualAddress dd ? ;节区的RVA地址
  SizeOfRawData dd ? ;在文件中对齐后的尺寸
  PointerToRawData dd ? ;在文件中的偏移
  PointerToRelocations dd ? ;在OBJ文件中使用
  PointerToLinenumbers dd ? ;行号表的位置(供调试用)
  NumberOfRelocations dw ? ;在OBJ文件中使用
  NumberOfLinenumbers dw ? ;行号表中行号的数量
  Characteristics dd ? ;节的属性
IMAGE_SECTION_HEADER ENDS
看这些结构知道,
图片2.jpg

DOS头e_lfanew---->指向IMAGE_NT_HEADERS结构
而IMAGE_SECTION_HEADER=e_lfanew+IMAGE_NT_HEADERS
也就是指向节。

代码很短,看看代码做了哪些工作?
//打开文件 strFilePath指出了路径
HANDLE hFile = CreateFile(strFilePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
  MessageBox(L"文件打开错误", L"错误");
  return ;
}
IMAGE_DOS_HEADER dosHeader;//声明ODS_HEADER结构
BOOL bRet;
DWORD readSize;
bRet = ReadFile(hFile, &dosHeader, sizeof(dosHeader), &readSize, NULL);//获取结构内容
if (!bRet)
{
  MessageBox(L"读取错误", L"错误");
  CloseHandle(hFile);
  return ;
}
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE)//判断dosHeader.e_magic 是否为IMAGE_DOS_SIGNATURE,也就是"MZ"。打开winhex可以看到PE头的这两个字符。
{
  MessageBox(L"不是PE文件", L"错误");
}
printf("DOS头长度:%X\n", dosHeader.e_lfanew);
IMAGE_NT_HEADERS peHeader;//IMAGE_NT_HEADERS 结构
SetFilePointer(hFile, dosHeader.e_lfanew, NULL, FILE_BEGIN);//定位指针到dosHeader.e_lfanew,上面说到dosHeader.e_lfanew刚好指向IMAGE_NT_HEADERS

bRet = ReadFile(hFile, &peHeader, sizeof(peHeader), &readSize, NULL);
if (!bRet)
{
  MessageBox(L"读取错误", L"错误");
  return ;
  CloseHandle(hFile);
}
if (peHeader.Signature != IMAGE_NT_SIGNATURE)//跟上面的MZ一样,判断Signature是否是"PE"这两个字符
{
  MessageBox(L"不是PE文件", L"错误");
  return ;
  CloseHandle(hFile);
}
IMAGE_OPTIONAL_HEADER32 imOpHeader; // IMAGE_OPTIONAL_HEADER32结构
imOpHeader = peHeader.OptionalHeader;
CStringW Goep, GimageB, GCode, GImageSize, GDimage;
Goep.Format(L"%08X", imOpHeader.AddressOfEntryPoint);//从结构里获取程序的入口地址(这里是文件偏移地址,内存中会加上基址,一般是04000000)
GimageB.Format(L"%08X", imOpHeader.ImageBase);//获取基址
GCode.Format(L"%08X", imOpHeader.BaseOfCode);
GImageSize.Format(L"%08X", imOpHeader.SizeOfImage);//获取基址大小
GDimage.Format(L"%08X", imOpHeader.BaseOfData);//数据大小
下面这些是显示出来。不做解释
SetDlgItemText(IDC_EDIT2, GimageB);
SetDlgItemText(IDC_EDIT3, Goep);
SetDlgItemText(IDC_EDIT4, GCode);
SetDlgItemText(IDC_EDIT5, GImageSize);
SetDlgItemText(IDC_EDIT6, GDimage);
IMAGE_SECTION_HEADER Section;
int ii = peHeader.FileHeader.NumberOfSections;//段数目。NumberOfSections指向节的数目
int iii = 0;
iii = dosHeader.e_lfanew + sizeof(peHeader);
int s = sizeof(Section);
m_list.DeleteAllItems();
for (int i = 0; i < ii; i++)
{
  SetFilePointer(hFile, iii + s*i, NULL, FILE_BEGIN);//定位指针到节的位置
  bRet = ReadFile(hFile, &Section, sizeof(Section), &readSize, NULL);
  if (!bRet)
  {
   MessageBox(L"读取错误",L"错误");
   return ;
   CloseHandle(hFile);
  }

  CString namea,Vaddr,Vsize,Raddr,Rsize;
  namea.Format(L"%S", Section.Name);
  Vaddr.Format(L"%08X", Section.VirtualAddress);//--
  Vsize.Format(L"%08X", Section.Misc);
  Raddr.Format(L"%08X", Section.PointerToRawData);
      Rsize.Format(L"%08X", Section.SizeOfRawData);//--
  m_list.InsertItem(i , namea);
  m_list.SetItemText(i, 1, Vaddr);//--
  m_list.SetItemText(i , 2, Vsize);
  m_list.SetItemText(i, 3, Raddr);
  m_list.SetItemText(i , 4, Rsize);//--
}
源码放送。。。
游客,如果您要查看本帖隐藏内容请回复

评分

参与人数 12HB +14 THX +4 收起 理由
虚心学习 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
zxjzzh + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
消逝的过去 + 1
DeeDarrick + 1
agan8888 + 1
ch_1943 + 1
h112233h456 + 1
leo999 + 1
别管我了行 + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
playboy + 1
muker + 1
逍遥绝尘 + 6 + 1 ★★★★★ 热心人,佛祖保佑你事事顺利 ,财源滚滚!!!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
童话Wayn 发表于 2015-4-5 18:44 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
逍遥绝尘 发表于 2015-4-5 18:46 | 显示全部楼层

嗯!不错的软件!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
 楼主| yl1003 发表于 2015-4-5 18:55 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
40960725 发表于 2015-4-20 10:43 | 显示全部楼层

完全看不懂!!!!!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
gujin162 发表于 2015-5-6 08:35 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
 楼主| yl1003 发表于 2015-5-6 12:48 | 显示全部楼层

gujin162 发表于 2015-5-6 08:35
这个学会了是不是可以欺骗查壳工具?

可以的。
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
xpj4258a 发表于 2015-10-9 14:11 | 显示全部楼层

好 陈年老帖
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
526413341 发表于 2015-11-3 12:54 | 显示全部楼层

我来看一下
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
sava 发表于 2016-2-9 06:10 | 显示全部楼层

非常实用!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表