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 demanding 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 function’s address, and it is only assigned during the application loaded.

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

Why use RETN ?

RETN is typically used when the assembly language execution has come to the end of the function to return to the position that calls it. The RETN will take the topmost value in the stack as the return address

In the case above. When the EIP is 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 the end of the test() function.

We can see the code above that when the EIP reached the RETN, and 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 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 test() address function and assign it to func_ptr to point to that address. This information is passed to the embedded assembly code in C where we push the address to the stack 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 to make the static analysis harder because IDA will fail when IDA tries to parse and generate the graph view based on the call and jmp. The function’s address will only be known during runtime mode or debugging so that IDA cannot decide where the jump will go to. The jump was 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