Function Call with PUSH EAX and RETN

Hi Friends,

Learning how malware creator develops their code is very inspiring because it has some tricks to ensure their application could bypass the security perimeter and hard to be statically analyzed

We know that there is one common technique that almost every malware use to evade the function call so that it makes the static analysis become not easy. The function is called based on the address of the function and it is only assinged during the the application loaded.

Also to make the analyses even harder, the malware developer craft their code at assembly level not to call the function using call function but by manipulating the stack with RETN function

Why use RETN ?

RETN is normaly used when the assembly language execution has come to the end of function so that it will return back to the function that call it. The RETN will actually take the top most value in the stack as the return address

in the case above. when the EIP ready to jump to the function test(), it will push the return address 00E8269D to become the return address when the later will be used when the EIP has reached at the end of test() function.

We can see the code above that when the EIP reached the RETN, we can see that the memory address on top of the stack is the return address after the call 00E8269D. The next EIP will be directed to this memory address.

So with the knowledge above, basically we can evade the function call without call function by manipulating the stack and ret address.

with the above code we can achieve the same call test() function. First we push the address of the test() function into the stack in order to put this on the very top of the stack. Then by calling the RETN the EIP will be directed to that function address.

You can program your c code to handle that with the below code

#include <iostream>

void test() {
    std::cout << "Run your payload here";
}

int main()
{
    test();
    void (*fun_ptr)(void) = &test;
    printf("address of function funct() is : %p\n", fun_ptr);

    __asm {
        mov eax, fun_ptr
        push eax
        retn
    }
    return 1;
}

The above code is the complete application.

so basically the operation is like the above. First we will get the address of the test() function and assign it to func_ptr to point to that address. And then this information is passed to the embedded assembly code in C where we push the address to the stact that is currently in eax. then we call the retn to jump to that address and execute the code in set() function

Why do we need this ?

Why do we need to manipulate the call like this. the intention is actually to make the static analysis become harder because when IDA will fail when IDA tries to parse and generate the graph view based on the call and jmp. The address of the function will only be known during runtime mode or debugging so that IDA cannot decide where the jump will go to. The jump were not detected

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s