Log in

View Full Version : reversing DLLs with relocation table?


Hero
August 22nd, 2010, 14:55
Hi all

I was reversing a DLL and have no problem with reversing it right now in general.
But when I was reversing, I suddenly asked myself: "When you patch a DLL and make changes in its code, what should you do about relocations?" and I didn't have a good answer for it myself.
Anybody knows what we should do about relocations? Because relocations are like values(addresses) that will change in link time based on relocation table. Now assume that our patch for DLL crosses over one of these addresses that should be changed by relocation table on link time. if this happens, some value will be added to some bytes of code and it will result in inappropriate changes in our patch code(if I have not messed up anything in understanding how relocations work).
If what I say is true,how I should solve this problem? remove any relocation reference that may be available in my patch code from relocation table and add some if needed?
And another question: is it possible that we have relocation for addresses that are in same section of a DLL?or we need them when we need to access between sections?

Regards

Extremist
August 22nd, 2010, 18:33
Quote:
[Originally Posted by Hero;87604]
If what I say is true,how I should solve this problem? remove any relocation reference that may be available in my patch code from relocation table and add some if needed?
And another question: is it possible that we have relocation for addresses that are in same section of a DLL?or we need them when we need to access between sections?


The easiest solution is just to watch out for relocations and avoid changing relocatable words. Usually they're easy to spot (global variables, string addresses, jump tables, vtables, function pointers, etc.), and chances are that a patch shouldn't touch them. Otherwise you'll have to edit the .reloc table, probably in-place to avoid the headaches of inserting or deleting entries.

The only time you need relocations is when a DLL doesn't load at its preferred address, but these days that's unusual.

Hero
August 22nd, 2010, 21:56
Quote:
[Originally Posted by Extremist;87609]but these days that's unusual.


this is not unusual in windows 7 and vista at all,because they use address randomizers.

Maximus
August 23rd, 2010, 10:18
Quote:
[Originally Posted by Extremist;87609]
The only time you need relocations is when a DLL doesn't load at its preferred address, but these days that's unusual.


With MSVC giving standard address for all DLLs, it is never 'usual'.
Also, even if you disable address space randomization, you will always end up in address-racing dlls due to the load-order of the modules.

Hero
August 23rd, 2010, 11:38
Quote:
[Originally Posted by Maximus;87612]With MSVC giving standard address for all DLLs, it is never 'usual'.
Also, even if you disable address space randomization, you will always end up in address-racing dlls due to the load-order of the modules.


completely true.
even in my test in windows XP, my dll loaded in various addresses because of race.

But I found something that can ease patching dlls with relocations a little and prevent getting into relocations at same time too....
When you look into codes of dll while debugging it in ollydbg, olly draws a line under bytes that is changed with relocation beside command. Then when you write your patch codes,you can jump over these positions easily by JMP commands.

Good luck everyone

Darkelf
August 23rd, 2010, 13:36
Have you tried to get the baseadress at runtime and make your patch relative to it?
I mean something like:

Code:

push 0
call GetModuleHandleA


which returns the baseadress of the .dll.
I don't know if that's really related to your problem. If not, just ignore it.

Regards
darkelf

edit: Would you be so kind as to provide an example? I'm doing all my patches relative to the baseaddress of a .dll and I've never run into a problem.

OHPen
August 23rd, 2010, 17:07
@Hero: I can answer one of your questions. In my opinion you have two possibilities to solve the problem. One is to change all corresponding relocations to point to a code location which is not used by your patch code. I think that is easier than remove single relocations and realign the relocation table.
Another Idea would be to analyse the relocations which point to your patch code. If you for example have a relocation which is simply adding a delta to a location in your code than you could substract that delta and instead of patching your patch code you could patch hex values which are only valid if you add that value determined by the relocation.
Finally this method would end up in get working patch code at runtime AFTER the relocations are applied. For virii writes there is another advantage of this mechanism. you prevent static code analysis if you use this technique.

Hope that helps you.

Regards,
OHPen.

aqrit
August 23rd, 2010, 22:34
The instruction can be changed so it dumps to an unused register
which may save a tiny bit of space in some situations

A3 EFBEADDE MOV DWORD PTR DS:[DEADBEEF],EAX

can be changed to

25 EFBEADDE AND EAX,DEADBEEF

if EAX is zero then it is effectively a NOP

Hero
August 24th, 2010, 22:37
Quote:
[Originally Posted by aqrit;87620]The instruction can be changed so it dumps to an unused register
which may save a tiny bit of space in some situations

A3 EFBEADDE MOV DWORD PTR DS:[DEADBEEF],EAX

can be changed to

25 EFBEADDE AND EAX,DEADBEEF

if EAX is zero then it is effectively a NOP


This is true, but I normally use other way.
Because you normally don't see this instruction as first instruction in a function(normally there is a push as first instruction or any other 2-byte length instruction) I use this way:

6AFF PUSH -1
A3 EFBEADDE MOV DWORD PTR DS:[DEADBEEF],EAX

to:

EB05 JMP SHORT $+5
A3 EFBEADDE MOV DWORD PTR DS:[DEADBEEF],EAX

and that jump goes exactly after mov command and I will right patch code in there. I guess this way gives you more flexibility, because you don't know if eax is 0 when you enter a function.

Regards