linux下elf二进制文件怎么回事(ls,vmstat等命令)
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());
return0;
}
编译
[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 2617:35 pagesize.c
-rw-r--r-- 1 root root 575 Feb 2617: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:    4889 e5                mov    %rsp,%rbp
4:    4883 ec 10              sub    $0x10,%rsp
王者荣耀星元皮肤
8:    89 7d fc                mov    %edi,-0x4(%rbp)
b:    488975 f0              mov    %rsi,-0x10(%rbp)
f:    e8 00000000          callq  14 <main+0x14>
14:    89 c6                    mov    %eax,%esi
16:    bf 00000000          mov    $0x0,%edi
1b:    b8 00000000          mov    $0x0,%eax
20:    e8 00000000          callq  25 <main+0x25>
25:    b8 00000000          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:    4889 e5                mov    %rsp,%rbp
400584:    4883 ec 10              sub    $0x10,%rsp
400588:    89 7d fc                mov    %edi,-0x4(%rbp)
40058b:    488975 f0              mov    %rsi,-0x10(%rbp)
40058f:    e8 ec fe ff ff          callq  400480 <getpagesize@plt>
400594:    89 c6                    mov    %eax,%esi
400596:    bf 40064000          mov    $0x400640,%edi
40059b:    b8 00000000          mov    $0x0,%eax
4005a0:    e8 ab fe ff ff          callq  400450 <printf@plt>
4005a5:    b8 00000000          mov    $0x0,%eax
4005aa:    c9                      leaveq
4005ab:    c3                      retq
4005ac:    0f 1f 4000              nopl  0x0(%rax)
我们读取elf可执⾏⽂件可以通过readelf 命令
参数列表解释:
-a 显⽰全部信息              -r 显⽰可重定位段的信息
-h 显⽰ELF⽂件开始的⽂件头信息 -d 显⽰动态段的信息
-l 显⽰程序头(段头)信息      -V 显⽰版本段的信息
-S 显⽰节点头信息            -A 显⽰CPU架构信息
-g 显⽰节组信息              -D 使⽤动态段中的符号表显⽰符号,⽽不是使⽤符号段
-t 显⽰节的详细信息          -I 显⽰符号的时候,显⽰bucket list长度的柱状图
-
s 显⽰符号表段中的项        -W 宽⾏输出
-e 显⽰全部头信息            -H 显⽰readeif所⽀持的命令⾏选项
-n 显⽰note段的信息
readelf读取⼆进制pagesize程序
[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            000000000000000000000000
00000000000000000000000000000000000
大卫 鲍威
[ 1] .interp          PROGBITS        000000000040023800000238
000000000000001c  0000000000000000  A      001
[ 2] .note.ABI-tag    NOTE            000000000040025400000254
00000000000000200000000000000000  A      004
[ 3] .u.build-i NOTE            000000000040027400000274
00000000000000240000000000000000  A      004
[ 4] .gnu.hash        GNU_HASH        000000000040029800000298
000000000000001c  0000000000000000  A      508
[ 5] .dynsym          DYNSYM          00000000004002b8  000002b8
00000000000000780000000000000018  A      618
[ 6] .dynstr          STRTAB          000000000040033000000330
000000000000004b  0000000000000000  A      001
[ 7] .gnu.version      VERSYM          000000000040037c  0000037c
000000000000000a  0000000000000002  A      502
[ 8] .gnu.version_r    VERNEED          000000000040038800000388
00000000000000200000000000000000  A      618
[ 9] .rela.dyn        RELA            00000000004003a8  000003a8
00000000000000180000000000000018  A      508
[10] .rela.plt        RELA            00000000004003c0  000003c0
00000000000000600000000000000018  A      5128
[11] .init            PROGBITS        000000000040042000000420
000000000000001a  0000000000000000  AX      004
[12] .plt              PROGBITS        000000000040044000000440
00000000000000500000000000000010  AX      0016
[13] .text            PROGBITS        000000000040049000000490
00000000000001920000000000000000  AX      0016
[14] .fini            PROGBITS        000000000040062400000624
00000000000000090000000000000000  AX      004
[15] .rodata          PROGBITS        000000000040063000000630
000000000000002d  0000000000000000  A      008
[16] .eh_frame_hdr    PROGBITS        000000000040066000000660
00000000000000340000000000000000  A      004
[17] .eh_frame        PROGBITS        000000000040069800000698
00000000000000f4  0000000000000000  A      008
[18] .init_array      INIT_ARRAY      0000000000600e10  00000e10
00000000000000080000000000000000  WA      008
[19] .fini_array      FINI_ARRAY      0000000000600e18  00000e18
00000000000000080000000000000000  WA      008
[20] .jcr              PROGBITS        0000000000600e20  00000e20
发芽土豆去掉芽能吃吗
00000000000000080000000000000000  WA      008
[21] .dynamic          DYNAMIC          0000000000600e28  00000e28
00000000000001d0  0000000000000010  WA      608
[22] .got              PROGBITS        0000000000600ff8  00000ff8
00000000000000080000000000000008  WA      008
[23] .got.plt          PROGBITS        000000000060100000001000
00000000000000380000000000000008  WA      008
[24] .data            PROGBITS        000000000060103800001038
00000000000000040000000000000000  WA      004
[25] .bss              NOBITS          000000000060103c  0000103c
00000000000000040000000000000000  WA      004
[26] ment          PROGBITS        0000000000000000  0000103c
000000000000005a  0000000000000001  MS      001
[27] .shstrtab        STRTAB          000000000000000000001096
00000000000001080000000000000000001
[28] .symtab          SYMTAB          000000000000000000001920
0000000000000630000000000000001829458
[29] .strtab          STRTAB          0000000000000000  00001f50
00000000000002550000000000000000001
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 shar
ed 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
查看⼀下相关其他信息对⽐
ldd命令⽤于打印程序或者库⽂件所依赖的共享库列表
[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 2614892022427292      6a9c    /usr/bin/vmstat [root@fp-web-112 test]# size pagesize
text      data        bss        dec        hex    filename 133955641899        76b    pagesize

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。