Casi no hay amigos que se dediquen al desarrollo de software en Linux que no conozcan el comando strings. Primero echemos un vistazo a las cadenas de hombre:
cadenas: imprime las cadenas de caracteres imprimibles en archivos.
Es decir, caracteres imprimibles en el archivo de impresión. Permítanme agregar, este archivo puede ser un archivo de texto (prueba.c), archivo ejecutable (prueba), biblioteca de vínculos dinámicos (prueba.o), biblioteca de vínculos estáticos (prueba.a)
No es mi estilo escribir una larga historia a partir del código sin verificarlo. Hagamos un código para ordenar los platos (el código se almacena en test.c):
- #include <stdio.h>
- int agregar ( int x, int y)
- {
- return x + y;
- }
- int main ()
- {
- int a = 1;
- int b = 2;
- int c = agregar (a, b);
- printf ( "oh, querida, c es% d \ n" , c);
- return 0;
- }
#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;
}
Echemos un vistazo a los resultados de strings test.c:
- [taoge @ localhost learn_c] $ strings test.c
- #include <stdio.h>
- int agregar (int x, int y)
- return x + y;
- int main ()
- int a = 1;
- int b = 2;
- int c = agregar (a, b);
- printf ("oh, querida, c es% d \ n", c);
- return 0;
- [taoge @ localhost learn_c] $
[taoge@localhost learn_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;
[taoge@localhost learn_c]$
Como puede ver, muchos caracteres en test.c están realmente impresos.
A continuación, intentemos usar cadenas para archivos ejecutables, de la siguiente manera:
- [taoge @ localhost learn_c] $ gcc test.c
- [taoge @ localhost learn_c] $ strings a.out
- /lib/ld-linux.so.2
- = $ TsU
- __gmon_start__
- libc.so.6
- _IO_stdin_used
- printf
- __libc_start_main
- GLIBC_2.0
- PTRh
- [^ _]
- oh, querida, c es% d
- [taoge @ localhost learn_c] $
[taoge@localhost learn_c]$ gcc test.c
[taoge@localhost learn_c]$ strings a.out
/lib/ld-linux.so.2
=$TsU
__gmon_start__
libc.so.6
_IO_stdin_used
printf
__libc_start_main
GLIBC_2.0
PTRh
[^_]
oh, my dear, c is %d
[taoge@localhost learn_c]$
Como puede ver, se imprimen muchos caracteres en a.out.
De hecho, si hay archivos de objetos, bibliotecas estáticas o bibliotecas dinámicas, también puede usar el comando strings para imprimir. Vamos a ver:
Archivo xxx.h:
- impresión vacía ();
void print();
Archivo xxx.c:
- #include <stdio.h>
- #include "xxx.h"
- impresión vacía ()
- {
- printf ( "días lluviosos \ n" );
- }
#include <stdio.h>
#include "xxx.h"
void print()
{
printf("rainy days\n");
}
Luego, echemos un vistazo a cómo crear bibliotecas estáticas y dinámicas (continuaremos presentándolas en detalle en publicaciones de blog posteriores):
- [taoge @ localhost learn_strings] $ ls
- xxx.c xxx.h
- [taoge @ localhost learn_strings] $ gcc -c xxx.c
- [taoge @ localhost learn_strings] $ ar rcs libxxx.a xxx.o
- [taoge @ localhost learn_strings] $ gcc -shared -fPIC -o libxxx.so xxx.o
- [taoge @ localhost learn_strings] $ ls
- libxxx.a libxxx.so xxx.c xxx.h xxx.o
- [taoge @ localhost learn_strings] $ cadenas xxx.o
- días lluviosos
- [taoge @ localhost learn_strings] $ strings libxxx.a
- ! <arch>
- / 1437887339 0 0 0 14 '
- Rprint
- xxx.o / 1437887333 501 502 100664 848 '
- días lluviosos
- CCG: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)
- .symtab
- .strtab
- .shstrtab
- .rel.text
- .datos
- .bss
- .rodata
- .comentario
- .note.GNU-stack
- xxx.c
- imprimir
- pone
- [taoge @ localhost learn_strings] $
- [taoge @ localhost learn_strings] $
- [taoge @ localhost learn_strings] $ strings libxxx.so
- __gmon_start__
- _en eso
- _fini
- __cxa_finalize
- _Jv_RegisterClasses
- imprimir
- pone
- libc.so.6
- _edata
- __bss_start
- _final
- GLIBC_2.1.3
- GLIBC_2.0
- días lluviosos
- [taoge @ localhost learn_strings] $
[taoge@localhost learn_strings]$ ls
xxx.c xxx.h
[taoge@localhost learn_strings]$ gcc -c xxx.c
[taoge@localhost learn_strings]$ ar rcs libxxx.a xxx.o
[taoge@localhost learn_strings]$ gcc -shared -fPIC -o libxxx.so xxx.o
[taoge@localhost learn_strings]$ ls
libxxx.a libxxx.so xxx.c xxx.h xxx.o
[taoge@localhost learn_strings]$ strings xxx.o
rainy days
[taoge@localhost learn_strings]$ strings libxxx.a
!<arch>
/ 1437887339 0 0 0 14 `
Rprint
xxx.o/ 1437887333 501 502 100664 848 `
rainy days
GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)
.symtab
.strtab
.shstrtab
.rel.text
.data
.bss
.rodata
.comment
.note.GNU-stack
xxx.c
print
puts
[taoge@localhost learn_strings]$
[taoge@localhost learn_strings]$
[taoge@localhost learn_strings]$ strings libxxx.so
__gmon_start__
_init
_fini
__cxa_finalize
_Jv_RegisterClasses
print
puts
libc.so.6
_edata
__bss_start
_end
GLIBC_2.1.3
GLIBC_2.0
rainy days
[taoge@localhost learn_strings]$
Míralo.
El comando strings es muy simple y no parece nada, pero en realidad tiene muchos usos. A continuación, déjeme dar un ejemplo. En el desarrollo de software a gran escala, asumiendo que hay 100 archivos .c / .cpp, este archivo .cpp eventualmente generará 10 bibliotecas .so, entonces, ¿cómo podemos saber rápidamente que un determinado archivo .c / .cpp está compilado en el que. así que la biblioteca se ha ido? Por supuesto, puede que tenga que decir que no sabe si mira el archivo MAKE. Sí, definitivamente puedes mirar el archivo MAKE, pero el siguiente método es mejor, solo usa el comando:
cadenas -f "* .so" | grep "xxxxxx"
Si aún no lo entiende, simplemente tome el subprograma anterior como ejemplo. Sin embargo, aquí consideramos todos los archivos, de la siguiente manera:
- [taoge @ localhost learn_c] $ cadenas -f * | grep "querida"
- a.out: oh, querida, c es% d
- test.c: printf ("oh, querida, c es% d \ n", c);
- [taoge @ localhost learn_c] $
[taoge@localhost learn_c]$ strings -f * | grep "my dear"
a.out: oh, my dear, c is %d
test.c: printf("oh, my dear, c is %d\n", c);
[taoge@localhost learn_c]$
Como puede ver, hay cadenas "querida" tanto en el archivo fuente test.cy en el archivo ejecutable, y el archivo correspondiente se encontró de una vez, está claro. Si se compila un archivo .c / .cpp en la biblioteca .so, las cadenas -f * | grep "my dear" deben poder encontrar el archivo .so correspondiente, donde "my dear" está en el .c /. archivo cpp Una cadena de registro (por ejemplo, printf se usa para imprimir).
La función de las cadenas se presentará primero, así que familiaricémonos con las cadenas.