View Full Version : Pointers in unpacked file don't get rebased
Darkelf
September 15th, 2011, 16:51
Hi there,
I have a problem which I know where it comes from and why it occurs - but I don't know how to overcome it.
I've searched through the forum and the web but somehow I can't find a solution. Maybe my head is already too full with too many thoughts on the problem. Let's begin from the start:
I have a .dll that I unpacked manually. Not a big thing so far. What's a problem is the packer is writing some pointer addresses according to the base address the .dll is loaded to. When I dump the .dll these addresses are just carried over to the dump. Obviously the dump won't work due to that.
It looks like this:
Code:
2002DB16 |. A1 2CC40510 MOV EAX,DWORD PTR DS:[1005C42C]
The dword pointer should be: 2005C42C and I have absolutely no idea how to reach this goal.
I thought of replacing all the fixed pointers with relative addresses like [eax + xxxxxxxx] (let's assume eax holds the base address) but that looks like a Sisyphean task. Then I thought of creating a relocation table onmy own (somethong I never did before and also something I don't know if it is possible at all)
I'd be really, really thankful for any advice.
Regards
darkelf
Kayaker
September 15th, 2011, 22:32
I'm a little confused as to the intent here. Do you mean that the original dll ran at base address 0x10000000, you dumped and got the hardcoded pointer addresses, but then you rebased in IDA to 20000000? Or is 20000000 the imagebase specified in the PE header and IDA is just disassembling based on that address?
If the latter, changing the PE header imagebase should make both the IDA disassembly make sense, as well I think as allowing the dll to run properly, as long as it continues to load at the preferred base address of 10000000. Or maybe I'm missing something here.
If you're trying to change those pointers and you know they should be offset 200xxxxx, an IDC script to patch those bytes should be doable. Look into the GetOperandValue / GetOpnd commands to assist. Then you could create a DIF file and patch as a new dll executable.
You'd be stuck then hoping the new dll is actually loaded at the preferred 20000000 base address though, so maybe there is a better way to modify those pointer addresses so it won't matter what the final loading address is.
Anyway, here are a couple of posts on patching via DIF file:
http://www.woodmann.com/forum/showthread.php?7868-Patching-with-IDA-Pro
http://www.woodmann.com/forum/showthread.php?3670-quot-Patch-program-quot-functions-removed-in-IDA-Pro-!
And an IDC script example which might help in patching operands (script 2)
http://www.woodmann.com/forum/entry.php?35-IDC-scripting-a-Win32.Virut-variant-Part-1
Darkelf
September 15th, 2011, 23:45
Hi Kayaker,
thanks a lot for your reply and a big "Sorry" for the confusion.
The dll runs indeed at base address 0x10000000. I dumped it and got the hardcoded pointers as above. It took me a while to notice that they are hardcoded, because standalone in Olly the dll is loaded at it's preferred address (0x10000000) and all is well, but when started with the main program the dll belongs to, it crashes. I then debugged the whole stuff and found out about the hardcoded pointers, as the dll was rebased when running with it's main program. This was when I started searching the web for rebasing/relocation just to find it a really common problem as far as unpacking dlls is concerned. The packer in question is PECompact 2.08. Unpacking this crap is normally a blind flight - if an exe is packed with it. It was actually the first time I played the mup-game with a dll. In the last couple of hours I 've read every tutorial on unpacking dlls that I could get my hands on, but none of them dealt with relocation.
Thank you very much for searching and providing me with the links. I guess this will be a very, very tedious task because I have no idea how to find the pointers in question apart from checking every line of disassembly and comparing it with another instance of debugger/disassembler running the dll with another base address. Right now I'm thinking about coding some tool for that but I have to read more on relocation and how it is handled in the header and the whole PE. I guess this would be a somewhat useful tool.
Best regards
darkelf
Kayaker
September 16th, 2011, 00:44
Hi Darkelf,
That's OK, I was the one confused, not you

OK, maybe it's not this simplistic, but is there any consistency in the instructions which use the hardcoded addresses you wish to change? If you can determine if they're all in the form of "DWORD PTR DS:[100xxxxx]" or similar, you could still use the IDC patch approach. You'd just be doing a string search of the 2nd operand (or maybe the 1st as well) to match that pattern, then fix.
Maybe try a
text search in IDA for "100" and see if it picks up every instance of the hardcoded pointer?
Cheers,
Kayaker
izlesa
September 16th, 2011, 04:30
Most packers process relocs by hand on initialization stage. They have internal relocs table. You must find this table and convert her to pe format of relocation's. No generic way to relocate dll without this information, because you can`t differentiate address from constant value in generic way.
Also, if this dll loaded first and no one reside on address 0x10000000 you can set in pe header, that this dll cant relocates.
PS Sorry for my bad english.
Darkelf
September 16th, 2011, 10:58
Hi izlesa,
your english is readable so I know what you mean and that's all that's needed, isn't it? Since my english is also far from being perfect I'm in a way trained to read between the lines

You've written that most packers have an internal relocation table. Do you mean a table outside the .reloc section? Because the .reloc section of that packed file in question is almost empty. In the header there it says that there are 18 entries but there are just 3 of them (assuming an entry is 32bit long). I guess you must be right because the relocation is done in a couple of loops with preceding VirtualAlloc(). How would you convert this internal table? Maybe you can give me a short example. As for the "don't-relocate-me"-flag: that's new to me. I always thought that this is only possible if ASLR is completely turned off.
Best regards
darkelf
izlesa
September 16th, 2011, 15:22
Hi
>> Do you mean a table outside the .reloc section?
Yes, packers must do all job for setup packed image in memory (import, relocs, etc). They maintain internal reloc tables, more often in same pe format (IMAGE_BASE_RELOCATION), and you can relocate dll self or just add reloc directory in unpacked binary.
>> I always thought that this is only possible if ASLR is completely turned off.
it is mistake. see IMAGE_FILE_HEADER::Characteristics, flag IMAGE_FILE_RELOCS_STRIPPED. But if there are not free space on imagebase address, LDR will not load this dll.
blabberer
September 16th, 2011, 18:30
http://www.woodmann.com/forum/entry.php?231-Simple-Dll-Compiled-From-Commandline-Unlike-what-google-returns-vc-proj
you can use /FIXED commandline option to the linker when you compile the above mentioned code and the compiler will strip off the relocations
and the dll will load only at its preferred imagebase
and i think what islesa is trying to tell is you can probably edit the peheader to resemble image reloactions stripped
i passed /nofixed to the above code while all else are same and compared both dlls and i find the diff to be
Code:
reloc>fc /b FIXED\AddNumbers.dll NOFIXED\AddNumbers.dll
Comparing files FIXED\AddNumbers.dll and NOFIXED\ADDNUMBERS.DLL
000000DE: 03 04 ; NumberOfSections
000000E0: B2 F5 ; TimeDateStamp = 4E73B8B2
000000EE: 03 02 ; Characteristics = DLL|EXECUTABLE_IMAGE|32BIT_MACHINE|RELOCS_STRIPPED
000000F9: 36 44 ; SizeOfInitializedData = 3600 (13824.)
00000129: C0 D0 ; SizeOfImage = C000 (49152.)
00000179: 00 C0 ; Relocation Table address = 0
0000017C: 00 D4 ; Relocation Table size = 0
0000017D: 00 06 ; Relocation Table size = 0
00000248: 00 2E 00000248 2E 72 65 6C 6F 63 00 00 ; SECTION
00000249: 00 72
0000024A: 00 65
0000024B: 00 6C
0000024C: 00 6F
0000024D: 00 63
00000250: 00 22 00000250 220C0000 ; VirtualSize = C22 (3106.)
00000251: 00 0C
00000255: 00 C0 00000254 00C00000 ; VirtualAddress = C000
00000259: 00 0E 00000258 000E0000 ; SizeOfRawData = E00 (3584.)
0000025D: 00 92 0000025C 00920000 ; PointerToRawData = 9200
0000026C: 00 40 0000026C 40000042 ; Characteristics = INITIALIZED_DATA|DISCARDABLE|READ
0000026F: 00 42
000082B4: B2 F5 TimeDateStamp = 4E73B8B2 at IAT
FC: NOFIXED\ADDNUMBERS.DLL longer than FIXED\AddNumbers.dll
so if you have a running dll and dumped it
maybe before dumping it you can edit the peheader to strip relocations and make it load at preferred address only on which it was running at that moment
rendari
September 22nd, 2011, 21:44
I don't have time to write indepth post, but this is the tool you want:
http://tuts4you.com/download.php?view.419
Dump DLL once at one imagebase
Dump DLL again at different imagebase
Compare 2 dumps
Relox will generate .reloc section for you. Piece of cake

Nacho_dj
October 4th, 2011, 19:05
You have stated your dll is wrapped by PECompact, right?
Could I get a link to download your dll via PM, please?
Relocations are there but you cannot see them when you reach the OEP to dump your target, since the wrapper keeps them in a reduced way, to save size, different from a PE relocations section. But that .reloc section can be rebuilt from the wrapper itself.
Best regards
Nacho_dj
Darkelf
October 5th, 2011, 04:55
Hi,
first I'd like to thank everyone who responed to my question meanwhile.
Neither blabberer's approach nor the tool rendari proposed did it.

I played with the dump by hand a couple of times and got the beast running a bit further but it's still not perfect. My main problem seems to be Olly constantly crashing if I'll try to step the packed .dll to find that damn .reloc table.
@Nacho_dj
I've seen you played with a very similar file over there at Exetools. The difference between my .dll and the one over there is that mine is the retail not the demo. I don't want you to unpack the file for me. I'm sure that the dump is OK and the imports are restored correctly. But without a doubt I need a bit help with this reloc thingy. I'll drop you a PM so you can look at it if you are still interested. The thing I'm interested in is not the ready-made file but the howto!
Regards
darkelf
Nacho_dj
October 5th, 2011, 05:27
That's OK then, I remember that target, it has been wrapped with some security features of PECompact.
The "how-to" about retrieving imports & relocations from the wrapper itself will come as a tutorial together with an automatic tool to unpack any file wrapped by PECompact.
Best regards
Nacho_dj
Powered by vBulletin® Version 4.2.2 Copyright © 2020 vBulletin Solutions, Inc. All rights reserved.