返回列表 发帖

[讨论]C++简单判断PE文件有效性详解

[讨论]C++简单判断PE文件有效性详解
议题作者:xxfish
信息来源:邪恶八进制信息安全团队(www.eviloctal.com

注:本文章首发黑客防线,后由原作者友情提交到邪恶八进制信息安全团,转载请注明首发站点。

部分内容参照看雪的《加密解密 技术内幕》,不过那个是汇编写的..因为偶最近学习c++所以就写个c++版的嘿...

今天早上学习PE文件结构,把自己的一点点心得发出来与大家一起分享,嘿,不要拿板砖拍我.......
PE文件结构的资料很多,但是大多都是讲的理论... 我等小菜,如果不实践操作,看了也等于白看。嘿..好先来看下PE文件的框架..

PE文件框架构成
DOS MZ header
DOS stub
PE header
Section table
Section 1
Section 2
Section ...
Section n

我们今天只看DOS MZ 头 和 PE HEADER就行了..因为我们仅仅判断PE文件的有效性...

首先先给大家介绍下DOS MZ header和PE HEADER吧,DOS MZ headerder的结构是_IMAGE_DOS_HEADER,首先大家看下_IMAGE_DOS_HEADER的结构图,当然这里我就不全给大家表示了,因为我们只需要了解_IMAGE_DOS_HEADER结构两个重要的域e_magic和e_lfnew。
复制内容到剪贴板
代码:
typedef struct __IMAGE_DOS_HEADER
{
WORD e_magic //它用来表示一个MS_DOS兼容的文件类型,所有的MS_DOS兼容可执行文件都将这个值设为0x5A4D,表示ASCII字符就是MZ.

LONG e_lfanew//它是一个文件偏移量,我们的PE头就是它来定位的

}IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;

接下来给大家介绍下IMAGE_NT_HEADERS结构
复制内容到剪贴板
代码:
typedef struct IMAGE_NT_HEADERS
{
DWORD Signature //pe文件头标志"PE\0\0"我们可以此识别给定文件是否为有效PE文件。


//我就不列完全了,因为我们只需要了解这个重要域就可以了...
}IMAGE_NT_HEADERS32,&IMAGE_NT_HEADERS32
看到这里大家肯定应该可以想到,__IMAGE_DOS_HEADER的e_magic域是来表示MS_DOS的兼容类型的,并且它的e_lfanew是我们PE头的偏移量..而IMAGE_NT_HEADERS的Signature域则PE文件头标志,所以这里我想大家应该明白怎么来判断PE文件的有效性了吧。

这里我举个例子,因为一个PE文件遵循的都是上面的PE文件框架图,所以首先检验文件头部第一个字的值是否等于 IMAGE_DOS_SIGNATURE,是则 DOS MZ header 有效。 一旦证明文件的 DOS header 有效后,就可用e_lfanew来定位 PE header 了。 比较 PE header 的第一个字的值是否等于 IMAGE_NT_HEADER。如果前后两个值都匹配,那我们就认为该文件是一个有效的PE文件。  

这里我贴一个用C++Builder写的一段判断PE文件有效性的代码..
复制内容到剪贴板
代码:
IMAGE_DOS_HEADER DosHeader;
IMAGE_NT_HEADERS32 ExeHeder;
FILE *fp;
fp=fopen(Edit1->Text.c_str(),"r");
fseek(fp,0,SEEK_SET);
fread(&DosHeader,sizeof(DosHeader),1,fp);//读取IMAGE_DOS_HEADER结构的大小到DosHeader成员
if (DosHeader.e_magic!=IMAGE_DOS_SIGNATURE)//判断 e_magic是否等于ASCII字符"MZ","MZ"等于16进制5A4Dh ,IMAGE_DOS_SIGNATURE是定义的常量相当于5A4Dh

{
  ShowMessage("不是有效的MZ文件");
}
fseek(fp,DosHeader.e_lfanew,SEEK_SET);//通过e_lfanew域来到PE头位置
fread(&ExeHeder,sizeof(ExeHeder),1,fp);//同上读取相同 IMAGE_NT_HEADERS32结构大小到ExeHeder成员
if (ExeHeder.Signature!=IMAGE_NT_SIGNATURE)//判断 Signature域 是否等于4550h,4550H相当于ASCII字符串就是"PE",IMAGE_NT_SIGNATURE 常量相当于4550h
{
    ShowMessage("不是有效的PE文件");
}
else
{
ShowMessage("是有效的PE文件");

}
fclose(fp);
因为小弟只是把自己早上的心得发表出来,如有错误请各位大牛指正,小弟好学习学习.....
帖子31 精华0 积分3128 阅读权限100 在线时间57 小时 注册时间2008-1-3 最后登录2008-7-20 查看详细资料TOP 让女孩一夜变的更有女人味

asm
运维管理组

补一个: 校验 SizeOfOptionalHeader 来确认PE文件结构的正确性

来个以前的学习PE的笔记。祝LZ早日进步,呵呵
附件
sudami之PE学习笔记.rar (323 KB)
2008-1-4 21:54, 下载次数: 107
PE格式检测.rar (48 KB)
2008-1-4 21:54, 下载次数: 35 WINDOWS内核疯狂爱好者
帖子242 精华6 积分5536 阅读权限150 性别男 在线时间1113 小时 注册时间2007-1-10 最后登录2008-7-23 查看个人网站
查看详细资料TOP 爱要怎么说出口

xxfish
荣誉会员

TOP

CreateFile---CreateFileMapping---MapViewOfFile---返回@lpMemory,然后:
mov  esi,@lpMemory
assume  esi:ptr IMAGE_DOS_HEADER
.if  [esi].e_magic != IMAGE_DOS_SIGNATURE
jmp  _ErrFormat
.endif
add  esi,[esi].e_lfanew
assume  esi:ptr IMAGE_NT_HEADERS
.if  [esi].Signature != IMAGE_NT_SIGNATURE
jmp  _ErrFormat
.endif游戏吧  http://www.game8.cc/MyBlog    http://www.asm32.cn
帖子1604 精华30 积分8760 阅读权限150 性别男 在线时间954 小时 注册时间2006-9-21 最后登录2008-7-24 查看详细资料TOP 少女暴富的隐秘(图)

sudami
大米米

运维管理组

TOP

返回列表