用于复制和翻译目标文件的 Linux Objcopy 命令示例
有时您需要将可用于一种平台的目标文件移植到另一种平台。如果源代码可用,事情就相对容易了,因为它可以在目标平台上重新编译。但是,如果源代码不可用并且您仍然需要将目标文件从平台类型移植到其他平台怎么办?如果您使用的是 Linux,那么命令 objcopy 完全可以满足您的要求。在本文中,我们将通过一些示例来了解该命令的基本用法。
该命令的语法是:
objcopy [options] infile [outfile]...
请注意,'options' 和 'outfile' 不是强制性参数,但有其自身的意义。
例子
1.简单地将目标文件从源复制到目标
考虑以下示例:
$ objcopy test new_test
$
所以上面的命令会将'test'复制到一个新文件'new_test'中。请注意,由于在这种情况下,“test”是在同一平台上编译的,因此输出“new_test”将没有什么不同。
此外,如果您想反汇编二进制文件并获取有关目标文件的更多详细信息,则应使用objdump 命令,如前所述。
2.复制目标文件而不提供新文件名
在上面的示例中,复制的文件被命名为“new_test”,因为它与命令的选项一起提供。但是,如果没有提供目标文件名,则 objcopy 命令将原始文件替换为复制的文件。
考虑以下示例:
$ stat test
File: `test'
Size: 8498 Blocks: 24 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1442357 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/himanshu) Gid: ( 1001/ family)
Access: 2012-08-31 21:25:54.828808055 +0530
Modify: 2012-08-31 21:25:50.498614487 +0530
Change: 2012-08-31 21:25:50.498614487 +0530
$ objcopy test
$ stat test
File: `test'
Size: 8498 Blocks: 24 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1459714 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/himanshu) Gid: ( 1001/ family)
Access: 2012-08-31 21:30:04.108833244 +0530
Modify: 2012-08-31 21:30:04.108833244 +0530
Change: 2012-08-31 21:30:04.108833244 +0530
所以我们看到目标文件“test”的统计数据完全改变了,因为 objcopy 将它创建为一个全新的文件。
3. 使用 -j 选项仅复制特定部分
如果您只想将源目标文件中的一个部分复制到目标目标文件,则在这种情况下使用 -j 选项。
考虑以下示例:
$ objcopy -j.interp test new_test
$
上面的命令实际上只会将 .interp 部分复制到空的 new_test 文件中。
如果我们确认:
$ objdump -s new_test
new_test: file format elf64-x86-64
Contents of section .interp:
400238 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
400248 7838362d 36342e73 6f2e3200 x86-64.so.2.
所以我们看到这个文件只包含 .interp 部分(我们从 'test' 复制的)。
4. 使用 -R 选项从复制的文件中仅删除特定部分
此选项允许 objdump 命令复制完整的源文件,除了与此选项一起指定的部分。
考虑以下示例:
$ objcopy -R.interp test new_test
如果我们确认:
$ objdump -s -j.interp new_test
new_test: file format elf64-x86-64
所以我们看到新文件“new_test”中没有.interp 部分。
5. 使用 -p 选项保留访问和修改日期
通过使用 -p 选项和此命令,可以保留复制文件的访问和修改日期(可以与源保持相同)。
考虑以下示例:
$ objcopy -p test new_tst
上述命令将保留访问和修改日期/时间。
如果我们确认:
$ $ stat test
File: `test'
Size: 8498 Blocks: 24 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1459714 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/himanshu) Gid: ( 1001/ family)
Access: 2012-08-31 21:32:32.458629723 +0530
Modify: 2012-08-31 21:30:04.108833244 +0530
Change: 2012-08-31 21:30:04.108833244 +0530
$ stat new_tst
File: `new_tst'
Size: 8498 Blocks: 24 IO Block: 4096 regular file
Device: 805h/2053d Inode: 1442650 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/himanshu) Gid: ( 1001/ family)
Access: 2012-08-31 21:32:32.000000000 +0530
Modify: 2012-08-31 21:30:04.000000000 +0530
Change: 2012-08-31 21:42:25.938657423 +0530
所以我们看到访问和修改时间/日期都被保留了。
6. 使用–weaken 选项将所有全局符号更改为弱
这在构建可以使用链接器的 -R 选项与其他目标文件链接的目标文件时很有用。
考虑以下示例:
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 65 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
..
27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
28: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
29: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
..
49: 0000000000400550 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini
50: 0000000000400440 0 FUNC GLOBAL DEFAULT 14 _start
51: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
52: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
53: 0000000000400628 0 FUNC GLOBAL DEFAULT 15 _fini
54: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
55: 0000000000400638 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
..
$ objcopy --weaken test new_test
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 65 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
..
28: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
29: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
30: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 __CTOR_LIST__
31: 0000000000600e28 0 OBJECT LOCAL DEFAULT 20 __DTOR_LIST__
32: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
...
49: 0000000000400550 2 FUNC WEAK DEFAULT 14 __libc_csu_fini
50: 0000000000400440 0 FUNC WEAK DEFAULT 14 _start
51: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
52: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
53: 0000000000400628 0 FUNC WEAK DEFAULT 15 _fini
54: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
55: 0000000000400638 4 OBJECT WEAK DEFAULT 16 _IO_stdin_used
56: 0000000000601010 0 NOTYPE WEAK DEFAULT 25 __data_start
..
$
所以我们看到,在运行带有 –weaken 标志的 objcopy 命令后,所有 GLOBAL 符号都被转换为 WEAK。
7. 使用 --prefix-symbols 选项为字符串添加前缀
考虑以下示例,其中需要在符号名称之前添加字符串“TGS”:
$ objcopy --prefix-symbols="TGS" test new_test
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 65 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
...
28: 000000000040046c 0 FUNC LOCAL DEFAULT 14 TGScall_gmon_start
29: 0000000000000000 0 FILE LOCAL DEFAULT ABS TGScrtstuff.c
30: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 TGS__CTOR_LIST__
31: 0000000000600e28 0 OBJECT LOCAL DEFAULT 20 TGS__DTOR_LIST__
32: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 TGS__JCR_LIST__
33: 0000000000400490 0 FUNC LOCAL DEFAULT 14 TGS__do_global_dtors_aux
...
所以我们看到'TGS' 在符号名称之前有前缀。
8. 使用 –strip-symbols 选项去除特定符号
如果需要去除某些符号,则可以将选项 –strip-symbols 与文件名一起使用。此文件名包含要剥离的符号名称(每行一个)。
考虑以下示例,其中将删除“call_gmon_start”符号名称,因为它是在文件(符号名称)中指定的。
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 65 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
.....
28: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
29: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
30: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 __CTOR_LIST__
31: 0000000000600e28 0 OBJECT LOCAL DEFAULT 20 __DTOR_LIST__
32: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
33: 0000000000400490 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
...
$ objcopy --strip-symbols=symbolname test new_test
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 64 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
...
26: 0000000000601020 0 SECTION LOCAL DEFAULT 26
27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
29: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 __CTOR_LIST__
30: 0000000000600e28 0 OBJECT LOCAL DEFAULT 20 __DTOR_LIST__
31: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
32: 0000000000400490 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
...
所以我们看到符号“call_gmon_start”被成功剥离。
9. 使用 –prefix-sections 选项为部分名称添加前缀
考虑以下示例:
$ objcopy --prefix-sections="TGS" test new_test
$ readelf -s new_test
readelf: Error: no .dynamic section in the dynamic segment
Symbol table 'TGS.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
所以我们看到部分名称以我们提供的字符串 TGS 为前缀。
10. 使用 –keep-file-symbols 选项保留源文件名符号
每当使用 –strip-debug 符号(它会剥离许多与调试相关的符号以及指定文件名的符号),如果需要保留源文件名符号,则可以使用 –keep-file-symbols。
考虑以下示例:
$ objcopy --strip-debug test new_test
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 62 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
2: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 __CTOR_LIST__
3: 0000000000600e28 0 OBJECT LOCAL DEFAULT 20 __DTOR_LIST__
4: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
...
10: 00000000004006e8 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
11: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 __JCR_END__
12: 00000000004005f0 0 FUNC LOCAL DEFAULT 14 __do_global_ctors_aux
13: 0000000000600fe8 0 OBJECT LOCAL HIDDEN 24 _GLOBAL_OFFSET_TABLE_
14: 0000000000600e14 0 NOTYPE LOCAL HIDDEN 19 __init_array_end
15: 0000000000600e14 0 NOTYPE LOCAL HIDDEN 19 __init_array_start
...
$ objcopy --strip-debug --keep-file-symbols test new_test
$ readelf -s new_test
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 65 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000040046c 0 FUNC LOCAL DEFAULT 14 call_gmon_start
2: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
3: 0000000000600e18 0 OBJECT LOCAL DEFAULT 19 __CTOR_LIST__
4: 0000000000600e28 0 OBJECT LOCAL DEFAULT 20 __DTOR_LIST__
...
12: 00000000004006e8 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
13: 0000000000600e38 0 OBJECT LOCAL DEFAULT 21 __JCR_END__
14: 00000000004005f0 0 FUNC LOCAL DEFAULT 14 __do_global_ctors_aux
15: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
16: 0000000000600fe8 0 OBJECT LOCAL HIDDEN 24 _GLOBAL_OFFSET_TABLE_
17: 0000000000600e14 0 NOTYPE LOCAL HIDDEN 19 __init_array_end
18: 0000000000600e14 0 NOTYPE LOCAL HIDDEN 19 __init_array_start
在上面的示例中,首先使用 –strip-debug 选项运行 objcopy,该选项(以及许多其他符号)剥离了提及源文件 (test.c) 名称的符号。接下来,我们重新运行 objcopy 命令以及 –keep-file-symbols 选项,并观察到(粗体)源文件名的符号没有被删除。
- 点赞
- 收藏
- 关注作者
评论(0)