2020-08-20 2020-08-17 2020-08-14 Android系统安全和反编译实战_笔记(四)

目标文件里有什么?

编译器编译源代码后生成的文件叫目标文件,
那么目标文件存放的到底是什么?
或者我们的源代码在经过编译以后是怎么存储的?
让我们剥开目标文件的层层外壳,去探索它最本质的内容。

目标文件从结构上讲,它是已经编译后的可执行文件格式,只是还没有经过链接的过程,其中可能有些符号或有些地址还没有被调整。其实他本身就是按照可执行文件格式存储的,只是根真正的可执行文件在结构上稍有不同

目标文件就是源代码编译后但未进行链接的那些中间文件

可执行文件格式涵盖了程序的编译、链接、装载和执行的各个方面。了解它的结构并深入剖析它对于认识系统、了解背后的机理大有好处。

目标文件的格式

  • PE
  • ELF
    *COFF

不光是可执行文件按照可执行文件格式存储。
按照可执行文件格式存储的文件有

  • 动态链接库
  • 静态链接库
  • 可执行文件
    ELF 标准把系统中按照 ELF 格式的文件归为如下
  • Linux 的 .o 可重定位文件
  • /bin/bash 文件 可执行文件
  • Linux .so 共享目标文件

这种文件包含了代码数据,可以在以下两种情况下使用。
一种是链接器可以使用这种文件跟其他的可重定位文件共享目标文件,产生新的目标文件。
第二种是动态链接器可以将几个这种共享目标文件可执行文件结合,作为进程映像的一部分来运行。
*核心转储文件 Linux 下的core dump。
可以在 Linux 下使用 file 命令来查看相应的文件格式。

61964:~ hahaha$ file /Users/hahaha/Desktop/hi/libbluetooth.so
/Users/hahaha/Desktop/hi/libbluetooth.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=04f69a9e32c4a40bfed145a687344691, stripped

目标文件是什么样的?

我们能猜到,目标文件中的内容至少有编译后的机器指令代码、数据。没错,除了这些内容意外,目标文件中还包括了链接时所需要的一些信息,比如符号表调试信息字符串等。一般目标文件将这些信息按照不同的属性,以 "节" (Section) 的形式存储,有时候也叫"段" (Segment)

ELF 文件

  • 文件头

描述整个文件的文件属性,包括文件是否可执行是静态链接还是动态链接入口地址(如果是可执行文件)、 目标硬件目标操作系统等信息,
文件头还包括一个段表 (Section Table),段表其实是一个描述文件中各个段的数组。段表描述了文件中各个段在文中的便移位置及段的属性等,从段表里面可以得到各个段的所有信息。

  • 各个段的内容

文件头后面就是各个段的内容,比如
代码段保存的就是程序的指令,
数据段保存的就是程序的静态变量等。

    • .text 段

一般 C语言编译后执行语句都编译成机器代码,保存在 .text 段;

    • .data 段

已初始化的全局变量局部静态变量都保存在 .data 段;

    • .bss

未初始化的全局变量和局部静态变量一般放在一个叫 ".bss" 的段里。我们知道未初始化的全局变量和静态变量默认值都为0, 本来它们也可以放在 .data 段的,但是因为它们都是0,所以为它们在 .data 段分配空间并且存放数据0是没有必要的。程序运行的时候它们的确要占内存空间的,并且可执行文件必须记录所有未初始化的全局变量局部变量的大小总和,记为 .bss 段。所以 .bss 段只是为未初始化的全局变量和局部静态变量预留位置而已,它并没有内容,所以它在文件中也不占据空间。

总体来说,程序源代码被编译以后主要分成两种段: 程序指令和程序数据。代码段属于程序指令,而数据段和.bss段属于程序数据。

为什么要把指令和数据的存放分开?

  • 一方面
    进程
  • 另一方面
    CPU 缓存
  • 第三个原因
    其实也是最重要的原因,共享资源节省大量内存

挖掘 SimpleSection.o

代码

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

int global_init_var = 84;
int global_uinit_var;
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;
}
hahaha:hi hahaha$ gcc -c SimpleSection.c # (参数 -c 表示只编译不链接 )
hahaha:hi hahaha$ ls -l /Users/hahaha/Desktop/hi/SimpleSection.o 
-rw-r--r--  1 hahaha  INTERNAL\Domain Users  1252  8 20 14:19 /Users/hahaha/Desktop/hi/SimpleSection.o
我们得到了一个 1252 字节(该文件大小可能会因为编译器版本及机器平台不同而发生变化) 的 SimpleSection.o 目标文件。

用 binutils 的工具 objdump 来查看 object 内部的结构。

 hahaha:hi hahahau$ objdump -h SimpleSection.o

SimpleSection.o:    file format Mach-O 64-bit x86-64

Sections:
Idx Name          Size      Address          Type
  0 __text        00000068 0000000000000000 TEXT 
  1 __data        00000008 0000000000000068 DATA 
  2 __cstring     00000004 0000000000000070 DATA 
  3 __bss         00000004 0000000000000120 BSS
  4 __compact_unwind 00000040 0000000000000078 DATA 
  5 __eh_frame    00000068 00000000000000b8 DATA 

有一个专门的命令叫做 "size",它可以用来查看 ELF 文件的代码段、数据段和 BSS段的长度

hahaha:hi hahaha$ size SimpleSection.o
__TEXT  __DATA  __OBJC  others  dec hex
212 12  0   64  288 120

代码段

objdump
"-s" 参数可以将所有段的内容十六进制的方式打印出来,
“-d” 参数可以将所有包含指令的段反汇编

hahaha:hi v_liuxiaoju$ objdump -s -d SimpleSection.o

SimpleSection.o:    file format Mach-O 64-bit x86-64

Disassembly of section __TEXT,__text:
_func1:
       0:   55  pushq   %rbp
       1:   48 89 e5    movq    %rsp, %rbp
       4:   48 83 ec 10     subq    $16, %rsp
       8:   48 8d 05 61 00 00 00    leaq    97(%rip), %rax
       f:   89 7d fc    movl    %edi, -4(%rbp)
      12:   8b 75 fc    movl    -4(%rbp), %esi
      15:   48 89 c7    movq    %rax, %rdi
      18:   b0 00   movb    $0, %al
      1a:   e8 00 00 00 00  callq   0 <_func1+0x1f>
      1f:   89 45 f8    movl    %eax, -8(%rbp)
      22:   48 83 c4 10     addq    $16, %rsp
      26:   5d  popq    %rbp
      27:   c3  retq
      28:   0f 1f 84 00 00 00 00 00     nopl    (%rax,%rax)

_main:
      30:   55  pushq   %rbp
      31:   48 89 e5    movq    %rsp, %rbp
      34:   48 83 ec 10     subq    $16, %rsp
      38:   c7 45 fc 00 00 00 00    movl    $0, -4(%rbp)
      3f:   c7 45 f8 01 00 00 00    movl    $1, -8(%rbp)
      46:   8b 05 00 00 00 00   movl    (%rip), %eax
      4c:   03 05 00 00 00 00   addl    (%rip), %eax
      52:   03 45 f8    addl    -8(%rbp), %eax
      55:   03 45 f4    addl    -12(%rbp), %eax
      58:   89 c7   movl    %eax, %edi
      5a:   e8 00 00 00 00  callq   0 <_main+0x2f>
      5f:   8b 45 f8    movl    -8(%rbp), %eax
      62:   48 83 c4 10     addq    $16, %rsp
      66:   5d  popq    %rbp
      67:   c3  retq
Contents of section __text:
 0000 554889e5 4883ec10 488d0561 00000089  UH..H...H..a....
 0010 7dfc8b75 fc4889c7 b000e800 00000089  }..u.H..........
 0020 45f84883 c4105dc3 0f1f8400 00000000  E.H...].........
 0030 554889e5 4883ec10 c745fc00 000000c7  UH..H....E......
 0040 45f80100 00008b05 00000000 03050000  E...............
 0050 00000345 f80345f4 89c7e800 0000008b  ...E..E.........
 0060 45f84883 c4105dc3                    E.H...].
Contents of section __data:
 0068 54000000 55000000                    T...U...
Contents of section __cstring:
 0070 25640a00                             %d..
Contents of section __bss:
<skipping contents of bss section at [0120, 0124)>
Contents of section __compact_unwind:
 0078 00000000 00000000 28000000 00000001  ........(.......
 0088 00000000 00000000 00000000 00000000  ................
 0098 30000000 00000000 38000000 00000001  0.......8.......
 00a8 00000000 00000000 00000000 00000000  ................
Contents of section __eh_frame:
 00b8 14000000 00000000 017a5200 01781001  .........zR..x..
 00c8 100c0708 90010000 24000000 1c000000  ........$.......
 00d8 28ffffff ffffffff 28000000 00000000  (.......(.......
 00e8 00410e10 8602430d 06000000 00000000  .A....C.........
 00f8 24000000 44000000 30ffffff ffffffff  $...D...0.......
 0108 38000000 00000000 00410e10 8602430d  8........A....C.
 0118 06000000 00000000     
  • Contents of section_text 就是 .text的数据以十六进制方式打印出来的内容。
    • 最左面一位是偏移量
    • 中间一位是十六进制内容
    • 最右面一列是 .text 段的 ASCII 码形式。

对照上面的反汇编结果,可以明显地看到,
.text 段里所包含的正是 SimpleSection.c 里两个函数 fun1() 和 main() 的指令。
.text 段的第一个字节 "ox55"
就是 "func1()"函数的第一条指令 pushq %rbp 指令,
而最后一个字节 0xc3 正是 main() 函数的最后一条指令 "retq"

数据段和只读数据段

.data 保存的是那些已经****

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350