Project 22 Display Binary Files
“Can I view archived log files without uncompressing them first?”
This project focuses on compressed and binary files. It explains an easy way to view compressed text files, and shows you how to search binary files for text fragments. It covers the commands gzcat, zless, zmore, bzcat, bzless, bzmore, strings, hexdump, and xxd.
View Compressed Files
On occasions, you’ll find it necessary to view the contents of a compressed file, such as an archived log file. The log files in /var/log are rotated by Mac OS X periodic maintenance, which means that the current files are compressed and renamed, and new ones are created. To view a compressed file, you could uncompress it and then view and delete the uncompressed file. A better way uses zless to view compressed-file content directly. The zless command is equivalent to less; there are also equivalents to cat and more, gzcat and zmore.
Let’s view an old system log file. Type
$ zless /var/log/system.log.0.gz
Press the spacebar to view the next page and q to quit less. If you cannot find the example file, run daily maintenance, giving your administrator password when requested. This should rotate system.log and create system.log.0.gz. Type
$ sudo periodic daily Password:
Unfortunately, zless isn’t included in versions of Mac OS X older than 10.4, but you can simulate it by piping gzcat output to less.
$ gzcat /var/log/system.log.0.gz | less
The zless command works on files that have been compressed with command zip or gzip (GNU-Zip). You’ll recognize such files by their extensions: .z for zipped files and .gz for g-zipped files.
A newer and better compression format is implemented by bzip2. A file compressed by bzip2 is given the extension .bz2 and must be displayed by a viewer that understands that particular compression format. Choose bzcat, bzmore, or bzless.
View Binary Files
Project 21 showed you how to view text files that contain some control characters by using the cat -v and vis commands. Other commands are better for working with binary files, such as those containing images and executable programs. Binary files contain large numbers of nonprintable characters.
Search for Strings
Search a binary file for sequences of printable characters by using the strings command. It can be used to extract version numbers, help text, error messages, and such like from executable files.
Let’s search the executable file /usr/bin/du. We’ll consider only strings of 16 or more printable characters (the default is four) by specifying option -16.
$ strings -16 /usr/bin/du __dyld_mod_term_funcs __dyld_make_delayed_module_initializer_calls The kernel support for the dynamic linker is not presen... @(#) Copyright (c) 1989, 1993, 1994 The Regents of the University of California. All right... $FreeBSD: src/usr.bin/du/du.c,v 1.28 2002/12/30 18:13:0... invalid argument to option d: %s can't allocate memory usage: du [-H | -L | -P] [-a | -s | -d depth] [-c] [-h ... cannot allocate memory @(#)PROGRAM:du PROJECT:file_cmds-82 DEVELOPER:root B...
View with hexdump and xxd
You’ll probably never have to do this, but should you want to examine an executable file or explore how a file format such as JPEG is encoded, use the hexdump command. It displays a binary file by showing the hexadecimal value of each byte, rather than trying to display the equivalent (and probably nonprintable) ASCII character.
Let’s view the executable file /bin/ls, specifying option -n32 to display the first 32 bytes of the file.
$ hexdump -n32 /bin/ls 0000000 feed face 0000 0012 0000 0000 0000 0002 0000010 0000 000f 0000 0778 0000 0095 0000 0001
Notice that the first four bytes of a Mac OS X executable file spell “feed face” in hexadecimal.
File shows the type of file and is able to recognize different binary formats.
$ file /bin/ls /bin/ls: Mach-O executable ppc
To display the ASCII character equivalents too (where dot represents a nonprintable character), select option -C. (The output below has been squashed horizontally to fit on the page.)
$ hexdump -n64 -C /bin/ls 00000000 feed face 0000 0012 0000 0000 0000 0002 |................| 00000010 0000 000f 0000 0778 0000 0095 0000 0001 |.......x........| 00000020 0000 0038 5f5f 5041 4745 5a45 524f 0000 |...8__PAGEZERO..| 00000030 0000 0000 0000 0000 0000 1000 0000 0000 |................|
Similar to hexdump is the xxd command. In the next example, option -l64 says to display the first 64 bytes of the file.
$ xxd -l64 /bin/ls 0000000: feed face 0000 0012 0000 0000 0000 0002 ................ 0000010: 0000 000f 0000 0778 0000 0095 0000 0001 .......x........ 0000020: 0000 0038 5f5f 5041 4745 5a45 524f 0000 ...8__PAGEZERO.. 0000030: 0000 0000 0000 0000 0000 1000 0000 0000 ................
The xxd command will display a file in binary instead of hexadecimal if option -b is specified.
$ xxd -b -l24 /bin/ls 0000000: 11111110 11101101 11111010 11001110 00000000 00000000 ...... 0000006: 00000000 00010010 00000000 00000000 00000000 00000000 ...... 000000c: 00000000 00000000 00000000 00000010 00000000 00000000 ...... 0000012: 00000000 00001111 00000000 00000000 00000111 01111000 .....x
Like commands vis and unvis, xxd can restore its own output into a binary file—handy if you need to process or transmit a file in which control characters may cause problems. As an example, we’ll process and then restore the ls command into the file new-ls.
$ xxd /bin/ls > xxd-ls $ xxd -r xxd-ls > new-ls
To prove it has worked, we’ll try to run our copy of the ls command.
$ chmod +x new-ls $ ./new-ls Documents Library Public new-ls ...