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

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 
  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  

猜你喜欢

转载自www.cnblogs.com/wsw-seu/p/10622736.html