2010-9-16 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
withmemcpy() 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
there was program that can be used to make segment writable.After running
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 functionposition 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 functionit
can be saved in some location
At this moment we have converted segment to writable.Have writen
position detection function. If there would be data that will used
in replaced function than need detectposition of that data. For
example we will use
if this was ordinary situation then define:
and our code becomes
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 instructionafter
Our code becomes
ECX has position independent pointer to our text.For testing purposes
function fun() is filled with
hex 0x90 translates in nop instruction.
nop is No OPeration instruction.
And function does nothing.Function fun() contains
Nop instructions can be replaced with any binary code. There should
be enought nop instructions for our binary code. There is no check
on function size that way when overwriting can be problemsif binary
code size is larger then function size.Start function overwriting at
position (&fun+3) witn memcpy()
Wuala function after enabling segment can be overwriten. Here is
used previous expirienceand we have mega trick with function replacment.
Compile:
run it. In default it is not possible. If you try to write some bytes
withmemcpy() 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 previos 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 functionposition 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 functionit
can be saved in some location
get_ip: mov ecx, [esp] ret
At this moment we have converted segment to writable.Have writen
position detection function. If there would be data that will used
in replaced function than need detectposition 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 instructionafter
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
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 enought nop instructions for our binary code. There is no check
on function size that way when overwriting can be problemsif binary
code size is larger then function size.Start function overwriting at
position (&fun+3) witn memcpy()
push ebp mov ebp, esp start_overwrite_here: nop ... ... ... nop pop ebp ret
Wuala function after enabling segment can be overwriten. Here is
used previous expirienceand we have mega trick with function replacment.
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