3
votes

Lets say I want to write an inline assembly function in a c++ code that returns its return address.

So if I'm calling the function returnAddress() from some address and it needs to return to the address X after the function is done, I want returnAddress() to return the value X.

example of code for returnAddress():

void* getAddress()
{
    __asm {
        pop ebx;     // moving return offset to ebx?
        push ebx;    // restoring stack state
        xor eax, eax;
        mov ax, cs;  // ax <- code segment
        mov ecx, 16;
        mul ecx;     // multiplying the code segment by 16
        add eax, ebx;// adding offset
    }
}

The previous code doesn't work correctly, since when I press alt+8 I can clearly see my code's address is completely different from the return value of this function.

The reason I want to find my code's address in the memory is because I want to try and change it while the code itself is running. If there is any other way to find the address of my code without using inline assembly (maybe using windows API?) let me know please.

Also I'm pretty sure I can't even use CS's (code segment) value using visual studio 2010, so maybe that's what causing me problems... CS always equals to 35. Does the assembly view (alt+8) show incorrect addresses because VS2010 runs a virtual machine?

This is my first post here so maybe I didn't make my point very clear. Please let me know if I can explain myself to make it any clearer.

2
In any case this isn't possible in 64-bit since there is no inline assembly - SomeWittyUsername
Just use the _ReturnAddress intrinsic. - Raymond Chen
@RaymondChen I'm favoriting this just for that comment. I had no idea that even existed. Thanks! - WhozCraig
So, problem #1 in producing self-modifying code is solved, on to problem #2 of...?? - Michael Burr

2 Answers

4
votes

Code segments are only used in 16-bit systems. With the introduction of 32-bit, code segments went away.

You can use VisualStudio's intrinsic _ReturnAddress() function:

void * _ReturnAddress(void);
#pragma intrinsic(_ReturnAddress)

void* getAddress()
{
    return _ReturnAddress();
}

If you want to do it manually, say on a non-VisualStudio compiler, then the call stack of a 32-bit x86 function call contains the full 32-bit return address, so you can return it as-is:

void* __declspec(naked) getAddress()
{
    asm
    {
        mov eax, [esp];
        ret;
    }
}

For x64 function calls, you should be able to use the equivilent 64-bit registers:

void* __declspec(naked) getAddress()
{
    asm
    {
        mov rax, [rsp];
        ret;
    }
}
4
votes

Actually I had a hard time trying to understand the mystery that you're using just to recover the return address. As some suggested, you may use intrinsic _ReturnAddress. Nevertheless, just for fun, you can use this straightforward code:

__declspec(naked) 
void* get_RetAddr()
{
    _asm {
        mov eax, [esp]
        ret
    }
}