Disclaimer: I am relatively new to this whole RE thing. So I successfully crammed some instructions into the end of an existing DLL and redirected a call.
Now I actually want to do things with a function argument before calling the original code and try to OutputDebugStringA
it.
OutputDebugStringA
is statically imported by my Dll, so I try to do the following:
call dword ptr ds:[<&OutputDebugStringA>]
This is an instruction I copy from a usage in the DLL itself.
So this works and is successfully called. But, when I patch the Dll with this instruction, on the next run the address is invalid which leads to an Access Violation and crash. (See red line in picture)
Why is that so? Shouldn't the IAT entry of the function be always at the same place, relative to where the Dll was loaded?
And how do I fix it?
Do I need complicated hacks to find the base address of my module?
Or is there some sort of relative far call instruction I am stupidly not aware of?
Thank you for your help.
I think I got it now. So I can't be sure that the IAT is always at the same address, not even relative to the ds segment (which makes it kinda useless in my opinion).
I can however be sure that the IAT address is always a fixed relative amount away from the code I want to run.
So I googled PIC techniques under x86 and ended up with this code that seems to work fine so far.
push ebp
mov ebp,esp
push eax
push ecx
push edx
push dword ptr ss:[ebp+C]
call <rcp-be-name.tmplbl>
pop ebx ;@tmplbl
lea eax,dword ptr ds:[ebx+80F] ;the relative offset
call dword ptr ds:[eax-5] ;dunno why 5
pop edx
pop ecx
pop eax
push dword ptr ss:[ebp+C] ;the original arguments
push dword ptr ss:[ebp+8] ; ...
call rcp-be-name.644A97D0 ;the original function
add esp,8
pop ebp
ret
Thanks a lot!