Jump to content
Tuts 4 You

Manually processing relocations


deepzero

Recommended Posts

hi,

i am trying to manually rebase a PE32 file, ie instead of having the windows loader load it, i read the file myself and manually resolve imports, relocations, etc.

import processing went fine, but the relocation stuff just doesnt work.

I can get a pointer to the DWORD that needs to be relocated, but somehow the the delta is incorrect or whatever.

So i tried to manually rebase it, but failed :S

rebaset this push:

//original code

0040106E 68 79204000 PUSH 00402079 ; ||FileName = "Keyfile.dat"

original imagebase: 400000

new imagebase: 6d000

delta = new - original

hexa:

FFC6D000h = 6d000h - 400000h = delta

decimal:

delta = 446464d - 4194304d = -3747840d

79204000h + FFC6D000h = 78E71000h

2032156672d + -3747840d = 78E71000h

should be:

//properly rebased push

0006D66E 68 79DC0600 PUSH 6DC79 ; ASCII "Keyfile.dat"

what`s wrong? :S

edit:

i`m kinda confused as to why

0006dc79

-00402079

-----------

FFC6BC00

but

6d000

-400000

______

FFC6D000

Edited by deepzero
Link to comment

If Delta confuses you, just think of it that way:

Old address - old imagebase = RVA

and then simply

New address = RVA + new imagebase

But instead of having to recalculate that all the time you just use a delta.

All you have to do is ADD delta

In your last example, look at the 2 in 402079, that explains the D in FFC6D00 (B+2=D)

Link to comment

good idea, but it gets me the same result as before:

0006D66E 68 79F00600 PUSH 6F079//invalid

this is the code:

						push eax
push ebx
mov eax,ImageBase//original imagebase
mov ebx,target//pointer to dword to relocate
sub dword ptr [ebx],eax
mov eax,newbase//new base
add dword ptr [ebx],eax
pop ebx
pop eax

i checked all the values on runtime, all correct (ImageBase, target, newbase).

in my last example, the two calculations should get me the same result, because it`s the same RVA.

Since the result says different, i apparently messed up somewher, but i dont see where... :dunno:

edit:

in more detail:

						push eax
push ebx
push ecx
push edx
mov eax,target
mov ebx,dword ptr [eax]
mov ecx,ImageBase
mov edx,newbase
sub ebx,ecx
add ebx,edx
mov edx,target
mov dword ptr [edx],ebx
pop edx
pop ecx
pop ebx
pop eax

same result.

something is VERY wrong here... :sick:

Edited by deepzero
Link to comment

The code itself looks OK to me. The calculation in your last post is correct, too

00402079 - 400000 = 2079 (RVA)

6D000 + 2079 = 6F079

You sure 6D000 is your new imagebase? If your 'properly rebased' code is correct, that means it accesses data from the PE header. Maybe it's 6B000 or something, that would explain miscalculation.

Also, make sure you correctly parse the reloc table, maybe that's where your error is. You have mask out the last 3 bytes if I remember correctly, maybe you forgot something there.

Edited by Killboy
sleepy
Link to comment
Peter Ferrie

look again:

original imagebase: 400000

new imagebase: 6d000

0006dc79

-00402079

-----------

FFC6BC00

but

6d000

-400000

______

FFC6D000

0006dc79 - 6d000 = 0c79

00402079 - 400000 = 2079

not the same. Your image base in 6b000, not 6d000.

Link to comment

//original code

0040106E 68 79204000 PUSH 00402079 ; ||FileName = "Keyfile.dat"

//properly rebased push

0006D66E 68 79DC0600 PUSH 6DC79 ; ASCII "Keyfile.dat"

402079 (VA) - 400000 (ImageBase) --> 2079 (RVA)

6DC79 (VA) - 2079 (RVA) --> 6BC00 (New ImageBase)

So the new ImageBase is not 6D000 but 6BC00...

Cheers

Nacho_dj

Link to comment

ok, i got it.

Turns out there was a bug mapping the sections after fixing imports/relocaions.

When the sections are mapped to the proper adresses the numbers are correct and it all works out... :yahoo:

Thanks for your help, Nacho,PF and Killboy :wub:

Link to comment

You're welcome! :)

Btw, did you note that relocations section (if it exists) must include all absolute addresses related to import address table?

Cheers

Nacho_dj

Link to comment
Peter Ferrie

Btw, did you note that relocations section (if it exists) must include all absolute addresses related to import address table?

You need to explain this one to me. Imports can't be relocated, because they're relative already.

Link to comment

You need to explain this one to me. Imports can't be relocated, because they're relative already.

i not know if you was solved, but in old times, was used a 2method in some other packers

1) PEP, when section is in other part, copy the section real, and reserve that place and move the place+newimg ,check tutorial of subzero
/>http://tuts4you.com/download.php?view.346

2) moving and processing the section, relocation, can have this example of deroko:

can be used a place to change in any execution the resource zone:

@
/>http://deroko.phearless.org/rsrc.zip

about nacho, i know that know many, and peter ferrie too :S

well for my:

the iat related mm rare, but maybe are that say only for the category of forum:

or when reloc are ok, maybe iat can move, not the apis, the section maybe or size ?..not know. maybe the thrunk direction?, well this is a tool interesting maybe

3) http://tuts4you.com/download.php?list.38

try to check this app in that list:

ReloX 1.0

Author MackT
/>http://tuts4you.com/download.php?view.419

or
/>http://www.woodmann.com/collaborative/tools/index.php/ReloX

maybe can help in other cases

4)nice you was solved:

Turns out there was a bug mapping the sections after fixing imports/relocaTions.

When the sections are mapped to the proper adresses the numbers are correct and it all works out

but i wana say that if can be useful this appendix ;)

greetings bro

Apuromafo

Link to comment

Hi,

so I got the same problem with some dll files using diffrent ImabeBase's.So I have test the ReloX tool and it's working great and the unpacked dll files are working with any IB like the original files. :)

Thanks Apuromafo for posting this tool today which I have never used before.

greetz

Link to comment

So I think I had this reloc problem never beofre or I was to blind or something or did not checked this out in all this years... :) But its nice to know it and use it now if I see this problems again. :)

greetz

Link to comment
You need to explain this one to me. Imports can't be relocated, because they're relative already.

Not the contents of the actual IAT/FirstThunk arrays, but the actual references to the members. The pointer content is determined at runtime when the dll gets loaded and the procedure address is realized so relocating is impossible/pointless in the context we're using here. The addresses/references to these though are absolute (in most cases) and as such need relocating when the image is loaded at a different ImageBase, otherwise they would end up like the following examples:

When loaded at preferred ImageBase

CALL DWORD PTR [100174D8]

MOV EAX, DWORD PTR [1001D0E0]

MOV DWORD PTR [1001D0E4],SomeValue

When loaded at different ImageBase

CALL DWORD PTR [iNCORRECT_ADDRESS]

MOV EAX, DWORD PTR [iNCORRECT_ADDRESS]

MOV DWORD PTR [iNCORRECT_ADDRESS],SomeValue

Wow I always thought Relox is one of the most basic tools for any unpacker. How do you fix dumped DLLs without it

I know i'm not explaining anything new here guys, but think on it like this:

The packed file gets unpacked to the memory where the windows loader has placed it, not often its preferred ImageBase, so the packer stub must also take care of performing the base relocations so that all references are intact and valid. Most people choose to dump their dll's at the beginning of DllMain, where this has already taken place, so the code is not its original state but a relocated state.

Dumping the file here results in a file which has absolute addresses for all of its references, which is bad because the dll might not get loaded to the ImageBase what it was dumped at and this will screw up all of the addresses. Add to this most people don't zero the relocations information in the PE header on such files and as a result the Windows loader will still try to relocate all of the entries it finds in the relocations table, even though it is now invalid because it was based on an ImageBase the file no longer uses...

If they do zero the information in the header, they're left with a file which *must* run at the ImageBase it was dumped at because the loader is unable to relocate the references with no records... From what i've read, tools used for building relocation records usually require the user to load 2 copies of the relocatable image at different ImageBases and then the images are scanned for references which point into its own memory space. These references are kept in a table from which the new relocation records can be built.

I have something to remind all of though: If the packer stub has to process relocations on the protected image then there *should* be a relocation table in some form. Sometimes this is packed and/or encrypted but at the end of the day there is a place in code where the stub locates and adjusts these references and this place can be used to gather the original table if necessary.

Sometimes the original relocation directory is 100% intact, whatever the case you should be able to reconstruct the relocations information in the PE header and the actual directory if need be. If you prevent the initial relocation from occurring while it is unpacked so when you dump the file the code will already be at the preferred ImageBase or sometimes you can dump the file looong before it has actually reached OEP.

There seems to be a common misconception that an application/library must be at OEP to be dumped correctly but this is simply not the case. When we run an exe off disk it isn't sitting there waiting at EntryPoint to be summoned, the windows loader maps it into memory and performs its preparation before calling the EntryPoint. It is my belief that this has become the most popular location to dump the unpacked images because from here you only need to subtract the ImageBase/LoadBase and you have the AddressOfEntryPoint RVA, generic as can be without need to update or modify as new versions come out, just like memory breakpoints on the suspected code section but i digress.

If your relocation information in the PE header is valid and complete and the dumped file has the ImageBase stamped as the preferred one, the windows loader will gladly relocate the dll to any section it maps the dll to. I have used this method countless times when *revirgining* Armadillo protected dll files and it has yet to fail me, i wouldn't have the faintest idea how to use Relox though, although i have read nothing but good posts about it.

If i seem to babble or wander incoherently, you have my deepest apologies, i've just pulled another all-nighter and i'm operating without sleep for the last 72 hours, i'm going to go and try get some zzzzz's now i think. :D

HR,

Ghandi

Edited by ghandi
Link to comment

I remember writing a tool for Arma that fixes the reloc size in the PE header, the RVA was correct but size was 0, and for some reason Windows needs the exact size, not one byte off or it explodes (access violation, mind you, you would expect *some* sanity checks).

Most of the time it isn't there though, and before I start converting internal packer tables into relocation directories I rather dump 2 instances of the DLL and use Relox. If you're writing an unpacker it's a whole different story, isn't it :)

Link to comment

Youre absolutely correct mate, individual cases would be simpler to correct automatically using something like Relox.

Armadillo doesn't keep the original relocations information in the PE header in any versions i've ever seen, instead replacing it with a pointer to its own relocation records for the stub. That way the Windows loader will take care of the stub and the stub can take care of the protected file.

But then i've never worried too much what the stub does at runtime to the header because i use the one off disk, i wouldn't have a clue what it has there after it plays around with it.

HR,

Ghandi

Link to comment

Armadillo doesn't keep the original relocations information in the PE header in any versions i've ever seen

That's true, and also it's true Armadillo keeps all relocations data of virgin file inside one of the sections, so to rebuild any file you have to determine where in the file are located that data, then get the relocations size (as Killboy mentioned), fix all relocations referenced in the code section if they have been altered by the launcher of the original ImageBase, and then fix the PE Header info to indicate properly the rebuilt relocation section.

Talking about Armadillo, all of this is performed automatically by Armageddon when fixing PE header and sections size. :)

Btw, ghandi explained very well what Peter Ferrie was asking.

Cheers

Nacho_dj

Link to comment
  • 4 months later...

Thanks to ghandi for a detailed description; it clarified things for me. Could someone please explain what is meant by "zero the relocations information in the PE header"? Does it mean that the .reloc section header needs to be wiped from the dumped dll?

I use ImpREC for dumping an unpacked dll and can't get the dumped dll to load in Olly. It crashes right after "Program entry point" log message. The IAT is fine as far as I can tell. If the problem was that its preferred ImageBase is occupied, it would I think crash after "Entry point of debugged DLL". Any help would be very much appreciated.

Thanks,

zgreders

Edited by zgreders
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...