When an application is deployed, mostly only the binary files are packaged. It would be helpful for the developers (who wrote the original program) and for the users to search for a some ASCII text in the binary file to understand more about the executable.
So, the question is — “How do we search and display printable text strings from a binary file?”.
In Linux, the powerful utility “strings”, finds and displays the printable strings in a given executable, binary, or object file.
Example 1. Display printable characters from an object file
Let us create a sample object file of a C code as shown below.
$ cat welcome.c # include <stdio.h> main() { char a[]="strings program"; printf("Welcome to thegeekstuff\n"); system("ls"); printf("%s",a); }
Create an object file for the above code as shown below. If you are new to C programming language, C hello world program would give you a jump-start.
$ cc -o welcome welcome.c
Let us assume that you want to search for the string “welcome” in the above object file. If we do a search using grep command, it will give you whether the binary file matches the given string or not. i.e Grep output on binary files will not show you the exact matched words.
Unlike grep command, strings command will list all the printable characters from binary file.
The following code snippet displays the difference between doing a grep and strings on a binary file.
$ grep "Welcome" welcome Binary file welcome matches $ strings welcome /lib64/ld-linux-x86-64.so.2 __gmon_start__ libc.so.6 puts printf system __libc_start_main GLIBC_2.2.5 l$ L t$(L |$0H Welcome to thegeekstuff strings program $
Using strings command, you will be able to view all the printable strings from the binary file. The above C source code, calls the system command, to execute the Unix ls command. If you want to search for this “ls” string, you’ll not get anything as shown below.
$ strings welcome | grep ls $
By default strings command will be looking for sequences of at least 4 printable characters that are terminated by a NULL character.
To change the total number of characters that needs to be searched in the binary files, use option -n as shown below, which tells strings command to return strings which are at least the number of that integer in length.
The following example searches for ls from the object file.
$ strings -n 2 welcome | grep ls ls
Example 2. Search the entire Binary file for a specific String
By default strings command displays the printable character only from the data segment of the object file. If you want to search the full file, you should use strings -a option as shown below.
# strings -a welcome /lib64/ld-linux-x86-64.so.2 __gmon_start__ libc.so.6 puts printf system __libc_start_main GLIBC_2.2.5 l$ L t$(L |$0H Welcome to thegeekstuff strings program . . . __libc_csu_init __bss_start _end _edata main _init
Strings command reads the value of the environment variable TK_STRINGS_DEFAULT_SECTIONS, which indicates which sections has to be searched for printable characters. If TK_STRINGS_DEFAULT_SECTIONS variable is empty, it uses only data segment by default.
The following values can be given for the TK_STRINGS_DEFAULT_SECTIONS variable.
- TEXT read only code and static strings
- DATA initialized data
- BSS uninitialized data
- SYM symbol table
- RELT read only code and static strings
- RELD initialized data
- STACK function call stack
Example 3. Find out application details from a binary file by searching it’s content
Strings command is frequently used for looking through the executables to uncover copyright notices, error messages, undocumented features and so on.
For example, you can search for the copyright information in a Linux executable as shown below.
$ strings /bin/ls | grep Copyright Copyright %s %d Free Software Foundation, Inc.
Example 4. Print Text Strings from Executable Files with Offset
When you get the printable characters with offset, it will be useful to identify which portion/location of the file has these strings. -o option with strings command displays each string with its octal offset within the file as shown below.
$ strings -o welcome 1000 /lib64/ld-linux-x86-64.so.2 1361 __gmon_start__ 1400 libc.so.6 1412 puts 1417 printf 1426 system 1435 __libc_start_main 1457 GLIBC_2.2.5 3011 l$ L 3016 t$(L 3023 |$0H 3170 Welcome to thegeekstuff 3226 strings program
Example 5. Use Strings Command on Multiple Binary Files
Strings command accepts multiple files and displays the printable strings for all the given files. If you use grep command on the strings output of multiple files, the output will be meaningful where you’ll get a file name and matched strings as shown below.
The strings command output shown below has file name in each match. String command -f option displays each printable string preceded by the name of the file in which it was found.
$ strings -f /bin/* | grep Copy /bin/rpm: Copyright (C) 1998-2002 - Red Hat, Inc. /bin/sed: Copyright (C) 2003 Free Software Foundation, Inc. /bin/sh: Copyright (C) 2005 Free Software Foundation, Inc. /bin/dbus-cleanup-sockets: Copyright (C) 2003 Red Hat, Inc. /bin/dbus-cleanup-sockets: Copyright (C) 2002 Michael Meeks /bin/dbus-daemon: Copyright (C) 2002, 2003 Red Hat, Inc., CodeFactory AB, and others
Comments on this entry are closed.
I use it to find if a word exist in a mysql table. For e.g.
strings /var/lib/mysql/test/mynames.MYD | grep ‘shantanu’
Looking for a word ‘shantanu’ in a file that is located…
/path to MySQL data directory/DB name/Table Name.MYD
If you are using MyISAM table type, the data is always being stored in a .MYD file.
> strings -f /bin/* | grep Copy
That fails if the search string is included in one of the filenames (e.g., a file /bin/Copying).
Instead, try:
strings -f /bin/* | grep ‘:.*Copy’
There may still be some edge cases that need to be dealt with.
Really this is very useful article for me. Thanks lot
Those offsets in example #4 are decimal, not octal.