summaryrefslogtreecommitdiffstats
path: root/md/writeup/elf_rewrite_function.md
blob: 9cc29c10f523cbfed6036d7f679d314e66a81d27 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
title:ELF rewrite function
keywords:elf,linux

# ELF rewrite function
Main idea was to replace compiled in function with some other code and
run it. In default it is not possible. If you try to write some bytes
with memcpy() in function location then segfault happens. Why? Programm
has different segments and they used for different program purpose.Our
code belongs to readonly-executable segment. And '.text' section.
We can se it with readelf -S main -l in previous post
there was program that can be used to make segment writable.After running
./textwriteble main

now segment with '.text' section becomes writable. When we try
use memcpy() there is no segfault now.
Second thing is how to make our function that will
replace compiled in function position independent for some data inside
function? First of all we should know our current position.It is in
eip register. push eip? mov eax, eip? it doesnt work. When we use
call in stack is saved return address. Now with this small function it
can be saved in some location

```asm
get_ip:
    mov ecx, [esp]
    ret
```

At this moment we have converted segment to writable.Have written
position detection function. If there would be data that will used
in replaced function than need detect position of that data. For
example we will use

```asm
mov eax, sys_call ;we will use SYS_WRITE = 5
mov ebx, output_id ; output on terminal is STDOUT 1
mov ecx, pointer_to_msg
mov edx, size_of_msg
int 80h
```

if this was ordinary situation then define:

```asm
msg db "Hello",10
msg_size = $-msg
```

and our code becomes

```asm
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg
mov edx, msg_size
int 80h
```

but how to know position of msg if you dont know position where
function will placed?Use function get_it and you will know current
instruction position. And it will next instruction after

```asm
call get_ip
```

Our code becomes

```asm
call get_ip    ;calling and detecting eip
saved_ip:      ;position that will be saved
jmp get_ip_end ;jump over function
get_ip:
    mov ecx, [esp] ;save return eip
    ret
get_ip_end:
mov eax, SYS_WRITE   
mov ebx, STDOUT
add ecx, msg-saved_ip  ;offset of msg
mov edx, msg_size
int 80h
```

ECX has position independent pointer to our text.For testing purposes
function fun() is filled with

```c
asm(".byte 0x90, ... ,0x90");
```

hex 0x90 translates in nop instruction.

nop is No OPeration instruction.
And function does nothing.Function fun()  contains

```asm
push ebp
mov ebp, esp
start_overwrite_here:
nop
...
...
...
nop
pop ebp
ret
```


Nop instructions can be replaced with any binary code. There should
be enough nop instructions for our binary code. There is no check
on function size that way when overwriting can be problems if binary
code size is larger then function size.Start function overwriting at
position (&fun+3) with memcpy()

```asm
push ebp
mov ebp, esp
start_overwrite_here:
nop
...
...
...
nop
pop ebp
ret
```

Wuala function after enabling segment can be overwritten. Here is
used previous experienced we have mega trick with function replacement.
Compile:
```sh
make
```



## Links
http://www.unixwiz.net/techtips/win32-callconv-asm.html  
http://www.programmersheaven.com/mb/x86_asm/357735/357735/get-the-value-of-eip/  
http://toku.es/2010/06/text-writable/  
http://main.lv/posts/view/elf-text-section  
http://main.lv/posts/view/linux-assembler-hello-world  

## Downloads
replace_function.zip -
4KiB - http://archive.main.lv/files/writeup/elf_rewrite_function/replace_function.zip