zoukankan      html  css  js  c++  java
  • PE文件格式重定位

    一、关于重定位

    1、直接寻址指令需要重定位。如:mov eax, dword ptr [4000c0h]

    注意:call 401000h 是相对寻址,不需要重定位。

    请问 call [401000h]需要重定位吗?

    2、重定位需要的信息:重定位地址、实际装载地址、建议装载地址。

    二、重定位数据结构

    IMAGE_ BASE_RELOCATION struct

      VirtualAddress           dd         ;重定位内存页首地址RVA

      SizeOfBlock               dd         ;重定位块大小,包含本结构在内的大小

    IMAGE_BASE_RELOCATION ends 

    1、该结构后面紧跟的是word型的重定位项。

    2、重定位地址的 RVA = VirtualAddress + word型重定位项的低12位

    3、word行重定位项的高4位表示重定位类型,一般常见的值为0和3

    高4位值 常量表示 含义
    0 IMAGE_REL_BASED_ABSOLUTE 使块按照32位对齐,位置为0
    1 IMAGE_REL_BASED_HIGH 高16位必须应用于偏移量所指高字16位
    2 IMAGE_REL_BASED_LOW 低16位必须应用于偏移量所指低字16位
    3 IMAGE_REL_BASED_HIGHLOW 全部32位应用于所有32位
    4 IMAGE_REL_BASED_HIGHADJ 需要32位,高16位位于偏移量,低16位位于下一个偏移量数组元素,组合为一个带符号数,加上32位的一个数,然后加上8000然后把高16位保存在偏移量的16位域内
    5 IMAGE_REL_BASED_MIPS_JMPADDR 资料不详
    6 IMAGE_REL_BASED_SECTION 资料不详
    7 IMAGE_REL_BASED_REL32 资料不详

    4、重定位项数 = (SizeOfBlock - 4 - 4) / 2

    5、重定位块结束,以IMAGE_BASE_RELOCATION结构的VirtualAddress值为0结束。因此若映像加载00400000h,则代码加载地址为00401000h

    6、示例:

    (1)运行界面

    (2)代码processpefile_reloc.asm

    ;======================
    ;pe文件重定位表
    ;by 紫陌
    ;======================
    ;======================
    ;数据段
    ;======================
    .data?


    .const
    szErrNon    db '没有重定位信息', 0
    szBaseReloc   db '重定位首地址:%08X    重定位大小:%08X', 0dh, 0ah, 0
    szTitleBlock  db '================重定位块(%08X)(累计大小%08X)=============', 0dh, 0ah, 0
    szBlock    db '重定位内存页首地址(%08X):%08X', 0dh, 0ah
          db '重定位块大小(%08X):%08X', 0dh, 0ah, 0
    szEntry    db '重定位项(%08X):%04X', 0dh, 0ah, 0

    ;======================
    ;代码段
    ;======================
    .code

    _ProcessPeFile_Reloc proc _lpImageBase
     local @szBuf[512]:BYTE
     local @dwRelocSize:DWORD
     local @dwEntryNum:DWORD
     local @dwTotalSize:DWORD
     
     pushad
     
     ;********************
     ;从数据目录取重定位首地址和大小
     ;********************
     mov edi, _lpImageBase
     assume edi:ptr IMAGE_DOS_HEADER
     add edi, [edi].e_lfanew
     assume edi:ptr IMAGE_NT_HEADERS
     mov ecx, [edi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC * sizeof IMAGE_DATA_DIRECTORY].isize
     mov @dwRelocSize, ecx
     mov edi, [edi].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC * sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
     .if !edi
      invoke lstrcpy, addr szShowMsg, addr szErrNon
      invoke SetWindowText, hRichEdit, addr szShowMsg
      jmp _overpos
     .endif
     ;*******************
     ;将RVA转为文件偏移
     ;*******************
     invoke _RvaToOffset, _lpImageBase, edi
     add eax, _lpImageBase
     mov edi, eax
     assume edi:ptr IMAGE_BASE_RELOCATION
     ;*******************
     ;显示重定位首地址和大小
     ;*******************
     invoke wsprintf, addr @szBuf, addr szBaseReloc, edi, @dwRelocSize
     invoke lstrcpy, addr szShowMsg, addr @szBuf
     invoke SetWindowText, hRichEdit, addr szShowMsg
     ;*******************
     ;循环显示重定位块
     ;*******************
     mov @dwTotalSize, 0
     .while TRUE
      .break .if [edi].VirtualAddress == 0
      ;****************
      ;重定位块累计大小
      ;****************
      mov ecx, @dwTotalSize
      add ecx, [edi].SizeOfBlock
      mov @dwTotalSize, ecx
      invoke wsprintf, addr @szBuf, addr szTitleBlock, edi, @dwTotalSize
      invoke lstrcat, addr szShowMsg, addr @szBuf
      ;****************
      ;重定位头
      ;****************
      invoke wsprintf, addr @szBuf, addr szBlock, \
       addr [edi].VirtualAddress, [edi].VirtualAddress, \
       addr [edi].SizeOfBlock, [edi].SizeOfBlock
      invoke lstrcat, addr szShowMsg, addr @szBuf
      ;****************
      ;重定位项
      ;****************
      mov ecx, [edi].SizeOfBlock
      sub ecx, 8
      shr ecx, 1
      mov @dwEntryNum, ecx
      mov esi, edi
      sub esi, 8
      .while ecx
       mov @dwEntryNum, ecx
       lodsw
       movzx eax, ax
       invoke wsprintf, addr @szBuf, addr szEntry, esi, eax
       invoke lstrcat, addr szShowMsg, addr @szBuf
       mov ecx, @dwEntryNum
       dec ecx
      .endw
      ;*****************
      ;显示重定位块
      ;*****************
      invoke SetWindowText, hRichEdit, addr szShowMsg
      ;*****************
      ;取下一个重定位块
      ;*****************
    ;  mov ecx, @dwRelocSize
    ;  sub ecx, [edi].SizeOfBlock
    ;  mov @dwRelocSize, ecx
      add edi, [edi].SizeOfBlock
     .endw
    _overpos:
     assume edi:nothing
     popad
     ret

    _ProcessPeFile_Reloc endp

  • 相关阅读:
    22.Collections排序
    21.Collections常用方法的使用
    20.ArrayList获取并打印新闻标题
    19. Set接口的一般用法
    JS脚本显示当前日期+星期几[转]
    java流下载
    技术书籍分类[转]
    Javascript 继承 call与prototype
    SpringMVC访问静态资源[转]
    获取调用者Class和method、反射获取get方法、获取注解信息
  • 原文地址:https://www.cnblogs.com/guanlaiy/p/2493672.html
Copyright © 2011-2022 走看看