summaryrefslogtreecommitdiff
path: root/md/writeup/elf_rewrite_function.md
diff options
context:
space:
mode:
Diffstat (limited to 'md/writeup/elf_rewrite_function.md')
-rw-r--r--md/writeup/elf_rewrite_function.md147
1 files changed, 147 insertions, 0 deletions
diff --git a/md/writeup/elf_rewrite_function.md b/md/writeup/elf_rewrite_function.md
new file mode 100644
index 0000000..b507213
--- /dev/null
+++ b/md/writeup/elf_rewrite_function.md
@@ -0,0 +1,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
+
+```
+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:
+
+```
+msg db "Hello",10
+msg_size = $-msg
+```
+
+and our code becomes
+
+```
+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
+
+```
+call get_ip
+```
+
+Our code becomes
+
+```
+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
+
+```
+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()
+
+```
+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:
+```
+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 \ No newline at end of file