C program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_authentication(char *password)
{
char password_buffer[16];
int auth_flag = 0;
strcpy(password_buffer, password);
if(strcmp(password_buffer, "brillig") == 0)
auth_flag = 1;
if(strcmp(password_buffer, "outgrabe") == 0)
auth_flag = 1;
return auth_flag;
}
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Usage: %s <password>\n", argv[0]);
exit(0);
}
if(check_authentication(argv[1]))
{
printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
printf(" Access Granted.\n");
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
}
else
{
printf("\nAccess Denied.\n");
}
}
lyu@ubuntu:~/Desktop/work$ gcc -g auth.c
lyu@ubuntu:~/Desktop/work$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) set disassembly intel
(gdb) list
3 #include <string.h>
4 int check_authentication(char *password)
5 {
6 char password_buffer[16];
7 int auth_flag = 0;
8 strcpy(password_buffer, password);
9 if(strcmp(password_buffer, "brillig") == 0)
10 auth_flag = 1;
11 if(strcmp(password_buffer, "outgrabe") == 0)
12 auth_flag = 1;
(gdb) list
13 return auth_flag;
14 }
15 int main(int argc, char *argv[])
16 {
17 if(argc < 2)
18 {
19 printf("Usage: %s <password>\n", argv[0]);
20 exit(0);
21 }
22 if(check_authentication(argv[1]))
(gdb) list
23 {
24 printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
25 printf(" Access Granted.\n");
26 printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
27 }
28 else
29 {
30 printf("\nAccess Denied.\n");
31 }
32 }
(gdb) break 22
Breakpoint 1 at 0x80485e7: file auth.c, line 22.
(gdb) break 8
Breakpoint 2 at 0x8048549: file auth.c, line 8.
(gdb) break 13
Breakpoint 3 at 0x8048599: file auth.c, line 13.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /home/lyu/Desktop/work/a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Breakpoint 1, main (argc=2, argv=0xbffff0f4) at auth.c:22
22 if(check_authentication(argv[1]))
(gdb) i r esp
esp 0xbffff040 0xbffff040
(gdb) x/32xw $esp
0xbffff040: 0xb7fbb3dc 0xbffff060 0x00000000 0xb7e21637
0xbffff050: 0xb7fbb000 0xb7fbb000 0x00000000 0xb7e21637
0xbffff060: 0x00000002 0xbffff0f4 0xbffff100 0x00000000
0xbffff070: 0x00000000 0x00000000 0xb7fbb000 0xb7fffc04
0xbffff080: 0xb7fff000 0x00000000 0xb7fbb000 0xb7fbb000
0xbffff090: 0x00000000 0x98922377 0xa3590d67 0x00000000
0xbffff0a0: 0x00000000 0x00000000 0x00000002 0x08048430
0xbffff0b0: 0x00000000 0xb7feff10 0xb7fea780 0xb7fff000
(gdb) c
Continuing.
Breakpoint 2, check_authentication (password=0xbffff2e3 'A' <repeats 30 times>)
at auth.c:8
8 strcpy(password_buffer, password);
(gdb) i r esp
esp 0xbfffeff0 0xbfffeff0
(gdb) print 0xbffff040 - 0xbfffeff0
$1 = 80
(gdb) x/32wx $esp
0xbfffeff0: 0x00000000 0xbffff094 0xb7fbb000 0xbffff2e3
0xbffff000: 0xffffffff 0x0000002f 0x00000000 0xb7fd6858
0xbffff010: 0x00008000 0xb7fbb000 0xb7fb9244 0x1f1e2c00
0xbffff020: 0x00000002 0x00000000 0xbffff048 0x080485f8
0xbffff030: 0xbffff2e3 0xbffff0f4 0xbffff100 0x08048671
0xbffff040: 0xb7fbb3dc 0xbffff060 0x00000000 0xb7e21637
0xbffff050: 0xb7fbb000 0xb7fbb000 0x00000000 0xb7e21637
0xbffff060: 0x00000002 0xbffff0f4 0xbffff100 0x00000000
(gdb) x/s password_buffer
0xbffff00c: "X", <incomplete sequence \375\267>
(gdb) x/x &auth_flag
0xbffff008: 0x00
(gdb) disassemble main
Dump of assembler code for function main:
0x080485af <+0>: lea ecx,[esp+0x4]
0x080485b3 <+4>: and esp,0xfffffff0
0x080485b6 <+7>: push DWORD PTR [ecx-0x4]
0x080485b9 <+10>: push ebp
0x080485ba <+11>: mov ebp,esp
0x080485bc <+13>: push ecx
0x080485bd <+14>: sub esp,0x4
0x080485c0 <+17>: mov eax,ecx
0x080485c2 <+19>: cmp DWORD PTR [eax],0x1
0x080485c5 <+22>: jg 0x80485e7 <main+56>
0x080485c7 <+24>: mov eax,DWORD PTR [eax+0x4]
0x080485ca <+27>: mov eax,DWORD PTR [eax]
0x080485cc <+29>: sub esp,0x8
0x080485cf <+32>: push eax
0x080485d0 <+33>: push 0x80486e1
0x080485d5 <+38>: call 0x80483c0 <printf@plt>
0x080485da <+43>: add esp,0x10
0x080485dd <+46>: sub esp,0xc
0x080485e0 <+49>: push 0x0
0x080485e2 <+51>: call 0x8048400 <exit@plt>
0x080485e7 <+56>: mov eax,DWORD PTR [eax+0x4]
0x080485ea <+59>: add eax,0x4
---Type <return> to continue, or q <return> to quit---
0x080485ed <+62>: mov eax,DWORD PTR [eax]
0x080485ef <+64>: sub esp,0xc
0x080485f2 <+67>: push eax
0x080485f3 <+68>: call 0x804852b <check_authentication>
0x080485f8 <+73>: add esp,0x10
0x080485fb <+76>: test eax,eax
0x080485fd <+78>: je 0x8048631 <main+130>
0x080485ff <+80>: sub esp,0xc
0x08048602 <+83>: push 0x80486f7
0x08048607 <+88>: call 0x80483f0 <puts@plt>
0x0804860c <+93>: add esp,0x10
0x0804860f <+96>: sub esp,0xc
0x08048612 <+99>: push 0x8048714
0x08048617 <+104>: call 0x80483f0 <puts@plt>
0x0804861c <+109>: add esp,0x10
0x0804861f <+112>: sub esp,0xc
0x08048622 <+115>: push 0x8048725
0x08048627 <+120>: call 0x80483f0 <puts@plt>
0x0804862c <+125>: add esp,0x10
0x0804862f <+128>: jmp 0x8048641 <main+146>
0x08048631 <+130>: sub esp,0xc
0x08048634 <+133>: push 0x8048741
0x08048639 <+138>: call 0x80483f0 <puts@plt>
---Type <return> to continue, or q <return> to quit---<return>
0x0804863e <+143>: add esp,0x10
0x08048641 <+146>: mov eax,0x0
0x08048646 <+151>: mov ecx,DWORD PTR [ebp-0x4]
0x08048649 <+154>: leave
0x0804864a <+155>: lea esp,[ecx-0x4]
0x0804864d <+158>: ret
End of assembler dump.
(gdb) disassemble check_authentication
Dump of assembler code for function check_authentication:
0x0804852b <+0>: push ebp
0x0804852c <+1>: mov ebp,esp
0x0804852e <+3>: sub esp,0x38
0x08048531 <+6>: mov eax,DWORD PTR [ebp+0x8]
0x08048534 <+9>: mov DWORD PTR [ebp-0x2c],eax
0x08048537 <+12>: mov eax,gs:0x14
0x0804853d <+18>: mov DWORD PTR [ebp-0xc],eax
0x08048540 <+21>: xor eax,eax
0x08048542 <+23>: mov DWORD PTR [ebp-0x20],0x0
=> 0x08048549 <+30>: sub esp,0x8
0x0804854c <+33>: push DWORD PTR [ebp-0x2c]
0x0804854f <+36>: lea eax,[ebp-0x1c]
0x08048552 <+39>: push eax
0x08048553 <+40>: call 0x80483e0 <strcpy@plt>
0x08048558 <+45>: add esp,0x10
0x0804855b <+48>: sub esp,0x8
0x0804855e <+51>: push 0x80486d0
0x08048563 <+56>: lea eax,[ebp-0x1c]
0x08048566 <+59>: push eax
0x08048567 <+60>: call 0x80483b0 <strcmp@plt>
0x0804856c <+65>: add esp,0x10
0x0804856f <+68>: test eax,eax
---Type <return> to continue, or q <return> to quit---<return>
0x08048571 <+70>: jne 0x804857a <check_authentication+79>
0x08048573 <+72>: mov DWORD PTR [ebp-0x20],0x1
0x0804857a <+79>: sub esp,0x8
0x0804857d <+82>: push 0x80486d8
0x08048582 <+87>: lea eax,[ebp-0x1c]
0x08048585 <+90>: push eax
0x08048586 <+91>: call 0x80483b0 <strcmp@plt>
0x0804858b <+96>: add esp,0x10
0x0804858e <+99>: test eax,eax
0x08048590 <+101>: jne 0x8048599 <check_authentication+110>
0x08048592 <+103>: mov DWORD PTR [ebp-0x20],0x1
0x08048599 <+110>: mov eax,DWORD PTR [ebp-0x20]
0x0804859c <+113>: mov edx,DWORD PTR [ebp-0xc]
0x0804859f <+116>: xor edx,DWORD PTR gs:0x14
0x080485a6 <+123>: je 0x80485ad <check_authentication+130>
0x080485a8 <+125>: call 0x80483d0 <__stack_chk_fail@plt>
0x080485ad <+130>: leave
0x080485ae <+131>: ret
End of assembler dump.
(gdb) x/32wx $esp
0xbfffeff0: 0x00000000 0xbffff094 0xb7fbb000 0xbffff2e3
0xbffff000: 0xffffffff 0x0000002f 0x00000000 0xb7fd6858
0xbffff010: 0x00008000 0xb7fbb000 0xb7fb9244 0x1f1e2c00
0xbffff020: 0x00000002 0x00000000 0xbffff048 0x080485f8
0xbffff030: 0xbffff2e3 0xbffff0f4 0xbffff100 0x08048671
0xbffff040: 0xb7fbb3dc 0xbffff060 0x00000000 0xb7e21637
0xbffff050: 0xb7fbb000 0xb7fbb000 0x00000000 0xb7e21637
0xbffff060: 0x00000002 0xbffff0f4 0xbffff100 0x00000000
(gdb) x/s 0xbffff2e3
0xbffff2e3: 'A' <repeats 30 times>
Take a look at the memory layout for break point at strcpy
function.
0xbfffeff0: 0x00000000 0xbffff094 0xb7fbb000 0xbffff2e3 0xbffff000: 0xffffffff 0x0000002f 0x00000000 0xb7fd6858 0xbffff010: 0x00008000 0xb7fbb000 0xb7fb9244 0x1f1e2c00 0xbffff020: 0x00000002 0x00000000 0xbffff048 0x080485f8 0xbffff030: 0xbffff2e3 0xbffff0f4 0xbffff100 0x08048671 0xbffff040: 0xb7fbb3dc 0xbffff060 0x00000000 0xb7e21637 0xbffff050: 0xb7fbb000 0xb7fbb000 0x00000000 0xb7e21637 0xbffff060: 0x00000002 0xbffff0f4 0xbffff100 0x00000000
0xbffff040
is value of esp
before calling check_authentication
.
0xbfffeff0
is value of esp
after calling check_authentication
.
0xbffff008
is variable auth_flag
.
0xbffff00c
is variable password_buffer
.
the address at position 0xbffff030
is the parameter passed to function check_authentication
.
the address at position 0xbffff02C
is the saved return address to main function’s next instruction, which is at 0x080485f8
.
the address at position 0xbffff028
is the saved frame pointer.