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

可紊 提交于 2020-04-06 02:38:07

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

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

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.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文件:
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


















发布了347 篇原创文章 · 获赞 635 · 访问量 266万+
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!