Would it be possible to fake the return address at, ebp + 4.
I'm currently writing a DLL that you would inject into a game, in which it would call game functions to do things, but the functions I call check the return address against the program itself, and if its outside their base it detects it.
So basically is there any way to fake the return address in any way?
It works like this:
if ( (_BYTE *)retaddr - (_BYTE *)unusedPadding >= (unsigned int)&byte_A6132A )
{
dword_11E59F8 |= 0x200000u;
dword_162D06C = 0;
result = (void (*)())sub_51FEE0(dword_11E59FC, v5, (_BYTE *)retaddr - (_BYTE *)unusedPadding, ebx0, edi0, a1);
}
Better way:
push returnshere
push your_second_argument
push your_first_argument
push address_of_fragment_in_exe
jmp function_you_want_to_call
returnshere:
; more code
Where address_of_ret_in_exe is the address of this fragment:
add esp, 8 ;4 * number of arguments pushed
ret
This has the advantage of not editing the game binary. I've seen more than one game that checksummed itself so if you edited it, even in slack space, you're in trouble. If they went through so much trouble as to verify calls come from the game binary, than they likely have defenses against the game binary from being edited. Just be glad they don't trace the call graph.
You mean so on entry to the called function, the return address at [esp]
is not the actual call site?
You can emulate call
by pushing whatever you want and then jumping. Of course, the function you call this way will return to the return address you give it. There would also be a significant perf penalty for mismatched call
/ret
, because you'll break the CPU's return-address predictor stack.
Can you put some trampoline functions at an acceptable address range, and call through them? Although that's really inconvenient in a 32bit ABI which passes args on the stack. I guess you'd have to pass an extra arg to the trampoline function that it could use to stash the return address, instead of copying all the args.
So the trampoline could be something like:
mov [esp+20], esi ; save esi in a dummy arg slot
mov esi, [esp] ; save the orig return address in a call-preserved reg
add esp, 4 ; call with the original args
call lib_function
push esi ; restore the orig return address
mov esi, [esp+20] ; and restore esi
ret ; return to orig return address
That's not wonderful, and takes a lot of code for something that needs to be duplicated for every library functions. (And it doesn't make a stack frame, so might hurt debugging / exception handling?) For functions without many args it might be shorter to do something like
push [esp+8] ; 2nd arg
push [esp+8] ; 1st arg
call lib_function
add esp, 8
ret
Using indirect calls would let you use the same trampoline for multiple functions, but at the cost of branch mispredicts if there isn't a simple short pattern.
And of course none of these trampolines can work unless you can stick them in memory at an address the library will accept calls from.