梳理Ubuntu命令(文件查找和比较)---strings

来源:互联网 发布:国际网络加速器 编辑:程序博客网 时间:2024/06/13 16:16

声明版权归原作者所有,只用于学习。

我按照阿里的公开学习链接进行梳理的,网站里面很详细。

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中
#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.cmi@pc:~/linux命令学习/strings$ strings a.out /lib64/ld-linux-x86-64.so.2libc.so.6printf__libc_start_main__gmon_start__GLIBC_2.2.5UH-@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.commentcrtstuff.c__JCR_LIST__deregister_tm_clonesregister_tm_clones__do_global_dtors_auxcompleted.6973__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrytest.c__FRAME_END____JCR_END____init_array_end_DYNAMIC__init_array_start_GLOBAL_OFFSET_TABLE___libc_csu_fini_ITM_deregisterTMCloneTabledata_start_edata_finiprintf@@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_startmain_Jv_RegisterClasses__TMC_END___ITM_registerTMCloneTable_init
如果有目标文件、静态库或动态库, , 也是可以用strings命令进行打印操作的。 我们来看看:
test_1.h文件:
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.cmi@pc:~/linux命令学习/strings$ ar rcs libtest_1.a test_1.omi@pc:~/linux命令学习/strings$ gcc -fPIC -shared -o libtest_1.so test_1.cmi@pc:~/linux命令学习/strings$ lsa.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.orainy daysGCC: (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_frametest_1.cprintputsmi@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        `Rprinttest_1.o/       1501406735  1000  1000  100664  1488      `rainy daysGCC: (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_frametest_1.cprintputsmi@pc:~/linux命令学习/strings$ strings libtest_1.so__gmon_start___init_fini_ITM_deregisterTMCloneTable_ITM_registerTMCloneTable__cxa_finalize_Jv_RegisterClassesprintputslibc.so.6_edata__bss_start_endGLIBC_2.2.5fffff.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.commentcrtstuff.c__JCR_LIST__deregister_tm_clonesregister_tm_clones__do_global_dtors_auxcompleted.6973__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrytest_1.c__FRAME_END____JCR_END____dso_handle_DYNAMIC__TMC_END___GLOBAL_OFFSET_TABLE__ITM_deregisterTMCloneTableputs@@GLIBC_2.2.5_edata_finiprint__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 dayslibtest_1.so: rainy daystest_1.c: printf("rainy days\n");test_1.cpp~: printf("rainy days\n");test_1.o: rainy daystest_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