Working in the Linux environment is a lot easier. Running most programs, such as md5sum and sha1sum, does not generally require installing any new software. Depending on what distribution, less common programs such as ssdeep may well be in the distribution's repository.
The old standby for dumping a binary was "od" (octal dump); we now have other programs such "xxd", "ghex", and "hexdump" that might also be in a given distribution.
Of course, one of the handiest is the old "file" program, which does a very credible job of identifying quite a few programs. Also of some use can be "readelf -a" and of course "objdump -x". You can look for namelists with "nm"...
You can examine a program's dynamic linkage information with "ldd"; for that matter, you can strace the program (though if it's a suspect one, you should try this in a sandbox!) Also, you might try "ltrace"; while this is generally not as useful, it might show you interesting library activity.
Even if a program is "stripped", a dynamically linked program still has linkage information available. (If the binary isn't stripped, look to see if there is any debugging info — if so, you might be able to run "gdb" usefully!)
Generally, the easiest thing to do is to install packages like "clamav" and "clamav-update". You can then use "clamscan" to scan individual files, and "freshclam" to get the latest signatures.
Running "strings" over a suspect binary is almost always worth doing. While it's possible that a good programmer or packing/encryption has removed or obfuscated all strings, it's also also possible that it hasn't.
Using "ldd" can show you where things are actually at. You can use "file" (if you like) to learn more about a shared library.
Using "nm" can really show you where things are actually at. You can figure out exactly where in memory a variable can be located. If it shows a lot of information, you can use "gdb" (GNU debugger) to get a real feel for what the program is doing.
You can do an "strace -f PROGRAMNAME" in a sandbox (not a machine that you care about!) to see what's going on; this will show you all of the system calls made by this program and its children. If you find a lot of tasks created (not likely), you can use something like "strace -ff -o FILE PROGRAMNAME" to have all of strace output written to separate files for each task.
We can install "upx" easily in the Unix/Linux world. This is a simple packer/compressor that can actually save space.
Using upx:
[langley@host Slidy]$ cp /usr/bin/emacs .
[langley@host Slidy]$ pwd
/media/disk/CIS-4930r/2010-01/Slidy
[langley@host Slidy]$ file emacs
emacs: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
[langley@host Slidy]$ upx emacs
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2008
UPX 3.03 Markus Oberhumer, Laszlo Molnar & John Reiser Apr 27th 2008
File size Ratio Format Name
-------------------- ------ ----------- -----------
11102144 -> 2780472 25.04% linux/ElfAMD emacs
Packed 1 file.
[langley@host Slidy]$ file emacs
emacs: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped
Like the PE format in Windows, the Linux ELF format (also used by other folks), is related to COFF. You can look at /usr/include/elf.h for the exact layout, and use "readelf" and "objdump" to look at ELF files.
There are a number of options that are useful with "readelf":
With "objdump", try "-p" and "-a".
The program radare provides some powerful cross-platform capabilities for binary analysis.
Here's a simple session with radare2 on a debian box:
$ file OddBinary.exe
OddBinary.exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=8c7de897dd2f5d869d108bed2f2152a68b2f7b0a, stripped
$ radare2 OddBinary.exe
[0x00402830]> f
0x0046076b 0 section_end..shstrtab
0x00460668 259 section..shstrtab
0x00466700 0 section_end..bss
0x00460680 24704 section..bss
0x00460668 0 section_end..data
0x00460380 744 section..data
0x00460368 0 section_end..got.plt
0x0045ffe8 896 section..got.plt
0x0045ffe8 0 section_end..got
0x0045ffe0 8 section..got
0x0045ffe0 0 section_end..dynamic
0x0045fe00 480 section..dynamic
0x0045fe00 0 section_end..jcr
0x0045fdf8 8 section..jcr
0x0045fdf8 0 section_end..dtors
0x0045fde8 16 section..dtors
0x0045fde8 0 section_end..ctors
0x0045fdd8 16 section..ctors
0x0045fdd8 0 section_end..init_array
0x0045fd58 128 section..init_array
0x0045fa0a 0 section_end..gcc_except_table
0x0045c6d4 13110 section..gcc_except_table
0x0045c6d4 0 section_end..eh_frame
0x004514c8 45580 section..eh_frame
0x004514c4 0 section_end..eh_frame_hdr
0x0044ee40 9860 section..eh_frame_hdr
0x0044ee40 0 section_end..rodata
0x00447140 32000 section..rodata
0x00447126 0 section_end..fini
0x00447118 14 section..fini
0x00447118 0 section_end..text
0x00402830 280808 section..text
0x00402830 0 section_end..plt
0x00402150 1760 section..plt
0x00402150 0 section_end..init
0x00402138 24 section..init
0x00402138 0 section_end..rela.plt
0x00401700 2616 section..rela.plt
0x00401700 0 section_end..rela.dyn
0x00401610 240 section..rela.dyn
0x00401610 0 section_end..gnu.version_r
0x00401530 224 section..gnu.version_r
0x00401530 0 section_end..gnu.version
0x0040143e 242 section..gnu.version
0x0040143d 0 section_end..dynstr
0x00400e40 1533 section..dynstr
0x00400e40 0 section_end..dynsym
0x004002e8 2904 section..dynsym
0x004002e8 0 section_end..gnu.hash
0x00400298 80 section..gnu.hash
0x00400298 0 section_end..note.gnu.buildid
0x00400274 36 section..note.gnu.buildid
0x00400274 0 section_end..note.ABItag
0x00400254 32 section..note.ABItag
0x00400254 0 section_end..interp
0x00400238 28 section..interp
[0x00402830]> pd
; [12] va=0x00402830 pa=0x00002830 sz=280808 vsz=280808 rwx=-r-x .text
;-- section..text:
0x00402830 31ed xor ebp, ebp
0x00402832 4989d1 mov r9, rdx
0x00402835 5e pop rsi
0x00402836 4889e2 mov rdx, rsp
0x00402839 4883e4f0 and rsp, 0xfffffffffffffff0
0x0040283d 50 push rax
0x0040283e 54 push rsp
0x0040283f 49c7c0d0704. mov r8, 0x4470d0
0x00402846 48c7c140704. mov rcx, 0x447040
0x0040284d 48c7c7909c4. mov rdi, 0x409c90
0x00402854 e877faffff call sym.imp.__libc_start_main
0x004022d0(unk, unk) ; sym.imp.__libc_start_main
0x00402859 f4 hlt
0x0040285a 90 nop
0x0040285b 90 nop
0x0040285c 4883ec08 sub rsp, 0x8
0x00402860 488b0579d72. mov rax, [rip+0x25d779] ; 0x0040ffe0
0x00402867 4885c0 test rax, rax
,=< 0x0040286a 7402 jz 0x40286e
| 0x0040286c ffd0 call rax
| 0x00000000()
`-> 0x0040286e 4883c408 add rsp, 0x8
0x00402872 c3 ret
0x00402873 90 nop
While you can try a suspect binary inside of an emulation environment such as Wine, it's probably safer to simply put it into a sandbox, such as VirtualBox or qemu. This gives you not only a more realistic environment than Wine, but it's safer. You can easily do differential analysis of different snapshots of the VM's filesystems and (if Windows) the registry to track changes.