zoukankan      html  css  js  c++  java
  • 逆向工程核心原理——第十六章

    第十六章,PE文件重定位。

    PE重定位

    向进程的虚拟内存加载PE文件时,文件会被加载到PE头的ImageBase所指向的地址处,若IB位置已经加载了其他文件,PE装载器就会将其加载到去其他未被占用的空间,这就涉及到PE地址重定位的问题。
    创建好进程之后,EXE文件会首先加载到内存,因此在EXE文件无需考虑地址重定位问题
    ASLR安全机制:每次运行时EXE文件都会被加载到随机地址。
    此机制也适用于DLL/SYS文件,对于个OS的主要系统DLL,微软会根据不同版本分别赋予不同的IB地址。同意系统的kernel32.dll、user32.dll等会被加载到自身固有的IB,所以系统的DLL实际上并不会发生重定位问题。

    PE重定位操作原理

    1. 在应用程序中查找硬编码的地址位置
    2. 读取值后,减去ImageBase(VA->RVA)(原本这些值是以IB为基准的硬编码值)
    3. 加上实际加载的地址(RVA->VA)

    基址重定位表

    基址重定位表的地址位于PE头的Datadirectory数组的第六个元素
    基址重定位表是一个IMAGE_BASE_RELOCATION结构体数组

    IMAGE_BASE_RELOCATION

    成员:

    • VirtualAddress: 这是一个基准地址,实际上是RVA值
    • SizeOfBlock:指重定位块的大小
    • TypeOffset:不是结构体成员,以注释方式存在,表示在该结构体之下会出现WORD类型的数组,并且该数组的值就是硬编码在程序中的地址偏移

    基址重定位表的分析方法

    例:

    RVA 数据 注释
    0002F000 00001000 VirtualAddress
    0002F004 00000150 SizeOfBlock
    0002F008 3420 TypeOffset
    0002F00A 342D TypeOffset
    0002F00C 3436 TypeOffset
    ... ... ...

    注释:RVA是在文件当中这些数据所存储的RVA,注释是自己加的,文件里是没有的
    解读:VirtualAddress成员的值为1000,说明TypeOffset数组的基准地址为RVA1000,SizeOfBlock的值为150,TypeOffset数组的大小(不是长度)为150。TypeOffset的值为2B大小,是由4位的Type与12位的Offset合成的,如3420--->

    类型(4位) 偏移(12位)
    3 420

    低12位的偏移才是真正的位移,它是基于VA成员的偏移,因此

    RVA = VirtualSize + Offset

    等程序真正在内存中运行时,RVA=1420的地址处所存的硬编码地址,就会被替换成新的地址。

    注释:TypeOffset项中指向位移的低12位所拥有的最大地址值为1000,为了表示更大的地址,要添加一个与其对应的块(使用结构体的原因),这些块以数组形式罗列(就是结构体数组),故称为重定位表。

    作者:静者达观
    链接:https://www.jianshu.com/p/1c99033f8dfb
    来源:简书

  • 相关阅读:
    在GitHub上删除项目后,在Android Studio上传项目依然提示project is already on github
    Android Studio 使用Intent实现页面的跳转(带参数)
    Android Studio 点击两次返回键,退出APP
    Android Studio 使用ViewPager + Fragment实现滑动菜单Tab效果 --简易版
    Eclipse 分屏显示同一个代码文件
    关于线上问题处理心得分享
    关于敏捷开发
    Python语言程序设计学习 之 了解Python
    关于测试
    C# 使用FileUpload控件上传图片,将文件转换成二进制进行存储与读取
  • 原文地址:https://www.cnblogs.com/lex-shoukaku/p/13645097.html
Copyright © 2011-2022 走看看