During last year, the most common complaint on this blog was "your Molebox unpacker cannot unpack this crazy big EXE of MMORPG game X, Y or Z."
Sounds like an easy problem to fix, right? Well, that's not true - but I finally did it!
TL;DR:
In the rest of the post I'll describe the obstacles I had to overcome while solving this seemingly simple problem.
Delphi TMemoryStream limitation
First, unpacker is written using classic (non-.NET) Delphi and compiled as x86 executable. And standard Delphi streams are retarded. TMemoryStream uses GetMem - which ends up somewhere in Delphi memory manager and VirtualAlloc. That doesn't work well with 800+MB files.
I ended up with implementing custom stream backed by temporary file (CreateFile with FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE).
Pointer magic
Since the original unpacker was using TMemoryStream, the whole file was loaded in memory as a continuous memory block and I could easily read/write each byte of file using pointers. Something like this:
function Decode_Stage2(p: pdword; size: dword; key: dword): dword;
var
d: dword;
begin
result := 0;
d := 0;
while d < size do begin
key := key * $19660D + $3C6EF35F;
p^ := p^ xor key;
inc(p);
inc(d, 4);
end;
end;
...
Decode_Stage2(pointer(dword(f.fImage.Memory) + f.RVAToOffset(startAddress - f.NtHeader.OptionalHeader.ImageBase)), endAddress - startAddress, decryptionKey);
Guess what? Files don't work that way.. 🙁 I had to do a full and complete rewrite of all those methods.
Zlib conflicts
Original unpacker was compiled with Delphi 3. Delphi 3 didn't have Zlib library, so you had to supply your own Zlib implementation. But it won't compile with new versions of Delphi, giving error message
Unit Graphutil was compiled with a different version of zlib.TZDecompressionStream.
The solution was to get rid of my Zlib implementation and rewrite all methods that deal with decompression.
ANSI strings
In Delphi 3 all strings were ANSI. Starting from Delphi 20072009, strings are Unicode. Since Molebox internally uses ANSI, it required changing quite a few structure definitions and rewriting several string manipulation routines. It's a lot of fun (and source of the most obscure bugs), trust me!
Conclusion
I hope you find this unpacker useful. But if it doesn't work for you, please send me an error report with all the details you can and I'll try to fix it. Have fun!