• PE文件详解(八)


    本文转载自小甲鱼PE文件详解系列教程原文传送门
    当应用程序需要调用DLL中的函数时,会由系统将DLL中的函数映射到程序的虚拟内存中,dll中本身没有自己的栈,它是借用的应用程序的栈,这样当dll中出现类似于mov eax, [1000000]这样直接寻址的代码时,由于事先并不知道它会被映射到应用程序中的哪个位置,并且可能这个内存地址已经被使用,所以当调用dll中的函数时,系统会进行一个基址重定位的操作。系统是根据dll中的基址重定位表中的信息决定如何进行基址重定位,哪些位置的指令需要进行基址重定位。
    所以这次主要说明基址重定位表。
    这个重定位表位于数据目录表的第六项。这个表的主要结构如下:

    IMAGE_BASE_RELOCATION STRUC
    
        VirtualAddress      DWORD        ?  ; 重定位数据开始的RVA 地址
        SizeOfBlock         DWORD        ?  ; 重定位块得长度
        TypeOffset          WORD         ?  ; 重定项位数组
    
    IMAGE_BASE_RELOCATION  ENDS

    VirtualAddress 是 Base Relocation Table 的位置它是一个 RVA 值
    SizeOfBlock 是 Base Relocation Table 的大小;
    这个结构的示意图如下:
    这里写图片描述
    TypeOffset 是一个数组,数组每项大小为两个字节(16位),它由高 4位和低 12位组成,高 4位代表重定位类型,低 12位是重定位地址。高4位一般是3,表示这个地址是一个32位的地址,它与 VirtualAddress 相加即是指向PE 映像中需要修改的那个地址的位置,注意这里不是定位到对应代码的位置
    接下来进行手工的方式找到需要重定位的代码位置:
    打开一个dll文件,发现它的基址重定位表所在RVA = 0x00004000
    通过计算得到它是在.relo ,对应文件的偏移为0x800,查看这个位置的值为:
    这里写图片描述
    VirtualAddress = 0x1000,
    SizeOfBlock = 0x18
    通过它的大小,得知需要重定位的位置主要有(0x18 - 8) / 2 = 8,最后一个以0结尾,所以实际上总共有7处需要重定位
    这8个位置分别为:0x028, 0x02e, 0x003e 0x04b, 0x051, 0x61, 0x6c
    这里写图片描述
    后面的以此类推,可以发现这些需要重定位的位置,存储的都是一些立即寻址的地址

  • 相关阅读:
    python 学习分享-进程
    python 学习分享-实战篇类 Fabric 主机管理程序开发
    python 学习分享-线程
    python 学习分享-paramiko模块
    linux ubuntu开启sshd
    python 学习分享-实战篇高级的ftp
    python 学习分享-socketserver
    python 学习分享-socket编程
    Java学习笔记--Java开发坏境搭建
    C# 泛型
  • 原文地址:https://www.cnblogs.com/lanuage/p/7725697.html
Copyright © 2020-2023  润新知