首页
社区
课程
招聘
[求助]关于PE文件对齐的疑惑?
发表于: 2007-7-25 21:37 7208

[求助]关于PE文件对齐的疑惑?

2007-7-25 21:37
7208
PE文件中的节无论是在磁盘中或内存映像中都是按照一定单位进行对齐的。
那么对齐的具体情况是什么样的呢?

假如在内存中的对齐单位是4 Kb,那么Windows是不是将PE文件中节的有效数据(没有进行任何对齐时的数据),逐个填满4 Kb,然后再将最后那个还没填满的4 Kb用零补足呢?也就是说Windows为进行对齐而补上的零不会超过4 Kb!

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 1505
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
2
是的啊 是的啊
2007-7-26 02:49
0
雪    币: 209
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
罗运彬书里的一个例子:

_RVAToOffset  proc  _lpFileHead,_dwRVA
    local  @dwReturn

    pushad
    mov  esi,_lpFileHead   ;_lpFileHead是PE在内存映射中的起始地址
    assume  esi:ptr IMAGE_DOS_HEADER
    add  esi,[esi].e_lfanew
    assume  esi:ptr IMAGE_NT_HEADERS
    mov  edi,_dwRVA       ;指定数据的RVA
    mov  edx,esi
    add  edx,sizeof IMAGE_NT_HEADERS
    assume  edx:ptr IMAGE_SECTION_HEADER
    movzx  ecx,[esi].FileHeader.NumberOfSections
;********************************************************************
; 扫描每个节区并判断 RVA 是否位于这个节区内
;********************************************************************
    .repeat
      mov  eax,[edx].VirtualAddress
      add  eax,[edx].SizeOfRawData    
      .if  (edi >= [edx].VirtualAddress) && (edi < eax)
        mov  eax,[edx].Misc.VirtualSize 
        sub  edi,eax      
        mov  eax,[edx].PointerToRawData
        add  eax,edi      
        jmp  @F
      .endif
      add  edx,sizeof IMAGE_SECTION_HEADER
    .untilcxz
    assume  edx:nothing
    assume  esi:nothing
    mov  eax,-1
@@:
    mov  @dwReturn,eax
    popad
    mov  eax,@dwReturn
    ret

_RVAToOffset  endp

上面的例子用节在内存中的起始RVA,加上节的大小(SizeOfRawData字段)算出节的结束RVA!
但是一个节的大小在磁盘文件中与在内存中是不同的,用节在内存中的起始RVA加上节在磁盘文件中的大小算出节的结束RVA是准确的吗?
我认为应该用节在内存中的起始RVA加上VirtualSize字段(节的数据在没有进行对齐处理前的实际大小)的值按照SectionAlignment(节在内存中的节的对齐粒度)的值对齐以后的大小才是正确的节的结束RVA。不知是不是正确的?
2007-7-26 19:13
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
从向风一样自由的BLog上找到了一些资料:
由PE文件中IMAGE_SECTION_HEADER结构中的Misc.VirtualSize,SizeOfRawData,SizeOfImag之间的关系分析PE加载器的对区块的处理行为
//用来计算对齐数据后的大小
int alig(int size,unsigned int align)
{
if(size%align!=0)
  return (size/align+1)*align;
else
  return size;
}
假设align为文件或区块对齐函数

PE文件中IMAGE_OPTIONAL_HEADER结构中的SizeOfImage的值为最后一个区块的VirtualAddress与其alig(Misc.VirtualSize,SectionAlignment)的和,不论PE文件区块表中描述的Misc.VirtualSize与SizeOfRawData的大小关系如何,PE文件各区块分别被映射到内存后大小都为alig(Misc.VirtualSize,SectionAlignment)的值。但是按SectionAlignment对齐后区块中的数据来源又是怎么回事呢?我们明白:这些数据会来源于磁盘数据。但会出现下面三种情况:(windows 2000 sp4实现发现SizeOfRawData值不按FileAlignment对齐似乎也能被正常加载)
一,若当alig(Misc.VirtualSize,SectionAlignment)大于SizeOfRawData时,PE文件被映射到内存后数据会如何变化?windows200 sp4中实验发现,如alig(Misc.VirtualSize,SectionAlignment)大于SizeOfRawData时,则以PointerToRawData为偏移从磁盘中先读入alig(SizeOfRawData,FileAlignment)大小的数据,剩余的alig(Misc.VirtualSize,SectionAlignment)-alig(SizeOfRawData,FileAlignment)大小的数据以0填充
二,若当alig(Misc.VirtualSize,SectionAlignment)小于alig(SizeOfRawData,FileAlignment)时,PE文件被映射到内存时只读入则以PointerToRawData为偏移大小为alig(Misc.VirtualSize,SectionAlignment)的数据,剩余alig(SizeOfRawData,FileAlignment)-alig(Misc.VirtualSize,SectionAlignment)的数不会被映射。
三,若当alig(Misc.VirtualSize,SectionAlignment)等于alig(SizeOfRawData,FileAlignment)时,
PE文件会把alig(Misc.VirtualSize,SectionAlignment)大小的数据全部映射到进程线性地址空间。(注意:此时Misc.VirtualSize<=alig(SizeOfRawData,FileAlignment),若此时在磁盘文件PointerToRawData+Misc.VirtualSize偏移处写入不大于alig(SizeOfRawData,FileAlignment)-Misc.VirtualSize的数据,PE文件在磁盘中的大小与映像大小都不会发生变化)
2007-7-28 13:56
0
游客
登录 | 注册 方可回帖
返回
//