Solutions for protostar challenges
When I first started protostar I couldn't do shit. Well, not until I figured out the basics.
This debugger "allows you to see what is going on 'inside' another program while it executes" GNU Project. To execute it over a program (in this case stack0), run:
$ gdb stack0
The first thing we will probably wanna do is to get the assembly code of the program. To do so, you will need to pick a side AT&T or Intel (I'm team Intel) and set up the disassembly syntax:
(gdb) set disassembly-flavor intel
Proceed to disassemble the main function with:
(gdb) disassembly main
And we will see something like this:
Dump of assembler code for function main:
0x080483f4 <main+0>: push ebp
0x080483f5 <main+1>: mov ebp,esp
0x080483f7 <main+3>: and esp,0xfffffff0
0x080483fa <main+6>: sub esp,0x60
0x080483fd <main+9>: mov DWORD PTR [esp+0x5c],0x0
0x08048405 <main+17>: lea eax,[esp+0x1c]
0x08048409 <main+21>: mov DWORD PTR [esp],eax
0x0804840c <main+24>: call 0x804830c <gets@plt>
0x08048411 <main+29>: mov eax,DWORD PTR [esp+0x5c]
0x08048415 <main+33>: test eax,eax
0x08048417 <main+35>: je 0x8048427 <main+51>
0x08048419 <main+37>: mov DWORD PTR [esp],0x8048500
0x08048420 <main+44>: call 0x804832c <puts@plt>
0x08048425 <main+49>: jmp 0x8048433 <main+63>
0x08048427 <main+51>: mov DWORD PTR [esp],0x8048529
0x0804842e <main+58>: call 0x804832c <puts@plt>
0x08048433 <main+63>: leave
0x08048434 <main+64>: ret
This code here (that goes from 0x080483f4
to 0x08048434
) belogns to the .text
segment as long as other compiled functions. Basically there are 5 different segments: .text
, .data
, .bss
, heap
, stack
.
You can examine any hex address or register by using this synxtax:
(gdb) x/32 $esp
This means examine(x/
) and print 32 bytes (32
) from the register $esp
It could also show addresses, for example:
(gdb) x/32 0x80483f4
There are also a concept called breakpoint. A breakpoint is a stop in a certain point of the program when it's running. For example we are going to stop at the first instruction, so out breakpoint would be:
(gdb) b * 0x080483f4
And then, in order to run the program just:
(gdb) r
You will notice right away that the program stops with a message like this:
Starting program: /opt/protostar/bin/stack0
Breakpoint 1, main (argc=1, argv=0xbffff814) at stack0/stack0.c:6
6 stack0/stack0.c: No such file or directory.
in stack0/stack0.c
This means the program stopped at the breakpoint and now you can examine all registers and addresses at that point of the program.
"A processor register is a quickly accessible location available to a computer's central processing unit (CPU). Registers usually consist of a small amount of fast storage, although some registers have specific hardware functions, and may be read-only or write-only. Registers are typically addressed by mechanisms other than main memory, but may in some cases be assigned a memory address" Definition. Those are:
-
General registers:
EAX
,EBX
,ECX
,EDX
-
Segment registers:
CS
,DS
,ES
,FS
,GS
,SS
-
Index and pointers:
ESI
,EDI
,EBP
,EIP
,ESP
-
Indicator:
EFLAGS
You may see that some of the registers starts with E
, this indicates that you are using x86. In x64 the registers starts with R
and are the same as the x86 ones but larger in size.
I must say that registers are used slighly different in x86 and x64. You will learn the patterns with practice. For now, we will see 4 important registers which purpose do not vary from x86 to x64.
-
EIP
: This is called instruction pointer and it's value is provided and managed by the OS. It points to the instruction that it's about to execute, so the dynamic would be: moveeip
to the next instruction and then execute it. For example if we run the program aboveeip
would first take the value0x080483f4
; after it get executed theneip
would move to the next instruction that would be0x080483f5
. (Some instructions take more than just0x1
) -
ESP
: This is called stack pointer and it's initial value is provided by the OS only when the program starts. In other words, when you run your program the OS assigns an initial address to ESP, then the function prologue gets execute. This register points always to the top of the stack and grows by subtracting its value, for example: imagine that the OS assigns0xbffff77c
as first value ofESP
, if you want to separate a space for variables (for example0x10
), then you would have to substract0x10
from0xbffff77c
which would be0xbffff76c
. -
EBP
: This is called base pointer (also called frame pointer) and it's initial value is the previous frame. It always points
. In other words, when you run your program the OS assigns an initial address to ESP, then the function prologue gets execute.
- Is an abstract data type which has 2 operations
push
andpop
. - Used for memory management. Operating System provides one for each process running (by setting up a
ESP
and executing the function prologue.