diff options
Diffstat (limited to 'md/writeup/elf_rewrite_function.md')
-rw-r--r-- | md/writeup/elf_rewrite_function.md | 147 |
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 |