声明版权归原作者所有,只用于学习。
我按照阿里的公开学习链接进行梳理的,网站里面很详细。
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-printthestringsofprintablecharactersinfiles.
意思是, 打印文件中可打印的字符。 我来补充一下吧, 这个文件可以是文本文件(test.c),可执行文件(test),动态链接库(test.o),静态链接库(test.a)
代码存在test.c中
我们对可执行文件用strings试试, 如下:
原文链接:https://www.f2er.com/ubuntu/351928.html代码存在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,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,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文件:
@H_301_123@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
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 _initstrings命令很简单, 看起来好像没什么, 但实际有很多用途。 下面, 我来举一个例子。 在大型的软件开发中, 假设有100个.c/.cpp文件, 这个.cpp文件最终生成10个.so库, 那么怎样才能快速知道某个.c/.cpp文件编译到那个.so库中去了呢? 当然, 你可能要说, 看makefile不就知道了。 对, 看makefile肯定可以, 但如下方法更好, 直接用命令:
strings -f "*.so" | grep "xxxxxx"
如果还不明白, 那就就以上面的小程序为例为说明, 不过, 此处我们考虑所有的文件, 如下:
@H_301_123@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