用OD程序调试调试程序时见到的地址与应用C32Asm以十六进制方式查询程序流程时的地址方式有一定的差别。程序流程在内存中与在文件中具有不一样的地址方式,并且PE有关的地址不仅有这2种方式。与PE构造有关的地址方式有3种,且这3种地址形式可以开展变换。
1. 与PE构造有关的3种地址
与PE构造有关的3种地址是VA(虚似地址)、RVA(相对性虚似地址)和FileOffset(文件偏移地址)。
VA(虚拟地址):PE 文件投射到内存后的地址。
RVA(相对性虚似地址):内存地址相对性于投射基地址的偏移地址。
FileOffset(文件偏移地址):相对性 PE 文件在磁盘上的文件开始的偏移地址。
PE文件在磁盘上与在内存中的构造是一样的。所不一样的是,在磁盘上,文件是依照IMAGE_OPTIONAL_HEADER的FileAlignment值开展两端对齐的。而在内存中,印象文件是依照IMAGE_OPTIONAL_HEADER的SectionAlignment开展两端对齐的。FileAlignment是以磁盘上的磁道为公司的,换句话说,FileAlignment最少为512字节数,十六进制的0x200字节。而SectionAlignment是以内存分页查询为企业来两端对齐的,通常Win32服务平台一个内存分页查询为4KB,也就是十六进制的0x1000字节数。一般情形下,FileAlignment的值会与SectionAlignment的值同样,那样磁盘文件和内存印象的构造是完完全全一样的。当FileAlignment的值和SectionAlignment的值不一样的情况下,就存有一些微小的差别了,其具体差别取决于,依据两端对齐的具体情况而多添充了许多0值。PE文件投射如下图1所显示。
图1 PE文件投射图
除开文件两端对齐与内存对齐的差别之外,文件的开始地址从0地址逐渐,用C32Asm的十六进制方式查询PE文件时开始部位是0x00000000。而在内存中,它的开始地址为IMAGE_OPTIONAL_HEADER结构体的ImageBase字段名(该观点只对于EXE文件,DLL文件的投射地址不一定固定不动,可是绝对不会是0x00000000地址)。
2. 3种地址的变换
当FileAlignment和SectionAlignment的值不同样时,磁盘文件与内存印象的同一节表数据信息在磁盘和内存中的偏移都不同样,那样2个偏移就发生了一个必须变换的问题。当了解某数据信息的RVA,要想在文件中载入一样的数据资料的情况下,就需要将RVA变换为FileOffset。相反,也是相同的状况。
下边用一个事例来详细介绍怎么开展变换。一个用MessageBox()輸出“Hello World”的事例程序流程,用PEID开启它,查询它的节表状况,如下图2所显示。
图2 PEID表明的节表內容
从图2的菜单栏能够看见,这儿不叫“节表”,而叫“区间”。也有其他材料上称作“区块链”或“节区”,仅仅称呼不一样,內容全是一样的。
从图2中能够看见,节表的第一个节区的节名字为“.text”。一般来说,第一个节表项全是编码区,通道点也通常落在这一节表项。在初期壳不时兴时,根据分辨通道点是不是在第一个节区就可以判定该系统是不是被病毒感。现如今,因为壳的时兴,这类分辨方式也不靠谱了。重要需看的是“R.偏移”,说明了该节区在文件中的开始部位。PE头顶部包含DOS头、PE头和节表,通常不可能超出512字节数,换句话说,不容易超出0x200的尺寸。假如这一“R.偏移”为0x00001000,那麼一般来说可以明确该文件的磁盘两端对齐尺寸为0x1000。检测认证一下这一程序流程,见到“V.偏移”与“R.偏移”同样,则表明磁盘两端对齐与内存对齐是一样的,那样就没法进行演试变换的运行了。但是,可以人工地改动文件两端对齐尺寸。还可以利用专用工具来改动文件两端对齐的尺寸。这儿依靠LordPE来改动其文件两端对齐尺寸。改动方式非常简单,先即将改动的检测文件拷贝一份,以与改动后的文件做比照。开启LordPE,点击“复建PE”按键,随后挑选刚刚拷贝的那一个检测文件,如下图3和图4所显示。
图3 LordPE页面
图4 复建PE作用結果
PE复建作用中有缩小文件尺寸的作用,这儿的缩小也就是改动磁盘文件的两端对齐值,防止太多地因两端对齐而开展补0,使其少占有磁盘室内空间。用PEID查询这一开展重塑的PE文件的节表,如下图5所显示。
图5 复建PE文件后的节表
如今能够看见“V.偏移”与“R.偏移”的值不同样了,他们的两端对齐值都不一样了,大伙儿可以自身认证一下FileAlignment和SectionAlignment的值是不是同样。
现在有2个作用彻底一样,并且PE构造也一样的2个文件了,唯一的不一样是其磁盘两端对齐尺寸不一样。如今在这里2个程序流程中各自找寻一个节表中的数据信息,学习培训不一样地址中间的变换。
首先用OD开启未开展复建PE构造的测试代码,寻找反编译中启用MessageBox()口要弹出窗口的2个字符串数组主要参数的地址,如下图6和图7所显示。
图6 MessageBox()函数公式中采用的字符串数组地址
图7 2个字符串数组的地址在数据信息对话框的表明
从图6和图7中能够看见,字符串数组“hello world !”的地址为0x00406030,字符串“hello”的地址为0x00406040。这两个地址全是虚似地址,也就是VA。
将VA(虚拟地址)变换为RVA(相对性虚似地址)是非常容易的,RVA(相对性虚似地址)为VA(虚拟地址)减掉IMAGE_OPTIONAL_HEADER结构体中的ImageBase(印象文件的运载虚似地址)字段名的值,即RVA = VA – ImageBase = 0x00406030 – 0x00400000 = 0x0000 6030。因为IMAGE_OPTIONAL_HEADER中的SectionAlignment和FileAlignment的值同样,因而其FileOffset的值也为0x00006030。用C32Asm开启该文件查询文件偏移地址0x00006030处的內容,如下图8所显示。
图8 文件偏移0x00006030处的主要内容为“hello world!”字符串数组
从这些事例中可以看得出,当SectionAlignment和FileAlignment同样时,同一节表项中数据的RVA(相对性虚似地址)和FileOffset(文件偏移地址)是一致的。RVA的值是用VA – ImageBase测算获得的。
再用OD开启“复建PE”后的测试代码,一样寻找反编译中启用MessageBox()函数公式应用的那一个字符串数组“hello world !”,看其虚似地址多少钱。它的虚似地址依然是0x00406030。一样,用虚似地址减掉运载地址,相对性虚似地址的值依然为0x00006030。但是用C32Asm开启该文件查询得话会各有不同。用C32Asm看一下0x00006030地址处的內容,如下图9所显示。
图9 文件偏移0x00006030处沒有“hello world!”字符串数组
从图9中能够看见,用C32Asm开启该文件后,文件偏移0x00006030处并沒有“hello world!”和“hello”字符串数组。这就是由文件两端对齐与内存对齐的不同所造成的。这时就需要根据一些简易的测算把RVA变换为FileOffset。
把RVA转换为FileOffset的方式 非常简单,最先看一下现阶段的RVA或是是FileOffset归属于哪个节。0x00006030这一RVA归属于.data节。0x00006030这一RVA相对性于该节的起始RVA详细地址0x00006000而言偏移0x30字节。再看.data展在文件中的起始部位为0x00004000,以.data节的文件起始偏移0x00004000再加上0x30字节的数值0x00004030。用C32Asm看一下0x00004030详细地址处的内容,如下图10所显示。
图10 0x00004030文件偏移处的内容
从图10中可以看得出,该文件偏移处储存着“hello world !”字符串数组,换句话说,将RVA变换为FileOffset是合理的。根据LordPE专用工具来认证一下,如下图11所显示。
图11 用LordPE测算RVA为0x00006030的文件偏移
再去总结一下这一全过程。
某数据信息的文件偏移 = 该数据所属节的起始文件偏移 (某数据信息的RVA –该数据所属节的起始RVA)。
除开以上的计算方式之外,也有一种计算方式,即用节的起始RVA值减掉节的起始文件偏移值,获得一个误差,再用RVA减掉这一获得的误差,就可以获得其所相应的FileOffset。可以应用事例程序流程开展手工制作测算,随后根据LordPE开展认证。
了解怎么根据RVA变换为文件偏移,那麼根据文件偏移变换为RVA的办法也就不会太难了。这3种详细地址互相的转换规则就详细介绍完后。要是没有了解,就可以不断地依照公式计算开展了解和测算。只需在思维中创建有关硬盘文件和运行内存印象的构造,那麼了解起來就不可能太费劲。