Introduction
This post will be a scratch book to support my learning of the roots of computers: machine code, assembler, exploits, etc.
It will be quite messy as it's going to be based on mistakes I commit and things I find interesting to have in mind but maybe you can find anything that suits for you.
Things to note
SIZES
IA32 architechture:
Element | Size | Sample | Description |
Address | 4 bytes | 0xffffe000 | Memory address that in this case corresponds to the linux-gate.so static shared module |
Opcode | 1-2 bytes | FFE4 | In this case it corresponds to JMP *%ESP instruction used to circumvent random address stack |
RET | 4 bytes | 0xddccbbaa | As RET is the address of the returning function it is an address as well so it takes 4 bytes |
EBP | 4 bytes | 0xddccbbaa | Stack frame pointer, as again its an address it occupies 4 bytes |
AH | 1 byte | N/A | Register's high part of memory |
AL | 1 byte | N/A | Register's low part of memory |
AX | 2 bytes | N/A | 16 bit space formed by AH+AL |
EAX | 4 bytes | N/A | Extended AX register able to hold an address |
GCC
- Compile so that you can see the source code when debugging (gdb is most effective when it is debugging a program that has debugging symbols linked in to it. With g++, this is accomplished using the -g command line argument. For even more information, the -ggdb switch can be used which includes debugging symbols which are specific to gdb. The makefile for this tutorial uses the -ggdb switch. )
gcc -ggdb -o tesoro tesoro.c
GDB
- List code (if possible)
l
- Examine
x/FMT ADDRESS x/x <address> #examine address position and display hex content x/c <address> #examines address position and display the byte stored in that position translated to ascii
- Show functions of a binary
info functions
- show variables, print the names and data types of all variables that are declared outside of functions (i.e. excluding local variables).
info variables
* specify running arguments
set args
- Set breakpoint
break <function> brak *<line_num>
- Diverting output to file
Change the name of the current logfile. The default logfile is gdb.txt.
set logging file FILE
- Patching a program
By default, GDB opens the file containing your program's executable code (or the corefile) read-only. This prevents accidental alterations to machine code; but it also prevents you from intentionally patching your program's binary.
If you'd like to be able to patch the binary, you can specify that explicitly with the set write command. For example, you might want to turn on internal debugging flags, or even to make emergency repairs.
set write on set write off
- If you specify set write on', GDB opens executable and core files for both reading and writing; if you specify set write off' (the default), GDB opens them read-only. If you have already loaded a file, you must load it again (using the exec-file or core-file command) after changing set write, for your new setting to take effect.
show write
Display whether executable files and core files are opened for writing as well as reading.
Differences between Intel & AT&T Syntax
Intel and AT&T syntax Assembly language are very different from each other in appearance, and this will lead to confusion when one first comes across AT&T syntax after having learnt Intel syntax first, or vice versa. So lets start with the basics.
- In Intel syntax there are no register prefixes or immed prefixes. In AT&T however registers are prefixed with a '%' and immed's are prefixed with a '$'. Intel syntax hexadecimal or binary immed data are suffixed with 'h' and 'b' respectively. Also if the first hexadecimal digit is a letter then the value is prefixed by a '0'.
Example:
Intex Syntax
mov eax,1 mov ebx,0ffh int 80h
AT&T Syntax
movl $1,%eax movl $0xff,%ebx int $0x80
As you may have noticed, the AT&T syntax mnemonics have a suffix. The significance of this suffix is that of operand size. 'l' is for long, 'w' is for word, and 'b' is for byte. Intel syntax has similar directives for use with memory operands, i.e. byte ptr, word ptr, dword ptr. "dword" of course corresponding to "long". This is similar to type casting in C but it doesnt seem to be necessary since the size of registers used is the assumed datatype.
Moving data to registers
when coding something like:
mov ax,4
its possible that the high part of eax is polluted from previous actions and you don't get the results you wanted, thus better use:
mov eax,4
or
xor eax,eax mov ax,4
Compiling,liking..executing (linux)
ASM code -> machine code
nasm -f elf <program.s>
machine code -(linker)-> executable binary
gcc <program.o> -o <program>
executing
./<program>
Standard input, output...
- stdout=screen=1
- stdin=keyboard=0
Syscalls
They are invoked by an interruption and require some parameters that are provided in the registers (eax,ebx,etc).
SYSCALL # | action |
4 | write |
5 | read |
For reference, system call numbers can be found in /usr/include/asm/unistd.h.
Compare numbers sample
Read two numbers and say which one is bigger
Stack address randomization
Ways to check whether it is enabled or not (Debian like)
#cat /proc/sys/kernel/randomize_va_space /* or */ #sysctl kernel.randomize_va_space
To disable it
echo 0 > /proc/sys/kernel/randomize_va_space /* or */ sysctl -w kernel.randomize_va_space=0
Stack execution prevention
Stack execution prevention deactivates the stack addresses as executable. Thus EIP cannot point to an address considered as stack space. It is disabled at compilation time with
$ gcc -fno-stack-protector -z execstack vulnerable.c
-fno-stack-protector disables SSP (stack guard) -z execstack marks the stack as executable
Filling the stack
The genuine-oldskool:
./victim `perl -e "print 'a'x256"` Segmentation fault
or
./victim $(printf "%0512x") Segmentation fault
from inside gdb
(gdb) run `perl -e 'print "a"x516,"\xa8\xf5\xff\xbf"'`
I (L) Coredumps
#ulimit -c unlimited # ./victim $(printf "%0512x") Segmentation fault (core dumped) #gdb -c core
Understanding GDB errors
After inserting a seemingly correct breakpoint you get this error when starting your debugged program
Cannot insert Breakpoint N. Error accessing memory address XXXXXX: input/output error.
This will be probably caused because the address you specified as breakpoint does not match with the beginning of an instruction.
LINKs
- Small easy to follow tutorial about Assembly basics: http://asm.sourceforge.net/articles/linasm.html#Syntax
- Some Spanish howtos: http://www.bhats.org
- Basic howto of gdb counting with source code http://www.cs.cmu.edu/~gilpin/tutorial/
- Brief description of gdb commands http://developer.apple.com/documentation/developertools/gdb/gdb/gdb_14.html
- Useful tools listing: http://projectshellcode.com/?q=node/9
- Some notes about memory alignment on modern kernels http://www.milw0rm.com/papers/82
No comments:
Post a Comment