3

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)

enter image description here

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!

2

1 Answer 1

2

It appears you've already guessed what the actual issue is - your call instruction is using direct addressing and not relative addressing. This means that when a DLL changes it's location between executions you're still trying to execute the same absolute value, resulting in different types of errors depending on the content of the actual content in that address.

Specifically to your question - 0xFF 15 is an absolute, near, 4 byte immediate call. 0xFF is used for absolute calls, while 0x8E is used for relative calls (as you can see in your image, at the yellow highlighted line).

Replacing the single byte 0xFF will turn the instruction to a relative instruction, meaning the call will be to $+5e01d0e4 instead of to 0x5e01d0e4. The dollar sign ($) is a conventional representation of "the address of the next instruction".

Because how the x86 CPU (and many other CPUs) works, it is easier to first advance to the next instruction, and only then carry out any EIP modifying operations, thus having relative operations modify the EIP values of the following instruction.

Replacing the four last bytes with any signed integer will make the call instruction add that number (thus negative numbers are used to call a smaller address value) to the address of the next instruction. For example, the byte code FF 15 EA FF FF FF will be translated to a six byte long instruction call $-6, creating a call that calls itself, eventually faulting on a stack overflow.

A method simpler than manually editing instruction byte code could be using olly's assemble command with a $ sign to indicate a relative instruction.

3
  • So if I understand you correctly, 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 how do I load this value then? I can make a call 0x<theadress>, but that doesnt work because the IAT entry only contains the
    – Carraway
    Oct 30, 2016 at 22:34
  • The IAT is at a position relative to the start of the loaded image. This is not useless, this is precisely what makes it relocatable code easy by using relative addressing. I don't follow what you're still stuck on, please edit your question of you need more info (or explain clearly here)
    – NirIzr
    Oct 30, 2016 at 22:44
  • sorry about that comment, i hit enter on accident. Edited the original post, everything seems to be working now.
    – Carraway
    Oct 30, 2016 at 23:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.