A note to the technical reader : This is basically a custom loader I wrote so that i could edit the return address of functions on the stack.
Hi, non technical reader.
So basically this is the small program I wrote, which we are going to play with. In this program there are two functions : func1() and func2(). func1() is called from main, but func2() is never called.
So our aim is to execute func2 at run time.Here is the first run :
As you can see we do not go inside func2.
Reverse Engineering solution The first and the lot easier approach to this is, a RE solution. In this solution i just change some return addresses on the stack and we are done. Lets go step by step.
Step1 : Loading the program in OllyDbg
As can be seen there are three functions main, func1 and func2. These are indicated by the square brackets. The order of these functions is func1, func2 and lastly main.
Step2 : Now I am going to put a breakpoint on func1 and then observe the stack.
We have two images here the first one represents the assembly view of print2.cpp when i hitthe breakpoint and the second one represents the stack when I hit the breakpoint. In figure 1 it can be seen that the func1 starts at 401334 and it(the address) is in read with black background. Which indicates that we have hit the breakpoint. In figure two we can see that the return address for func1() is 0040139A. If we look up this address in the assembly dump, it is the one just after func1() is called that is 401395. Hence, things are fine here, the function always returns to the immediate expression after a call to it. So we have two deductions from here. First that the return address is 40139A which can be changed to make the func1() jump somewhere else. and secondly that this address is placed on the memory address starting 28FF0C.
Step3 : Now we are going to edit 40139A to 401359 so that we can jump over to func2().
After the modification even the comment changes to print2.00401359, which suggests that it is call. And as expected we enter the func2().
However this is not enough. In a similar way we have to edit the return address of func2 to 40139A which was the original return address of func1. Now to be able to identify where is the return address of func2, we single step through func2 till we reach RETN.
Step4 : Here the top address on the stack is the return address for the stack. We need to change this address. In order to return and exit normally.
As can be seen on the stack 0028FF10 is the address where the return address 00403050 is stored. We modify this and then run the program.
We are able to do it neatly. :)
Now the RE solution was though easy, it wasn’t automated, and i had no fuckin idea about how do i make a permanent modification. What i mean here is like if you want to completely change an instruction you can do that and simply save changes to the new executable. But the stack is a dynamic memory region, it is not a part of the exe file that you save. So there was something more, some workaround that was needed. And thanks to Atul Alex Cherian, who told me about loader. So a loader is basically a program that lets the entire exe load in memory and then plays around with it. I first thought about using a tool for this, but then why not just code this shit out. So here is the algorithm that i followed for this.
Step1. Use fread to read the bytes of print2.exe to an array.
Step2. In this array modify the byte that represents beginning of func1 to CC (breakpoint).
Step3. Save this array to a new myf.exe
Step4. Detach pointer to myf.exe and open process myf.exe as a DEBUG_PROCESS
Step5. Waitforadebugevent and use a simple condition to check that it orignates from the one that you forced.
Step6. On receiving the EXCEPTION_BREAKPOINT DEBUG_EVENT suspend the thread using process information of myf.exe
Step7, Now change the CC that you placed to the original byte
Step8. Getthreadcontext of this thread and access the context structure to decrement EIP.
Step9. Now change return addresses of func1 and func2. For func1 only one byte is edited and for func2 one has to edit 2 bytes.
Step10. Resume thread. Myf.exe should exit after you press the first enter, then loader.exe should exit after you press the second enter. Here is the code :
Here is the screen shot showing its execution.
And special thanks to Dhanesh sir. :)
H3LL Y34H! :)
You Might Want To Check Out:
by Adwiteeya Agrawal