Reversing Scratch Book


Introduction

This post will be a scratchbook 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

gcc -ggdb -o tesoro tesoro.c

GDB

 l

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

info functions

info variables

* specify running arguments

set args

break <function>
brak *<line_num>

Change the name of the current logfile. The default logfile is gdb.txt.

set logging file FILE

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

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.

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 dont 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...


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 seemengly 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.


ReversingScratchBookPost (last edited 2009-10-31 20:35:06 by eslimasec)

Locations of visitors to this page