zoukankan      html  css  js  c++  java
  • binary hacks读数笔记(ld 链接讲解 一)

    首先我们先看两段代码:

    a.c

    extern int shared;
     
    int main(){
           int a=100;
            swap(&a,&shared);
    }

    b.c

    int shared=1;
    
    void swap(int* a,int* b){
         *a^=*b^=*a^=*b;
    }

    gcc  -c a.c b.c 得到a.o 与b.o

    1、查看a.o:

    [root@tlinux misc]# objdump -h a.o
    
    a.o:     file format elf64-x86-64
    
    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .text         00000027  0000000000000000  0000000000000000  00000040  2**0
                      CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
      1 .data         00000000  0000000000000000  0000000000000000  00000067  2**0
                      CONTENTS, ALLOC, LOAD, DATA
      2 .bss          00000000  0000000000000000  0000000000000000  00000067  2**0
                      ALLOC
      3 .comment      0000002e  0000000000000000  0000000000000000  00000067  2**0
                      CONTENTS, READONLY
      4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  00000095  2**0
                      CONTENTS, READONLY
      5 .eh_frame     00000038  0000000000000000  0000000000000000  00000098  2**3
                      CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

    2、查看b.o:

    [root@tlinux misc]# objdump -h b.o
    
    b.o:     file format elf64-x86-64
    
    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .text         0000004a  0000000000000000  0000000000000000  00000040  2**0
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 .data         00000004  0000000000000000  0000000000000000  0000008c  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      2 .bss          00000000  0000000000000000  0000000000000000  00000090  2**0
                      ALLOC
      3 .comment      0000002e  0000000000000000  0000000000000000  00000090  2**0
                      CONTENTS, READONLY
      4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000be  2**0
                      CONTENTS, READONLY
      5 .eh_frame     00000038  0000000000000000  0000000000000000  000000c0  2**3
                      CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

    3、链接之前,VMA与LMA都是0,即目标文件的虚拟空间地址与装载地址都无效。经过链接ld过程,才会给链接文件分配虚拟地址空间。

    ld a.o b.o -e main -o ab

    链接过程,合并了a.o与b.o的代码段、数据段,具体的位置与大小如下所示:

    具体信息如下所示

    [root@tlinux misc]# objdump -h ab
    
    ab:     file format elf64-x86-64
    
    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .text         00000071  00000000004000e8  00000000004000e8  000000e8  2**0
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 .eh_frame     00000058  0000000000400160  0000000000400160  00000160  2**3
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      2 .data         00000004  0000000000601000  0000000000601000  00001000  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      3 .comment      0000002d  0000000000000000  0000000000000000  00001004  2**0
                      CONTENTS, READONLY

     同时,我们可以看一下,链接后,各个源文件的符号表也合成一张全局符号表,且符号表中表明各个符号的虚拟空间位置:

    readelf -s ab

    Symbol table '.symtab' contains 13 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 00000000004000e8     0 SECTION LOCAL  DEFAULT    1 
         2: 0000000000400160     0 SECTION LOCAL  DEFAULT    2 
         3: 0000000000601000     0 SECTION LOCAL  DEFAULT    3 
         4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
         5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.c
         6: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS b.c
         7: 000000000040010f    74 FUNC    GLOBAL DEFAULT    1 swap
         8: 0000000000601000     4 OBJECT  GLOBAL DEFAULT    3 shared
         9: 0000000000601004     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
        10: 00000000004000e8    39 FUNC    GLOBAL DEFAULT    1 main
        11: 0000000000601004     0 NOTYPE  GLOBAL DEFAULT    3 _edata
        12: 0000000000601008     0 NOTYPE  GLOBAL DEFAULT    3 _end

    4、接下来介绍一下符号的解析与重定位:

    首先查看一下未重定位之前,a.o中是怎么处理shared变量与swap函数的:

    利用 objdump -d a.o查看一下,a.o的反汇编代码

    [root@tlinux misc]# objdump -d a.o
    
    a.o:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000000000 <main>:
       0:    55                       push   %rbp
       1:    48 89 e5                 mov    %rsp,%rbp
       4:    48 83 ec 10              sub    $0x10,%rsp
       8:    c7 45 fc 64 00 00 00     movl   $0x64,-0x4(%rbp)
       f:    48 8d 45 fc              lea    -0x4(%rbp),%rax
      13:    be 00 00 00 00           mov    $0x0,%esi     //00 00 00 00 shared 未给地址
      18:    48 89 c7                 mov    %rax,%rdi
      1b:    b8 00 00 00 00           mov    $0x0,%eax
      20:    e8 00 00 00 00           callq  25 <main+0x25> //swap函数也未给地址
      25:    c9                       leaveq 
      26:    c3                       retq   

    5、经过ld链接之后,在最后文件ab中,shared 与 swap都知道了地址。因为链接过程会分配虚拟地址,那么根据前面第三点链接过后的信息,可以知道各个段的虚拟地址,那么

    其中各个符号的地址也会知道。那么,经过连接之后,ab中的代码反汇编结果如何,如下所示:

    [root@tlinux misc]# objdump -d ab
    
    ab:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    00000000004000e8 <main>:
      4000e8:    55                       push   %rbp
      4000e9:    48 89 e5                 mov    %rsp,%rbp
      4000ec:    48 83 ec 10              sub    $0x10,%rsp
      4000f0:    c7 45 fc 64 00 00 00     movl   $0x64,-0x4(%rbp)
      4000f7:    48 8d 45 fc              lea    -0x4(%rbp),%rax
      4000fb:    be 00 10 60 00           mov    $0x601000,%esi        //00 60 10 00 详见ab文件的数据段
      400100:    48 89 c7                 mov    %rax,%rdi
      400103:    b8 00 00 00 00           mov    $0x0,%eax
      400108:    e8 02 00 00 00(相对下一行命令偏移 02)           callq  40010f <swap>   // 由下面swap在 40010f处可知,a.o  b.o链接到一起后,swap的函数虚拟地址可知   call 命令: 40010d+00000002
      40010d:    c9                       leaveq 
      40010e:    c3                       retq   
    
    000000000040010f <swap>:
      40010f:    55                       push   %rbp
      400110:    48 89 e5                 mov    %rsp,%rbp
      400113:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
      400117:    48 89 75 f0              mov    %rsi,-0x10(%rbp)
      40011b:    48 8b 45 f8              mov    -0x8(%rbp),%rax
      40011f:    8b 10                    mov    (%rax),%edx
      400121:    48 8b 45 f0              mov    -0x10(%rbp),%rax
      400125:    8b 08                    mov    (%rax),%ecx
      400127:    48 8b 45 f8              mov    -0x8(%rbp),%rax
      40012b:    8b 30                    mov    (%rax),%esi
      40012d:    48 8b 45 f0              mov    -0x10(%rbp),%rax
      400131:    8b 00                    mov    (%rax),%eax
      400133:    31 c6                    xor    %eax,%esi
      400135:    48 8b 45 f8              mov    -0x8(%rbp),%rax
      400139:    89 30                    mov    %esi,(%rax)
      40013b:    48 8b 45 f8              mov    -0x8(%rbp),%rax
      40013f:    8b 00                    mov    (%rax),%eax
      400141:    31 c1                    xor    %eax,%ecx
      400143:    48 8b 45 f0              mov    -0x10(%rbp),%rax
      400147:    89 08                    mov    %ecx,(%rax)
      400149:    48 8b 45 f0              mov    -0x10(%rbp),%rax
      40014d:    8b 00                    mov    (%rax),%eax
      40014f:    31 c2                    xor    %eax,%edx
      400151:    48 8b 45 f8              mov    -0x8(%rbp),%rax
      400155:    89 10                    mov    %edx,(%rax)
      400157:    5d                       pop    %rbp
      400158:    c3                       retq  

     6、重定位表信息:

    对于可重定位文件,必须包含重定位表,用来描述如何修改相应的段。可以利用objdump  -r  a.o查看重定位表

    [root@tlinux misc]# objdump -r a.o
    
    a.o:     file format elf64-x86-64
    
    RELOCATION RECORDS FOR [.text]:
    OFFSET           TYPE              VALUE 
    0000000000000014 R_X86_64_32       shared
    0000000000000021 R_X86_64_PC32     swap-0x0000000000000004
    OFFSET指的是需要被重定位的内容在可重定位文件中的位置,看第4点的反汇编内容可知,0x14位置和0x21位置分别为shared 与 swap.需要被重定位
  • 相关阅读:
    [SSRS] Use Enum values in filter expressions Dynamics 365 Finance and Operation
    Power shell deploy all SSRS report d365 FO
    display method in Dynamics 365 FO
    How To Debug Dynamics 365 Finance and Operation
    Computed columns and virtual fields in data entities Dynamics 365
    Azure DevOps for Power Platform Build Pipeline
    Create readonly entities that expose financial dimensions Dynamics 365
    Dataentity call stack dynamics 365
    Dynamics 365 FO extension
    Use singletenant servertoserver authentication PowerApps
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/10622736.html
Copyright © 2011-2022 走看看