之前几节一直是理论性质的东西非常多。本文将会讲到利用之前的知识得出一个一个非常有用的一个应用。(转载请指明来源于breaksoftware的csdn博客)

首先我们说下磁盘上A.exe文件和正在内存中运行的A.xe之间的关系。当我们双击A.exe后,A.exe会运行起来。我们在任务管理器中可以看到A.exe。这个过程很简单,但是双击A.exe之后系统做了什么?这个过程你是否思考过?我不准备在此处详细说这个过程,因为这个过程比较复杂。我只讲一个过程——载入。

磁盘上A.exe在硬盘上,运行时的A.exe的执行体是在内存中。从磁盘到内存,这是个载入的过程。我们查看下A.exe占用的内存和A.exe这个文件的大小,会发现,这两个大小之间不存在任何关系。一则是因为A.exe运行时会载入部分DLL导致内存变大,其次可能是A.exe运行时申请了大量的空间。还有个原因很容易被忽略掉,就是系统在加载这个A.exe时,它是分段读取该文件,分段加载的。比如文件中一个信息是1byte,系统读取该信息后出于内存对齐考虑,可能会给这个信息分配4bytes的空间。是不是感觉我们A.exe被系统加载后,数据的连续性等被破坏了?如图

是的,原来的结构是被打乱的。是不是感觉恐慌?其实不用,这种映射必定存在一定的算法。我们本文就是讨论这种算法的。

讨论这个算法前,我们先说个概念——位置。现在有GPS功能的设备越来越多,玩这个功能的人是否考虑过其中的简单的原理呢?我没有研究过它,但是我想这是天上的卫星和地上(或者空间)一些设备合作计算出来的。比如我们地上有些基站,卫星知道它们的坐标,然后通过一些数据,比如我们“相对‘A基站的距离,“相对‘B基站的距离,从而计算出我们GPS设备和这些坐标的关系,从而得出我们所在的坐标,从而知道我们的位置。可以见得计算我们位置的过程涉及到“相对”这个概念。

文件中数据位置的描述也是使用”相对“来定位的,正在运行的程序中的数据的定位也是通过”相对“来定位的。一个数据位置相对于文件头(第一个字节)的偏移我们称为相对地址(RA),内存中一个数据相对于程序开始处的偏移我们称为相对虚拟地址(RVA)。这两个概念非常重要。

那我们PE文件中对数据的表述是使用RA还是RVA呢?大体可以总结如下:如果要在内存中运行和使用的数据大部分是使用RVA描述的。如果只是文件信息,程序运行时不关心的数据使用RA描述的。我在《PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头2》最后部分,说了一句话“DataDirectory保存了指向“块信息”的目录信息,其中包括偏移(除了IMAGE_DIRECTORY_ENTRY_SECURITY元素是相对文件偏移RA,其他都是相对虚拟首地址偏移RVA)和大小。”IMAGE_DIRECTORY_ENTRY_SECURITY区块保存的是文件的签名信息,在运行程序前,系统加载文件的过程是不会把这块信息加载到内存中的。还有《PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1》中介绍的IMAGE_FILE_HEADER::PointerToSymbolTable,它指向的数据是符号表,该信息也是程序运行时不关心的,所以它也是RA。程序运行时需要使用的信息的数据地址就要使用RVA来表示了,试想如果这些数据用RA表示,则程序在运行前要根据加载的情况把这些数据在内存中的RVA再算出来,这个工作量是非常大的,是非常不科学的。

在我分析PE文件时,遇到的大部分信息是RVA。于是我想查看该位置的信息,就要通过RVA计算出RA。一般来说文件的结构是比较紧凑的,这样是为了方便文件传输(想想在那个网络非常慢,硬盘那么贵的年代)。而程序的内存中的结构则相对松散些,这个并不是因为内存不值钱,而是为了执行效率,而且一般没谁会把电脑上所有保存的程序都跑起来执行吧?

一般来说,系统加载PE文件时,会先读取文件头信息,查看该文件是否可以重定向(通过判断IMAGE_FILE_HEADER::Characteristics是否包含IMAGE_FILE_RELOCS_STRIPPED)啊。如果不可以,则查看它想加载的位置(IMAGE_OPTIONAL_HEADER32(64)::ImageBase)是否被占用了,如果没有占用,或者即使被占用了但是其允许重定位,就继续读取”节信息“。关于节信息,我在《PE文件和COFF文件格式分析——节信息》中有说明。这儿我们再看下节头信息数据结构

#define IMAGE_SIZEOF_SHORT_NAME              8typedef struct _IMAGE_SECTION_HEADER {BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];union {DWORD   PhysicalAddress;DWORD   VirtualSize;} Misc;DWORD   VirtualAddress;DWORD   SizeOfRawData;DWORD   PointerToRawData;DWORD   PointerToRelocations;DWORD   PointerToLinenumbers;WORD    NumberOfRelocations;WORD    NumberOfLinenumbers;DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

VirtualAddress保存的是映像文件中该节被加载进内存时,第一个字节相对于映像基址的偏移量。VirtualSize保存的是内存中该节的大小。这组数据和RVA关系很大。

PoiterToRawData保存的是该节第一个字节在文件中相对于文件第一个字节的偏移量。SizeOfRawData保存的是该节在文件中的大小。这组数据和RA关系很大。

那么系统加载这些节可以用下图说明

是不是还是感觉比较乱?但是注意一个现象,看线1、2是平行的,线3、4是平行的,线5、6是平行的。为什么是平行的?在《PE文件和COFF文件格式分析——节信息》一文中我介绍VirtualSize属性时这么说的“VirtualSize属性是节加载进入内存后,节在内存中的大小。如果它比SizeOfRawData大,则多余的部分是用0x00填充的。”

那么这个平行这意味着什么?这意味着如果我们可以利用”相对“这个概念。因为平行就是相对的,如1和2平行而和3不平行。现在假如RVA落在内存的SectionBStart和SectionBEnd之间,则我们可以计算出RVA于SectionBStart的偏移OffsetBSection。然后我们通过节信息找到SectionBStart在文件中的相对地址RA,最后,我们让SectionBstart+OffsetBSection就得到RVA对应的RA了。是的!算法就是如此简单

        for ( VecSectionHeaderIter it = m_vecSectionHeaders.begin(); it != m_vecSectionHeaders.end(); it++ ){if ( dwRVA >= it->VirtualAddress && dwRVA < it->VirtualAddress + it->Misc.VirtualSize ) { if ( 0 == it->SizeOfRawData ) {break;}dwRA = dwRVA - it->VirtualAddress + it->PointerToRawData;bSuc =  TRUE;break;}}

这儿还要说一种场景:有些PE文件坏坏的让VirtualSize为0,而实际该大小确实存在的,这个时候我们就要修正VirtualSize之后再判断了。

            for ( VecSectionHeaderIter it = m_vecSectionHeaders.begin(); it != m_vecSectionHeaders.end(); it++ ){if ( dwRVA >= it->VirtualAddress && 0 == it->Misc.VirtualSize ) { // 校正虚拟大小DWORD dwSectionAlignment = ( EOp32 == m_eFileOpType ) ? m_OptionalHeader32.SectionAlignment : m_OptionalHeader64.SectionAlignment;DWORD dwVirtualSize = ( it->SizeOfRawData + (dwSectionAlignment - 1) ) &~(dwSectionAlignment - 1);it->Misc.VirtualSize = dwVirtualSize;if ( dwRVA < it->VirtualAddress + dwVirtualSize ) {dwRA = dwRVA - it->VirtualAddress + it->PointerToRawData;bSuc =  TRUE;break;  }}}

以上算法是讨论了从RVA计算出RA的过程,而通过RA计算出RVA只是这样一个逆向过程。我想如果看懂了以上的原理,那么这个算法是很容易写出来的。

刚接触这块的同学可能会存在一个误区:比如他知道RVA=0x00002100,还知道这个RVA对应的RA=0x00002200。于是可能会想当然的认为该文件的RA = RVA + 0x100。于是他下次遇到RVA=0x00008000时就认为其对应的RA=RVA+0x100=0x00008100!!这个是不对的,就像0x00002200落在上图的SectionAStart和SectionAEnd之间,而0x00008000落在上图的SectionBStart和SectionBEnd之间,线1和3不是平行的,即差值是不同的,不能这么算的。

PE文件和COFF文件格式分析——RVA和RA相互计算相关推荐

  1. PE文件和COFF文件格式分析——导出表

    在之前的<PE可选文件头>相关博文中我们介绍了可选文件头中很多重要的属性,而其中一个非常重要的属性是(转载请指明来源于breaksoftware的CSDN博客) IMAGE_DATA_DI ...

  2. PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL

    通过导出表隐性加载DLL?导出表?加载DLL?还隐性?是的.如果觉得不可思议,可以先看<PE文件和COFF文件格式分析--导出表>中关于"导出地址表"的详细介绍.(转载 ...

  3. PE文件和COFF文件格式分析——节信息

    在<PE文件和COFF文件格式分析--签名.COFF文件头和可选文件头3>中,我们看到一些区块的信息都有偏移指向.而我们本文讨论的节信息是没有任何偏移指向的,所以它是紧跟在可选文件头后面的 ...

  4. PE文件和COFF文件格式分析——导出表的应用——一种摘掉Inline钩子(Unhook)的方法

    在日常应用中,某些程序往往会被第三方程序下钩子(hook).如果被下钩子的进程是我们的进程,并且第三方钩子严重影响了我们的逻辑和流程,我们就需要把这些钩子摘掉(Unhook).本件讲述一种在32位系统 ...

  5. PE文件和COFF文件格式分析——导出表的应用——一种插件模型

    可能在很多人想想中,只有DLL才有导出表,而Exe不应该有导出表.而在<PE文件和COFF文件格式分析--导出表>中,我却避开了这个话题.我就是想在本文中讨论下载Exe中存在导出表的场景. ...

  6. PE文件和COFF文件格式分析--概述

    刚工作的时候,我听说某某大牛在做病毒分析时,只是用notepad打开病毒文件,就能大致猜到病毒的工作原理.当时我是佩服的很啊,同时我也在心中埋下了一个种子:我也得有这天.随着后来的工作进行,一些任务的 ...

  7. PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1

    本文将讨论PE文件中非常重要的一部分信息.(转载请指明来源于breakSoftware的CSDN博客) 首先说一下VC中对应的数据结构."签名.COFF文件头和可选文件头"这三部分 ...

  8. PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段

    MS 2.0节是PE文件格式中第一个"节".其大致结构如下:(转载请指明来源于breaksoftware的csdn博客) 在VC\PlatformSDK\Include\WinNT ...

  9. PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头2

    之前的博文中介绍了IMAGE_FILE_HEADER结构,现在来讨论比较复杂的"可选文件头"结构体.(转载请指明来自breaksoftware的csdn博客)先看下其声明 type ...

最新文章

  1. Maven 的classifier的作用
  2. python自学平台-自学Python网站推荐 从入门到精通
  3. Android 四大组件之——Acitivity(四) Activity是如何加载显示内容的?
  4. VMware Workstation All Key
  5. 安装sqlserver2008,重新启动计算机不通过的解决办法
  6. [bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp
  7. linux系统上安装toma,Linux-tar - osc_btnnkvs0的个人空间 - OSCHINA - 中文开源技术交流社区...
  8. CSS3特效,跳动的心
  9. 鱼和熊掌兼得---STM32调试接口SW动态复用为GPIO的方法
  10. 可信人工智能白皮书(概要)
  11. VSCode画 UML 图
  12. matlab2012仿真电路图,cuk电路matlab仿真 - 全文
  13. Thinkphp5.0实战 仿百度糯米开发多商家电商平台视频中常见的命令(正在更新)
  14. 大数据典型的应用场景
  15. VC6 SP6下载地址
  16. 自行车内胎常识和选购注意事项
  17. Java8 JDK8
  18. 辅助小工具---FooView
  19. 使用CLB部署HTTPS业务
  20. 自定义Qt Designer插件

热门文章

  1. python+opencv Canny边缘检测
  2. OpenCV中的霍夫线变换、概率霍夫线变换
  3. Excel 计算除法并显示为万分之几,如0.15‱
  4. 机器学习(11)线性回归(2)实战 -- 正规方程优化、梯度下降优化(波士顿房价预测)
  5. excel冻结窗口怎么设置_IE浏览器弹出窗口怎么设置
  6. 让你爽到飞起的【懒人插件AutoScssStruct4Vue】VSCode根据template的标签目录一键生成SCSS/LESS结构,敏捷开发必备插件!!!
  7. rtsp流 转 http播放视频
  8. linux下远程传输文件命令scp使用注解
  9. 关于部署osd过程中:Device is in use by a device-mapper mapping问题解决
  10. ubuntu18.04 Desktop版本部署13.2.6版本ceph