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