linux下elf二进制文件怎么回事(ls,vmstat等命令)

2022/2/27 7:21:46

本文主要是介绍linux下elf二进制文件怎么回事(ls,vmstat等命令),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

这个实验有两个目的:
1、linux的可执行命令例如:ls 、cd等都是二进制elf格式文件等,后面的逻辑是什么,我们怎么窥探底层内容。
2、ELF可执行文件默认从地址0x080480000开始分配
3、./和 cp到/usr/bin下就可以直接执行命令

4、写一个c程序获取Linux 内存页基页大小
//环境采样:
[root@fp-web-112 src]# rpm -qa |grep gcc
gcc-4.8.5-44.el7.x86_64
libgcc-4.8.5-44.el7.x86_64
如果没有gcc,你可以yum install gcc即可

一、直接创建编写pagesiz.c 文件
[root@fp-web-112 src]# vi pagesize.c
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
   printf("linux page size is %d bytes ",getpagesize());
   return 0;
}
 编译
[root@fp-web-112 src]#gcc -g pagesize.c -o pagesize -Wall
1、添加-Wall选项的作用:显示程序编译过程中产生的所有警告,而警告并不会对输出结果产生影响

执行有两种方式

  1、利用./ 方式

[root@fp-web-112 src]#./pagesize
linux page size is 4096 bytes

  2. 复制到 /usr/bin 目录下就不用./ 直接像我们平时的ls等命令一样执行了

  [root@fp-web-112 test]# cp pagesize /usr/bin/pagesize
  [root@fp-web-112 test]# pagesize
   linux page size is 4096 bytes

 

 

 二、我们用另外一种方式来做,从汇编开始生成,一直到生成可执行文件 。

[root@fp-web-112 test]# gcc -S pagesize.c   //生成汇编
[root@fp-web-112 test]# ll
total 8
-rw-r--r-- 1 root root 149 Feb 26 17:35 pagesize.c
-rw-r--r-- 1 root root 575 Feb 26 17:37 pagesize.s
[root@fp-web-112 test]# cat pagesize.s
//查看汇编代码
[root@fp-web-112 test]# cat pagesize.s
    .file    "pagesize.c"
    .section    .rodata
.LC0:
    .string    "linux page size is %d bytes "
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    call    getpagesize
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
    .section    .note.GNU-stack,"",@progbits

  产生pagesize.o的二进制代码,将汇编文件中的汇编代码翻译成相应的机器语言,这个过程叫做汇编,

[root@fp-web-112 test]# gcc -c -o pagesize.o pagesize.s
链接阶断将二进制代码生成一个操作系统可以识别的可执行文件格式,linux是elf格式,windows上是pe格式
[root@fp-web-112 test]# objdump -d pagesize.o
pagesize.o:     file format elf64-x86-64  //elf格式
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:    89 7d fc                 mov    %edi,-0x4(%rbp)
   b:    48 89 75 f0              mov    %rsi,-0x10(%rbp)
   f:    e8 00 00 00 00           callq  14 <main+0x14>
  14:    89 c6                    mov    %eax,%esi
  16:    bf 00 00 00 00           mov    $0x0,%edi
  1b:    b8 00 00 00 00           mov    $0x0,%eax
  20:    e8 00 00 00 00           callq  25 <main+0x25>
  25:    b8 00 00 00 00           mov    $0x0,%eax
  2a:    c9                       leaveq 
  2b:    c3                       retq   

 生成最终的可执行文件pagesize

[root@fp-web-112 test]# ./pagesize.o
-bash: ./pagesize.o: Permission denied
[root@fp-web-112 test]# sh ./pagesize.o
./pagesize.o: ./pagesize.o: cannot execute binary file

//还要执行一步,生成最终的可执行文件
[root@fp-web-112 test]#gcc pagesize.o -o pagesize

[root@fp-web-112 test]# ll
total 24
-rwxr-xr-x 1 root root 8613 Feb 26 17:54 pagesize
-rw-r--r-- 1 root root 149 Feb 26 17:35 pagesize.c
-rw-r--r-- 1 root root 1600 Feb 26 17:47 pagesize.o
-rw-r--r-- 1 root root 575 Feb 26 17:37 pagesize.s

//执行。
[root@fp-web-112 test]# ./pagesize
linux page size is 4096 bytes



ELF可执行文件默认从地址0x080480000开始分配,我们反汇编一下可执行文件

反汇编特定函数
[root@fp-web-112 test]# nm -n pagesize | grep main -A 1
                 U __libc_start_main@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
--
0000000000400580 T main
00000000004005b0 T __libc_csu_init

反汇编main函数:(从nm取得的main执行的地址+0x)
[root@fp-web-112 test]# objdump -d pagesize --start-address=0x0000000000400580 --stop-address=0x00000000004005b0

[root@fp-web-112 test]# objdump -d pagesize --start-address=0x0000000000400580 --stop-address=0x00000000004005b0
pagesize:     file format elf64-x86-64
Disassembly of section .text:
0000000000400580 <main>:
  400580:    55                       push   %rbp
  400581:    48 89 e5                 mov    %rsp,%rbp
  400584:    48 83 ec 10              sub    $0x10,%rsp
  400588:    89 7d fc                 mov    %edi,-0x4(%rbp)
  40058b:    48 89 75 f0              mov    %rsi,-0x10(%rbp)
  40058f:    e8 ec fe ff ff           callq  400480 <getpagesize@plt>
  400594:    89 c6                    mov    %eax,%esi
  400596:    bf 40 06 40 00           mov    $0x400640,%edi
  40059b:    b8 00 00 00 00           mov    $0x0,%eax
  4005a0:    e8 ab fe ff ff           callq  400450 <printf@plt>
  4005a5:    b8 00 00 00 00           mov    $0x0,%eax
  4005aa:    c9                       leaveq 
  4005ab:    c3                       retq   
  4005ac:    0f 1f 40 00              nopl   0x0(%rax)

我们读取elf可执行文件可以通过readelf 命令

[root@fp-web-112 test]# readelf -S pagesize
There are 30 section headers, starting at offset 0x11a0:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
       000000000000001c  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000004002b8  000002b8
       0000000000000078  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           0000000000400330  00000330
       000000000000004b  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           000000000040037c  0000037c
       000000000000000a  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000400388  00000388
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             00000000004003a8  000003a8
       0000000000000018  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             00000000004003c0  000003c0
       0000000000000060  0000000000000018   A       5    12     8
  [11] .init             PROGBITS         0000000000400420  00000420
       000000000000001a  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         0000000000400440  00000440
       0000000000000050  0000000000000010  AX       0     0     16
  [13] .text             PROGBITS         0000000000400490  00000490
       0000000000000192  0000000000000000  AX       0     0     16
  [14] .fini             PROGBITS         0000000000400624  00000624
       0000000000000009  0000000000000000  AX       0     0     4
  [15] .rodata           PROGBITS         0000000000400630  00000630
       000000000000002d  0000000000000000   A       0     0     8
  [16] .eh_frame_hdr     PROGBITS         0000000000400660  00000660
       0000000000000034  0000000000000000   A       0     0     4
  [17] .eh_frame         PROGBITS         0000000000400698  00000698
       00000000000000f4  0000000000000000   A       0     0     8
  [18] .init_array       INIT_ARRAY       0000000000600e10  00000e10
       0000000000000008  0000000000000000  WA       0     0     8
  [19] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
       0000000000000008  0000000000000000  WA       0     0     8
  [20] .jcr              PROGBITS         0000000000600e20  00000e20
       0000000000000008  0000000000000000  WA       0     0     8
  [21] .dynamic          DYNAMIC          0000000000600e28  00000e28
       00000000000001d0  0000000000000010  WA       6     0     8
  [22] .got              PROGBITS         0000000000600ff8  00000ff8
       0000000000000008  0000000000000008  WA       0     0     8
  [23] .got.plt          PROGBITS         0000000000601000  00001000
       0000000000000038  0000000000000008  WA       0     0     8
  [24] .data             PROGBITS         0000000000601038  00001038
       0000000000000004  0000000000000000  WA       0     0     4
  [25] .bss              NOBITS           000000000060103c  0000103c
       0000000000000004  0000000000000000  WA       0     0     4
  [26] .comment          PROGBITS         0000000000000000  0000103c
       000000000000005a  0000000000000001  MS       0     0     1
  [27] .shstrtab         STRTAB           0000000000000000  00001096
       0000000000000108  0000000000000000           0     0     1
  [28] .symtab           SYMTAB           0000000000000000  00001920
       0000000000000630  0000000000000018          29    45     8
  [29] .strtab           STRTAB           0000000000000000  00001f50
       0000000000000255  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

 

我们用我做的程序对比一下

[root@fp-web-112 test]# file /usr/bin/vmstat
/usr/bin/vmstat: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=d43f957c6d26e040ee323b94b306885849d37390, stripped
[root@fp-web-112 test]# file pagesize
pagesize: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=fd709e827bd4d79078d9bbbfb8b91495f3491e35, not stripped

 

查看一下相关其他信息对比

[root@fp-web-112 test]# ldd pagesize

[root@fp-web-112 test]#  ldd pagesize
    linux-vdso.so.1 =>  (0x00007ffca4b69000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f9c3c583000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f9c3c94e000)

[root@fp-web-112 test]# ldd /usr/bin/vmstat
    linux-vdso.so.1 =>  (0x00007ffff83e2000)
    libprocps.so.4 => /lib64/libprocps.so.4 (0x00007f7b83f39000)
    libsystemd-login.so.0 => /lib64/libsystemd-login.so.0 (0x00007f7b83f2c000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007f7b83d27000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f7b83966000)
    librt.so.1 => /lib64/librt.so.1 (0x00007f7b8375e000)
    libcap.so.2 => /lib64/libcap.so.2 (0x00007f7b83558000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f7b83256000)
    libdw.so.1 => /lib64/libdw.so.1 (0x00007f7b8300f000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7b82df8000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7b82bdc000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f7b8416a000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00007f7b829d7000)
    libelf.so.1 => /lib64/libelf.so.1 (0x00007f7b827c0000)
    liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f7b8259b000)
    libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f7b8238b000)
    libz.so.1 => /lib64/libz.so.1 (0x00007f7b82174000)

比较大小

[root@fp-web-112 test]# size /usr/bin/vmstat 
   text       data        bss        dec        hex    filename
  26148        920        224      27292       6a9c    /usr/bin/vmstat
[root@fp-web-112 test]# size pagesize
   text       data        bss        dec        hex    filename
   1339        556          4       1899        76b    pagesize

 



这篇关于linux下elf二进制文件怎么回事(ls,vmstat等命令)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程