Linux程序调试查看二进制文件

摘要:
Filetest.obj test.obj:notstriped b)使用gcc和ar:notstriated生成静态库文件d)使用gcc-gcc-otesttest.c使用file:intglobal_init_var=84生成可执行文件;intglobal_ uninit_变量;静态全局_静态变量;
http://blog.sina.com.cn/s/blog_7a2fc53a0100y54h.html

一,二进制文件的类型

 

    Linux下的二进制文件是ELF格式的,主要有目标文件、静态链接库文件、动态链接库文件、可执行文件和core dump文件。可以使用如下命令查看其类型:

 

    file  文件名。

 

    我们还是以之前的例子test.c举例,test.c的源代码和之前的文章一样:

 

 


    int sub(int a,int b,int c){

          *(int *)a=16;
           return 0;
    }

    int main()
   {
       int a=0;
       int b=1;
       int c=2;
       sub(a,b,c);
       return 0;
   }

 

 

   a)使用gcc生成目标文件: gcc -c -o test.obj test.c

 

   使用file查看:

 

   file test.obj
   test.obj: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

 

 

 

   b)使用gcc 和ar生成静态库文件:

   gcc -c -o test.o test.c

   ar rcs libtest.a test.o

 

   使用file查看:

 

    file libtest.a
    libtest.a: current ar archive

   c)使用gcc生成动态链接库文件:

   gcc -fPIC -c -o test.o test.c

   gcc -shared -o libtest.so test.o

 

   使用file查看:

 

   file libtest.so
   libtest.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped

 

   d)使用gcc生成可执行文件

    gcc -o test test.c

 

    使用file查看:

 

   file test
   test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared libs), not stripped

 

   e)运行产生core dump 

   ./test

 

 

    使用file查看:

 

     file test-29728.core
     test-29728.core: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from './test'

 

 

二,查看二进制文件段的信息

 

    为了能够在查看二进制文件的同时,看到二进制文件中段的意义,采用的源代码如下所示:

 

*Linux:
   gcc -c SimpleSection.c
 *
 *Windows:
 * cl SimpleSection.c /c/Za
 */
int printf(const char*format,...);

int global_init_var=84;
int global_uninit_var;
static int global_static_var;
static int global_static_var1=1;
static int global_static_var0=0;
void func1(int i)
{

printf("%d/n",i);
}

int main(void){

 static int static_var=85;
 static int static_var2;
 int a=1;
 int b;

 func1(static_var+static_var2+a+b);

 return a;





}

 

   使用gcc 编译出目标文件: gcc -c -o SimpleObject.o SimpleObject.c

 

   使用binutils工具包中的objdump查看该二进制文件,-h表示查看段头:

 

 

objdump -h SimpleSection.o

SimpleSection.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000005b  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         0000000c  00000000  00000000  00000090  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          0000000c  00000000  00000000  0000009c  2**2
                  ALLOC
  3 .rodata       00000004  00000000  00000000  0000009c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002e  00000000  00000000  000000a0  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  00000000  00000000  000000ce  2**0
                  CONTENTS, READONLY

 

注解:

 

  VMA即 Virtual Memory Address,即虚拟地址

  LMA即 Load Memory Address即加载地址

 

  正常情况下这两个地址一样,有些嵌入式系统这两个值不同。

 

 

  .text是代码段,其大小为5b,在文件中的偏移是34

 

  .data是数据段,大小是0c,在文件中的偏移是90

 

  .bss是BSS段,大小是0c,文件中的偏移是9c

 

  .bss是存储未初始化的全局变量和静态局部变量。其实仅仅是给这些变量预留空间。此处便是:
static int global_static_var;static int global_static_var0=0;static int static_var2,共12字节。由于static int global_static_var0=0相当于没有初始化(没有初始化的值就是0),因而被编译器优化到了.bss,因为这样不占用磁盘空间。

 

int global_uninit_var则没有被放到任何段,而是作为未定义的COMMON符号。这个和不同语言、编译器实现有关,有的编译器放到.bss 段,有的仅仅是预留一个COMMON符号,在链接的时候再在.bss段分配预留空间。编译单元内部可见的静态变量,比如在上述中加上static的 static int global_static_var则确实被放到了.bss,是因为这个仅仅是编译单元内部可见。

 

 

  .rodata是只读数据段,大小是4,文件中偏移是9c。单独设立.rodata段,不仅仅直接在语义上支持了c++的const关键字,而且操作系统 加载的时候,可将其映射会只读,防止对只读数据的修改。在嵌入式平台下,有些时候使用ROM进行存储。有的编译器把字符串常量防到.data,而不是放 到.rodata,例如MSVC编译器就在编译C++的时候把字符串常量放置到.data段。

 

  .comment是注释信息段,大小是2e,文件中的偏移是a0

 

  .note.GNU-stack是GNU栈提示段,大小事0,文件中的偏移是ce

 

其中的属性 CONTENTS表示在文件中存在内容,没有该属性则表示在文件中不存在内容

 

这样,其结构如图:

 

 Linux程序调试查看二进制文件第1张

 

 

也可使用size命令查看各个段的大小、地址信息,-format表示使用的输出格式:

 

size --format=SysV SimpleSection.o
SimpleSection.o  :
section           size   addr
.text               91      0
.data               12      0
.bss                12      0
.rodata                  0
.comment            46      0
.note.GNU-stack          0
Total              165

 

三,查看段的内容

 

 

   使用 objdump的-s查看任何需要的段的内容,如果不指定段,则显示所有的非空段的内容,-d表示将代码段反汇编(disassemble)。

 

 

 Contents of section .text:
 0000 5589e583 ec088b45 08894424 04c70424  U......E..D$...$
 0010 00000000 e8fcffff ffc9c38d 4c240483  ............L$..
 0020 e4f0ff71 fc5589e5 5183ec14 c745f401  ...q.U..Q....E..
 0030 0000008b 15080000 00a10400 00008d04  ................
 0040 020345f4 0345f889 0424e8fc ffffff8b  ..E..E...$......
 0050 45f483c4 14595d8d 61fcc3             E....Y].a..    

Contents of section .data:
 0000 54000000 01000000 55000000           T.......U...   
Contents of section .rodata:
 0000 25640a00                             %d..           
Contents of section .comment:
 0000 00474343 3a202847 4e552920 342e312e  .GCC: (GNU) 4.1.
 0010 32203230 30383037 30342028 52656420  2 20080704 (Red
 0020 48617420 342e312e 322d3434 2900      Hat 4.1.2-44). 
Disassembly of section .text:

00000000 <func1>:
   0:   55                      push   �p
   1:   89 e5                   mov    %esp,�p
   3:   83 ec 08                sub    $0x8,%esp
   6:   8b 45 08                mov    0x8(�p),�x
   9:   89 44 24 04             mov    �x,0x4(%esp)
   d:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
  14:   e8 fc ff ff ff          call   15 <func1+0x15>
  19:   c9                      leave 
  1a:   c3               

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇asp.net core 系列 19 EFCore介绍android adb push 图片到相册后刷新 media 库下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

windows系统中Emacs的HOME目录及配置文件的正确路径

最近爱折腾的毛病又犯了,开始折腾起Emacs,在自定义Emacs的配置文件存放位置时遇到一点问题,不过,在GNU的Emacs站点,看到这么一段话: On Windows, the .emacs file may be called _emacs for backward compatibility with DOS and FAT filesystems...

Qt程序的字符编码方式

本节会创建一个图形界面 Qt 程序,并故意对源文件使用不恰当的字符编码方式,导致其文本显示控件的汉字乱码。我们会介绍两种纠正方法: 第一种是不修改源代码文件编码格式,通过 QString::fromLocal8Bit() 函数在程序运行时转码; 第二种是直接将源代码文件整体转换成 UTF-8 编码,就不需要修改具体的代码行了。 第二种是最为推荐的方式,...

linux下mysql的安装与使用

一、mysql的安装 之前搭建linux下项目的发布,最后遗留的问题时数据库的迁移,如何从windows上迁移到linux上?这里首先进行mysql数据库的安装 1、下载mysql安装包 在这里下载的是如下版本的mysql https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.26-linux-glibc...

Maven系列(二)之安装和配置详解

检查JDK环境 在安装Maven之前,首先要确认你已经正确安装了JDK。Maven可以运行在JDK 1.4及以上的版本上。 打开cmd输入: java -version 下载Maven Maven官网:http://maven.apache.org/download.html 这里下载此时此刻的最新版本Maven 3.3.9版本 解压下载好的apach...

Centos7 之 MariaDB(Mysql) root密码忘记的解决办法

MariaDB(Mysql) root密码忘记的解决办法 1.首先先关闭mariadb数据库的服务 # 关闭mariadb服务命令(mysql的话命令就是将mariadb换成mysql) [root@node ~]# systemctl stop mariadb # 通过进行查询服务或者通过端口查询服务还是否存在 [root@node ~]# ps aux...

Linux学习之Linux目录及文件系统

以往的 Windows 一直是以存储介质为主的,主要以盘符(C 盘,D 盘...)及分区来实现文件管理,然后之下才是目录,目录就显得不是那么重要,除系统文件之外的用户文件放在任何地方任何目录也是没有多大关系。所以通常 Windows 在使用一段时间后,磁盘上面的文件目录会显得杂乱无章(少数善于整理的用户除外吧)。然而 UNIX/Linux 恰好相反,UNI...