the art of disassembly charpter01---lesson1---01

(1)overview of the pe format

          PE文件的整体概况:

                                             DOS  MZ  HEADERS

                                                 DOS   STUB

                                             PE    HEADER

                                            SECTION TABLE

                                            SETCTION  1

                                            SETCTION 2

                                            SETCTION n



1、当pe文件运行的时候,PE加载器检查DOS MZ的文件头去找到PE文件头的偏移地址,如若找到,则跳到PE文件头的开始部分。

2、PE加载器检查PE文件头的有效性,如若有效的,则跳到PE文件头的尾部,也即是节表的开始处。

3、PE加载器得到各个节的数据并使用内存文件映射的方法将它们映射到内存之中,同时根据各个节的属性赋予相应内存页的属性。

4、在PE文件被映射被内存之后,PE加载器开始关注PE文件的逻辑部分,即,导入表、导出表、重定位表等等。

(2)detecting a valid pe format

检查一个文件是否是一个有效的PE文件主要取决于你想要多么准确的查检。你可以查检相应于PE文件的每一个结构来确定,也可以仅仅检查一些关键的字段。

通过我们检查一些关键的字段来判断一个文件是否是一个有效的PE文件。如若关键字段已符合,那么我们就初步的断定此文件是一个有效的PE文件了。


     有效性的检查针对PE文件头,下面我们给出PE文件的结构

        IMAGE_NT_HEADERS  STRUCT

                Signature          dd           ?

                FileHeader        IMAGE_FILE_HEADER <>

               OptionHeader   IMAGE_OPTIONAL_HEADER32 <>

      IMAGE_NT_HEADERS  ENDS

  对于一个有效有PE文件  Signature 字段为: 'PE',0,0.。为了方便起见,MS已将此值定义为一个常量IMAGE_NT_SIGNATURE

现在的问题在于,我们怎么得到PE文件头的位置。答案是:由DOS MZ 文件头给出,DOS MZ 文件头已被定义为IMAGE_DOS_HEADER结构,由此结构的e_lfanew字段

就可以得到PE文件头在文件中的偏移值。

===================================================================================

现在来总结一下检查一个文件是否为PE文件的步骤:

                1、核实所给你的文件是否有一个有效的DOS 文件头,方法是:将文件的第一个字与IMAGE_DOS_SIGNAUTE作比较,如若两者相等,则取得成员e_lfanew字段的值

 得到PE文件头的偏移,从而得到PE文件头在文件中的实际位置

              2、比较PE文件头的第一个字是否与IMAGE_NT_SIGNATURE相等,

             3、若两者都相等,则我们就可以初步的认为这是一个有效的PE文件了

now Here comes An EXAMPLE:

SEH  STRUCT 

         PreLink

         Hanlder

         SafePlace

         preEbp

        preEsp

SEH  ENDS

  CheckPeFile      proc  lpMemory

                                local @seh:SEH

                                local @Valid

                                mov @Valid,FALSE

                               assume fs:nothing

                               push  fs:[0]

                               pop   @seh.PreLink

                               mov   @seh.SafePlace,offset SafePlace

                               mov   @seh.Hanlder,offset  Handler

                              mov    @seh.preEbp.ebp

                              mov    @seh.preEsp,esp

                              lea       eax,@seh

                              mov    fs:[0],eax

                             mov     edi,lpMemory

                             assume edi:ptr IMAGE_DOS_HEADER

                            .if   [edi].e_magic==IMAGE_DOS_SIGNATURE

                                     add edi,[edi].e_lfanew
                                     assume edi:ptr IMAGE_NT_HEADERS
                                     .if [edi].Signature==IMAGE_NT_SIGNATURE
                                             mov  @Valid,TRUE
                                             jmp   End
                                      .else
                                             mov @Valid,FALSE
                                      .endif
                             .else
                                   mov @Valid,FALSE
                            .endif
      SafePlace:        
                          mov @valid,FALSE
     End:            push @seh.PreLink
                         pop   fs:[0]
                          ret
CheckPeFile   endp


Handler            proc      c  _lpExcep,_lpSeh,_lpContext,_lpDispatcher
                          push     edi 
                          push     esi
                          mov       edi,_lpSeh
                          assume edi:ptr SEH
                          mov       esi,_lpContext
                          assume esi:ptr CONTEXT
                          push    [edi].SafePlace
                          pop      [esi].regEip
                          push   [edi].PreEbp
                          pop      [esi].regEbp
                          push    [edi].PreEsp
                          pop      [esi].regEsp
                          pop        esi
                          pop         edi
                          ret
Handler           endp
                       
下面我们来进行一下简要的分析:
                    程序使用传入的参数lpMemory,该参数是文件映射到内存的起始地址,然后设置SEH后开始Check,
如若两个地方都符合,则我们就可以假定是一个PE文件了。
                   在开始进行检查之前,我们先设置了一个SEH结构,对SEH的设置是非常重要的,因为对内存的访问
涉及很多的检查,对SEH的设置可以有效的避免。对SEH结构的设置如下:
                  1、取得SEH 链的前一个结点
                  2、设置安全地址 
                  3、设置处理程序的地址
                  4、设置当前的Esp
                  5、 设置当前的Ebp
对于前三个的设置相信大家都知道,这里特别的提醒自己对于后两个Ebp Esp的设置的重要性,
如若在程序中比如以上的CheckPeFile中,在SEH设置后有一些入栈出栈的操作,但是在还没有平衡
堆栈之前有错误出现,则会转去执行错误处理程序,错误处理程序返回后,在子程序退出之前要进行SEH链当前结点
的脱链,但是由于当前栈上有子程序之前入栈或出栈操作,使得没有办法进行正常的脱链,所以在错误处理程序中
要恢复堆栈。

                   



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值