声明版权归原作者所有,只用于学习。
我按照阿里的公开学习链接进行梳理的,网站里面很详细。
http://man.linuxde.net/
strings 命令在对象文件或二进制文件中查找可打印的字符串。字符串是 4 个或更多可打印字符的任意序列,以换行符或空字符结束。 strings 命令对识别随机对象文件很有用。
使用权限:
所有使用者
语法格式:
strings [ -a ] [ - ] [ -o ] [ -t Format ] [ -n Number ] [ -Number ] [ File ... ]
使用说明:
在对象文件或二进制文件中查找可打印的字符串。
主要参数:
-a – –all:扫描整个文件而不是只扫描目标文件初始化和装载段
-f –print-file-name:在显示字符串前先显示文件名
-n –bytes=[number]:找到并且输出所有NUL终止符序列
- :设置显示的最少的字符数,默认是4个字符
-t –radix={o,d,x} :输出字符的位置,基于八进制,十进制或者十六进制
-o :类似–radix=o
-T –target= :指定二进制文件格式
-e –encoding={s,S,b,l,B,L} :选择字符大小和排列顺序:s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit
@ :读取中选项
使用实例:
列出ls中所有的ASCII文本: strings /bin/ls
列出ls中所有的ASCII文本: cat /bin/ls strings
查找ls中包含libc的字符串,不区分大小写: strings /bin/ls | grep -i libc
strings - print the strings of printable characters in files.
意思是, 打印文件中可打印的字符。 我来补充一下吧, 这个文件可以是文本文件(test.c), 可执行文件(test), 动态链接库(test.o), 静态链接库(test.a)
代码存在test.c中
我们对可执行文件用strings试试, 如下:
代码存在test.c中
#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int main()
{
int a = 1;
int b = 2;
int c = add(a, b);
printf("oh, my dear, c is %d\n", c);
return 0;
}
strings test.c的结果:
#include <stdio.h>
int add(int x, int y)
return x + y;
int main()
int a = 1;
int b = 2;
int c = add(a, b);
printf("oh, my dear, c is %d\n", c);
return 0;
我们对可执行文件用strings试试, 如下:
mi@pc:~/linux命令学习/strings$ gcc test.c
mi@pc:~/linux命令学习/strings$ strings a.out
/lib64/ld-linux-x86-64.so.2
libc.so.6
printf
__libc_start_main
__gmon_start__
GLIBC_2.2.5
UH-@
UH-@
[]A\A]A^A_
oh, my dear, c is %d
;*3$"
GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
.symtab
.strtab
.shstrtab
.interp
.note.ABI-tag
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.jcr
.dynamic
.got
.got.plt
.data
.bss
.comment
crtstuff.c
__JCR_LIST__
deregister_tm_clones
register_tm_clones
__do_global_dtors_aux
completed.6973
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
test.c
__FRAME_END__
__JCR_END__
__init_array_end
_DYNAMIC
__init_array_start
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
data_start
_edata
_fini
printf@@GLIBC_2.2.5
__libc_start_main@@GLIBC_2.2.5
__data_start
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
_end
_start
__bss_start
main
_Jv_RegisterClasses
__TMC_END__
_ITM_registerTMCloneTable
_init
如果有目标文件、静态库或动态库, , 也是可以用strings命令进行打印操作的。 我们来看看:
test_1.h文件:
原链接中有一个错误,自己实践的时候就知道了。
参考:
http://blog.csdn.net/stpeace/article/details/46641069
http://man.linuxde.net/strings
void print();
test_1.cpp:
#include <stdio.h>
#include "test_1.h"
void print()
{
printf("rainy days\n");
}
顺便学习一下制作静态动态链接库。
mi@pc:~/linux命令学习/strings$ gcc -c test_1.c
mi@pc:~/linux命令学习/strings$ ar rcs libtest_1.a test_1.o
mi@pc:~/linux命令学习/strings$ gcc -fPIC -shared -o libtest_1.so test_1.c
mi@pc:~/linux命令学习/strings$ ls
a.out libtest_1.so test_1.cpp~ test_1.o test.c test.h~
libtest_1.a test_1.c test_1.h test_1.so test.c~
mi@pc:~/linux命令学习/strings$ strings test_1.o
rainy days
GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
.symtab
.strtab
.shstrtab
.rela.text
.data
.bss
.rodata
.comment
.note.GNU-stack
.rela.eh_frame
test_1.c
print
puts
mi@pc:~/linux命令学习/strings$ strings libtest_1.
libtest_1.a libtest_1.so
mi@pc:~/linux命令学习/strings$ strings libtest_1.a
!<arch>
/ 1501406739 0 0 0 14 `
Rprint
test_1.o/ 1501406735 1000 1000 100664 1488 `
rainy days
GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
.symtab
.strtab
.shstrtab
.rela.text
.data
.bss
.rodata
.comment
.note.GNU-stack
.rela.eh_frame
test_1.c
print
puts
mi@pc:~/linux命令学习/strings$ strings libtest_1.so
__gmon_start__
_init
_fini
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
__cxa_finalize
_Jv_RegisterClasses
print
puts
libc.so.6
_edata
__bss_start
_end
GLIBC_2.2.5
fffff.
rainy days
;*3$"
GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
.symtab
.strtab
.shstrtab
.note.gnu.build-id
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.jcr
.dynamic
.got
.got.plt
.data
.bss
.comment
crtstuff.c
__JCR_LIST__
deregister_tm_clones
register_tm_clones
__do_global_dtors_aux
completed.6973
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
test_1.c
__FRAME_END__
__JCR_END__
__dso_handle
_DYNAMIC
__TMC_END__
_GLOBAL_OFFSET_TABLE_
_ITM_deregisterTMCloneTable
puts@@GLIBC_2.2.5
_edata
_fini
print
__gmon_start__
_end
__bss_start
_Jv_RegisterClasses
_ITM_registerTMCloneTable
__cxa_finalize@@GLIBC_2.2.5
_init
strings命令很简单, 看起来好像没什么, 但实际有很多用途。 下面, 我来举一个例子。 在大型的软件开发中, 假设有100个.c/.cpp文件, 这个.cpp文件最终生成10个.so库, 那么怎样才能快速知道某个.c/.cpp文件编译到那个.so库中去了呢? 当然, 你可能要说, 看makefile不就知道了。 对, 看makefile肯定可以, 但如下方法更好, 直接用命令:
strings -f "*.so" | grep "xxxxxx"
如果还不明白, 那就就以上面的小程序为例为说明, 不过, 此处我们考虑所有的文件, 如下:
mi@pc:~/linux命令学习/strings$ strings -f * | grep "rainy days"
libtest_1.a: rainy days
libtest_1.so: rainy days
test_1.c: printf("rainy days\n");
test_1.cpp~: printf("rainy days\n");
test_1.o: rainy days
test_1.so: rainy days
可以看到, 源文件test_1.c和可执行文件中皆有"rainy days"串, 一下子就找到了对应的文件,清楚了吧。如果某.c/.cpp文件编译进了.so库, 那么,strings -f * | grep "rainy days"必定可以找到对应的.so文件, 其中"rainy days"为该.c/.cpp文件中的某个日志串(比如以printf为打印)。
原链接中有一个错误,自己实践的时候就知道了。
参考:
http://blog.csdn.net/stpeace/article/details/46641069
http://man.linuxde.net/strings
来源:oschina
链接:https://my.oschina.net/u/4330613/blog/3216316