/*nmtest.c*/
1 #include<stdio.h>
2
3 int global1;
4 int global2 = 3;
5
6 static int static_global1 = 1;
7
8 static int static_global2 = 3;
9
10 void foo ()
11 {
12 static int internal1;
13 static int internal2;
14
15 time (0);
16 }
17
18 static void bar ()
19 {
20
21 }
22
23 int main ()
24 {
25 int local1;
26 int local2 = 3;
27
28 foo ();
29
30 return 0;
31 }
~
上面的代碼存在各種數據,全局變量,全局靜態變量,局部變量,靜態局部變量等,我們可以采用nm找到各個符號的存儲位置。
下面是采用nm的實現效果:nm -n objtarget
[gong@Gong-Computer bintools]$ gcc -g nmtest.c -o nmtest
[gong@Gong-Computer bintools]$ nm -n nmtest
w _Jv_RegisterClasses
w __gmon_start__
U __libc_start_main@@GLIBC_2.0
U time@@GLIBC_2.0
08048290 T _init
08048300 T _start
08048330 t __do_global_dtors_aux
08048390 t frame_dummy
080483b4 T foo
080483c8 t bar
080483cd T main
080483f0 T __libc_csu_init
08048450 T __libc_csu_fini
08048455 T __i686.get_pc_thunk.bx
08048460 t __do_global_ctors_aux
0804848c T _fini
080484a8 R _fp_hw
080484ac R _IO_stdin_used
080484b0 R __dso_handle
08048550 r __FRAME_END__
08049554 d __CTOR_LIST__
08049554 d __init_array_end
08049554 d __init_array_start
08049558 d __CTOR_END__
0804955c d __DTOR_LIST__
08049560 D __DTOR_END__
08049564 d __JCR_END__
08049564 d __JCR_LIST__
08049568 d _DYNAMIC
08049634 d _GLOBAL_OFFSET_TABLE_
0804964c D __data_start
0804964c W data_start
08049650 D global2
08049654 d static_global1
08049658 d static_global2
0804965c A __bss_start
0804965c A _edata
0804965c b completed.5530
08049660 b dtor_idx.5532
08049664 b internal2.1676
08049668 b internal1.1675
0804966c B global1
08049670 A _end
上面的紅色部分就是我們的幾個變量,其中我們可以發現主要存在三列數據,分別是地址,以及所在段(.text,.data,.bss等),最后是符號名,函數名,全局變量,靜態數據都是符號。
其中第二列的字母分別表示對應的段:
A 表示不會改變的,即使在鏈接過程中
B 表示.bss段
C 表示沒有被初始化的公共符號
D 表示.data段
N 表示符號用于調試
P 表示符號位域一個棧中
R 表示在只讀數據段中
T和t 表示在代碼段中,對于函數名作為符號,若是"T"表示為非靜態函數,而"t"表示為靜態函數
U 表示沒有定義
根據上面的說明分析上面的結果可以知道對于靜態變量不是存儲在.data段中就是存儲在.bss段中,具體的根據是否初始化判斷。全局變量的分配也與是否初始化有關,不是存在于.data中就是在.bss中,而局部變量不能通過nm看到。
4、objdump工具,該工具主要用于查看數據,可以查看目標文件的段(sections),可以查看目標文件的信息。通常使用的幾個組合為:
4.1查看目標文件的段信息: objdump -h objtarget
4.2 查看目標文件的匯編代碼: objdump -d objtarget
源碼和匯編代碼對照顯示: objdump -S -d objtarget
4.3 查看具體段的信息: objdump -s -j .data(某一個段) objtarget 其中的-s表示顯示具體的內容,而-j 表示選擇某一個段。
4.4 查看程序的入口地址: objdump -f objtarget
5、段剪輯工具,可以操作具體的某一個段,可以刪除和剪輯以及濾除調試信息等
5.1剪輯具體的某一段到一個新的目標文件: objcopy -j .data(某一個段) objtarget newtarget
5.2 刪除具體的某一個段:objcopy -R .data(某一個段) objtarget newtarget
5.3 濾除調試信息 objcopy --strip-debug objtarget
通常是objdump 和objcopy 結合使用,這樣就能得到具體的信息。采用上面的nmtest.c進行演示。
[gong@Gong-Computer bintools]$ objcopy -j .data nmtest newtarget
BFD: nmtest: warning: Empty loadable segment detected, is this intentional ?
[gong@Gong-Computer bintools]$ ls -a
. .. arm_nmtest arm_nmtest.txt arm_test arm_test_cpp cppmain main.c newtarget nmtest nmtest.c onlytext string string.c target test
[gong@Gong-Computer bintools]$ objdump -h newtarget
newtarget: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000010 0804964c 0804964c 0000064c 2**2
CONTENTS, ALLOC, LOAD, DATA
[gong@Gong-Computer bintools]$ objcopy -j .data -j .text -j .bss nmtest newtarget
[gong@Gong-Computer bintools]$ objdump -h newtarget
newtarget: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000018c 08048300 08048300 00000300 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000010 0804964c 0804964c 0000064c 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000014 0804965c 0804965c 0000065c 2**2
ALLOC
[gong@Gong-Computer bintools]$ objcopy -R .text newtarget
BFD: newtarget: warning: Empty loadable segment detected, is this intentional ?
[gong@Gong-Computer bintools]$ objdump -h newtarget
newtarget: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000010 0804964c 0804964c 0000064c 2**2
CONTENTS, ALLOC, LOAD, DATA
1 .bss 00000014 0804965c 0804965c 0000065c 2**2
ALLOC
查看程序與對應的匯編代碼:
ALLOC
[gong@Gong-Computer bintools]$ objdump -S -d nmtest
nmtest: file format elf32-i386
Disassembly of section .init:
...
void foo ()
{
80483b4: 55 push %ebp
80483b5: 89 e5 mov %esp,%ebp
80483b7: 83 ec 18 sub $0x18,%esp
static int internal1;
static int internal2;
time (0);
80483ba: c7 04 24 00 00 00 00 movl $0x0,(%esp)
80483c1: e8 2a ff ff ff call 80482f0 <time@plt>
}
80483c6: c9 leave
80483c7: c3 ret
080483c8 <bar>:
static void bar ()
{
80483c8: 55 push %ebp
80483c9: 89 e5 mov %esp,%ebp
}
80483cb: 5d pop %ebp
80483cc: c3 ret
080483cd <main>:
int main ()
{
80483cd: 55 push %ebp
80483ce: 89 e5 mov %esp,%ebp
80483d0: 83 e4 f0 and $0xfffffff0,%esp
80483d3: 83 ec 10 sub $0x10,%esp
int local1;
int local2 = 3;
80483d6: c7 44 24 0c 03 00 00 movl $0x3,0xc(%esp)
80483dd: 00
foo ();
80483de: e8 d1 ff ff ff call 80483b4 <foo>
return 0;
80483e3: b8 00 00 00 00 mov $0x0,%eax
}
...
上面的就是通過objdump的反匯編代碼。
濾除的效果如下:
[gong@Gong-Computer bintools]$ objdump -h nmtest
nmtest: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 08048134 08048134 00000134 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 08048148 08048148 00000148 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 08048168 08048168 00000168 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 00000020 0804818c 0804818c 0000018c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000050 080481ac 080481ac 000001ac 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 0000004a 080481fc 080481fc 000001fc 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 0000000a 08048246 08048246 00000246 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000020 08048250 08048250 00000250 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rel.dyn 00000008 08048270 08048270 00000270 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rel.plt 00000018 08048278 08048278 00000278 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000030 08048290 08048290 00000290 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000040 080482c0 080482c0 000002c0 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text 0000018c 08048300 08048300 00000300 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000001c 0804848c 0804848c 0000048c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 0000000c 080484a8 080484a8 000004a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .eh_frame_hdr 00000024 080484b4 080484b4 000004b4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame 0000007c 080484d8 080484d8 000004d8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .ctors 00000008 08049554 08049554 00000554 2**2
CONTENTS, ALLOC, LOAD, DATA
18 .dtors 00000008 0804955c 0804955c 0000055c 2**2
CONTENTS, ALLOC, LOAD, DATA
19 .jcr 00000004 08049564 08049564 00000564 2**2
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 000000c8 08049568 08049568 00000568 2**2
CONTENTS, ALLOC, LOAD, DATA
21 .got 00000004 08049630 08049630 00000630 2**2
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 00000018 08049634 08049634 00000634 2**2
CONTENTS, ALLOC, LOAD, DATA
23 .data 00000010 0804964c 0804964c 0000064c 2**2
CONTENTS, ALLOC, LOAD, DATA
24 .bss 00000014 0804965c 0804965c 0000065c 2**2
ALLOC
25 .comment 0000002c 00000000 00000000 0000065c 2**0
CONTENTS, READONLY
26 .debug_aranges 00000020 00000000 00000000 00000688 2**0
CONTENTS, READONLY, DEBUGGING
27 .debug_pubnames 0000003b 00000000 00000000 000006a8 2**0
CONTENTS, READONLY, DEBUGGING
28 .debug_info 00000146 00000000 00000000 000006e3 2**0
CONTENTS, READONLY, DEBUGGING
29 .debug_abbrev 000000aa 00000000 00000000 00000829 2**0
CONTENTS, READONLY, DEBUGGING
30 .debug_line 00000041 00000000 00000000 000008d3 2**0
CONTENTS, READONLY, DEBUGGING
31 .debug_frame 00000074 00000000 00000000 00000914 2**2
CONTENTS, READONLY, DEBUGGING
32 .debug_str 000000eb 00000000 00000000 00000988 2**0
CONTENTS, READONLY, DEBUGGING
33 .debug_pubtypes 00000012 00000000 00000000 00000a73 2**0
CONTENTS, READONLY, DEBUGGING
一共33個段
[gong@Gong-Computer bintools]$ objcopy --strip-debug nmtest
[gong@Gong-Computer bintools]$ objdump -h nmtest
nmtest: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 08048134 08048134 00000134 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 08048148 08048148 00000148 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 08048168 08048168 00000168 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 00000020 0804818c 0804818c 0000018c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000050 080481ac 080481ac 000001ac 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 0000004a 080481fc 080481fc 000001fc 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 0000000a 08048246 08048246 00000246 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000020 08048250 08048250 00000250 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rel.dyn 00000008 08048270 08048270 00000270 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rel.plt 00000018 08048278 08048278 00000278 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000030 08048290 08048290 00000290 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000040 080482c0 080482c0 000002c0 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text 0000018c 08048300 08048300 00000300 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000001c 0804848c 0804848c 0000048c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 0000000c 080484a8 080484a8 000004a8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .eh_frame_hdr 00000024 080484b4 080484b4 000004b4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame 0000007c 080484d8 080484d8 000004d8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .ctors 00000008 08049554 08049554 00000554 2**2
CONTENTS, ALLOC, LOAD, DATA
18 .dtors 00000008 0804955c 0804955c 0000055c 2**2
CONTENTS, ALLOC, LOAD, DATA
19 .jcr 00000004 08049564 08049564 00000564 2**2
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 000000c8 08049568 08049568 00000568 2**2
CONTENTS, ALLOC, LOAD, DATA
21 .got 00000004 08049630 08049630 00000630 2**2
CONTENTS, ALLOC, LOAD, DATA
22 .got.plt 00000018 08049634 08049634 00000634 2**2
CONTENTS, ALLOC, LOAD, DATA
23 .data 00000010 0804964c 0804964c 0000064c 2**2
CONTENTS, ALLOC, LOAD, DATA
24 .bss 00000014 0804965c 0804965c 0000065c 2**2
ALLOC
25 .comment 0000002c 00000000 00000000 0000065c 2**0
CONTENTS, READONLY
這次只有25個段。
通過上面的分析可以發現調試信息減少了,這就實現了具體的濾除操作。
上面的這些工具只有在經常的運用才能有很好的效果啊,特別是出現錯誤時用來分析。