Debugging compiled binaries in Linux

GNU development tools provide a program called objdump.

Example: Binary of a hello world program as in post Compiling C program in Linux to output 20 lines after the regular express main.:

root@kali:~/Desktop/c-programming/demo# objdump -D helloworld | grep -A20 main.:
0000051d <main>:
 51d: 8d 4c 24 04 lea 0x4(%esp),%ecx
 521: 83 e4 f0 and $0xfffffff0,%esp
 524: ff 71 fc pushl -0x4(%ecx)
 527: 55 push %ebp
 528: 89 e5 mov %esp,%ebp
 52a: 53 push %ebx
 52b: 51 push %ecx
 52c: 83 ec 10 sub $0x10,%esp
 52f: e8 ec fe ff ff call 420 <__x86.get_pc_thunk.bx>
 534: 81 c3 cc 1a 00 00 add $0x1acc,%ebx
 53a: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
 541: eb 16 jmp 559 <main+0x3c>
 543: 83 ec 0c sub $0xc,%esp
 546: 8d 83 f0 e5 ff ff lea -0x1a10(%ebx),%eax
 54c: 50 push %eax
 54d: e8 5e fe ff ff call 3b0 <puts@plt>
 552: 83 c4 10 add $0x10,%esp
 555: 83 45 f4 01 addl $0x1,-0xc(%ebp)
 559: 83 7d f4 09 cmpl $0x9,-0xc(%ebp)
 55d: 7e e4 jle 543 <main+0x26>

Reference to understand number system:

Number Systems: An Introduction to Binary, Hexadecimal, and More

The hexadecimal number starting with 0x0000051d on the far left are memory addresses. Location in memory that these address point to contain bits of machine language instructions.

Hexadecimal instructions in the middle of listing in above screen shot are the machine language instructions. These hexadecimal values are representations of the bytes of binary 1s and 0s the CPU can understand. But language instructions such as 0101010011 are useful for CPU only and not for naked eye. So, machine code is displayed in hexadecimal bytes and each instruction is put on its own line.

Still, these hexadecimal instructions are not really helpful to understand the instructions unless we know what they mean. The instructions on the far right are assembly language representation of the hexadecimal commands.

The assembly shown in above screen shot is in AT&T syntax. It is easy to recognize AT&T syntax by the cacophony of % and $ symbols prefixing everything.

The same code can be shown in Intel syntax (which is cleaner compared with AT&T syntax) using option -M intel as below:

root@kali:~/Desktop/c-programming/demo# objdump -M intel -D helloworld | grep -A20 main.:
0000051d <main>:
 51d: 8d 4c 24 04 lea ecx,[esp+0x4]
 521: 83 e4 f0 and esp,0xfffffff0
 524: ff 71 fc push DWORD PTR [ecx-0x4]
 527: 55 push ebp
 528: 89 e5 mov ebp,esp
 52a: 53 push ebx
 52b: 51 push ecx
 52c: 83 ec 10 sub esp,0x10
 52f: e8 ec fe ff ff call 420 <__x86.get_pc_thunk.bx>
 534: 81 c3 cc 1a 00 00 add ebx,0x1acc
 53a: c7 45 f4 00 00 00 00 mov DWORD PTR [ebp-0xc],0x0
 541: eb 16 jmp 559 <main+0x3c>
 543: 83 ec 0c sub esp,0xc
 546: 8d 83 f0 e5 ff ff lea eax,[ebx-0x1a10]
 54c: 50 push eax
 54d: e8 5e fe ff ff call 3b0 <puts@plt>
 552: 83 c4 10 add esp,0x10
 555: 83 45 f4 01 add DWORD PTR [ebp-0xc],0x1
 559: 83 7d f4 09 cmp DWORD PTR [ebp-0xc],0x9
 55d: 7e e4 jle 543 <main+0x26>