ladislav-zezula / StormLib

Official GitHub repository of the StormLib library created by Ladislav Zezula (author)
http://www.zezula.net/mpq.html
MIT License
560 stars 213 forks source link

Add support for highly-protected maps #12

Closed Profforgr closed 10 years ago

Profforgr commented 10 years ago

Hello.

Is it possible to add support to read all information about MPQ's (.w3x on my situation), which protected by some modern (not really, software to crypt available since a middle of 2012) ways?

Here's a link to such of this 'highly-protected' map. http://mvpro.net/share/github/Life_v2_7d.w3x

MPQ Editor crashes when tries to read this archive (even with listfiles). I guess It can not find 'war3map.w3i' (and also war3map.j and scripts\war3map.j in some cases) in MPQ archive, because some other MPQ explorers said this :)

From this .w3x StormLib can read only map_size and map_info. Other options is undetected.

Unfortunely i am not sure with which of utility this map protected. Very very stupid suggestion is modified Spuzzler :)

Sincerely,

Alex.

ladislav-zezula commented 10 years ago

In general, I want StormLib to support map protectors. Of course I am aware that the list of the protectors that it supports will never be complete, so when you encounter a map that cannot be open, I'll try to add a support for it.

Let me look at the map you provided and see what I can do :-)

Profforgr commented 10 years ago

In general, I want StormLib to support map protectors.

Of course I am aware that the list of the protectors that it supports will

never be complete, so when you encounter a map that cannot be open, I'll

try to add a support for it.

Yeah, i understand that :) I am not sure, but i see many map's, which can not be opened, with same error (and even with StormLib), so i guess it's rather popular protector. I also guess that some map developers uses some edited version of this tool, but i assume, all of these little modification is useless and it should be possible for StormLib to detect and deprotect all modification of this tool (i don't know the name, unfortunely).

Let me look at the map you provided and see what I can do :-)

It would be perfect, if you can investigate :) I'll wait :)

ladislav-zezula commented 10 years ago

I was looking into code that loads MPQs in Warcraft: The Frozen Throne. The code actually tests if the header size is at least 0x20. In the map you sent me, there is a fake header at offset 0x200 (header size is 0x02), then the real offset is at offset 0x600.

Nice trick :-)

I'll prepare the fix

Profforgr commented 10 years ago

I was looking into code that loads MPQs in Warcraft: The Frozen Throne. The code

actually tests if the header size is at least 0x20. In the map you sent me, there is a fake

header at offset 0x200 (header size is 0x02), then the real offset is at offset 0x600.

Nice trick :-)

I'll prepare the fix

Awesome. I'll review some other protected map's and sent to you if StormLib is not support them. I also want to add some tools to protect/deprotect these map's, which can maybe help you. Can you give me your E-Mail or can you e-mail me (admin@mvpro.net), so i can give these tools only to you, privately?

ladislav-zezula commented 10 years ago

Private message sent. Support for Spazzler protector added in commit 699180bf90ef4952dc7e0f57ce025f54424e30cd. Thank you for the protected map, keep them coming.

Profforgr commented 10 years ago

Support for Spazzler protector added in commit 699180b.

Thanks. But related this commit i have an issue. I compiled it with debug headers, installed for my app, run with gdb, and if the map is protected by spazzler (i tested on the map i send you, and other map's protected with same protector), after load the map (read archive) i have seg fault:

ghost++: src/SBaseFileTable.cpp:265: ULONGLONG DetermineArchiveSize_V1(TMPQArchive*, TMPQHeader*, ULONGLONG, ULONGLONG): Assertion `pHeader->wFormatVersion == 0' failed.

Program received signal SIGABRT, Aborted.
0xb7fe1416 in __kernel_vsyscall ()
(gdb) backtrace
#0  0xb7fe1416 in __kernel_vsyscall ()
#1  0xb785f941 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0xb7862d72 in *__GI_abort () at abort.c:92
#3  0xb7858b58 in *__GI___assert_fail (assertion=0xb7f76284 "pHeader->wFormatVersion == 0", file=0xb7f76220 "src/SBaseFileTable.cpp", line=265,
    function=0xb7f76f20 "ULONGLONG DetermineArchiveSize_V1(TMPQArchive*, TMPQHeader*, ULONGLONG, ULONGLONG)") at assert.c:81
#4  0xb7f2d0e0 in DetermineArchiveSize_V1(_TMPQArchive*, _TMPQHeader*, unsigned long long, unsigned long long) () from /usr/local/lib/libStorm.so
#5  0xb7f2d485 in ConvertMpqHeaderToFormat4(_TMPQArchive*, unsigned long long, unsigned long long, unsigned int) () from /usr/local/lib/libStorm.so
#6  0xb7f3c93f in SFileOpenArchive () from /usr/local/lib/libStorm.so
#7  0x0811cc92 in CMap::Load (this=0xb3e018c8, CFG=0xbfffe45c, nCFGFile=<error reading variable: Cannot access memory at address 0x0>) at map.cpp:249
#8  0x0805b66e in CBNET::BotCommand (this=this@entry=0x81b0ac8, Message=..., User=..., Whisper=Whisper@entry=true, ForceRoot=ForceRoot@entry=false)
    at bnet.cpp:1965
#9  0x0805e153 in CBNET::BotCommand (this=0x81b0ac8, Message=..., User=..., Whisper=true, ForceRoot=false) at bnet.cpp:2190
#10 0x08061558 in CBNET::ProcessChatEvent (this=0x81b0ac8, chatEvent=0xbfffeb68) at bnet.cpp:1141
#11 0x08065b4b in CBNET::ProcessPackets (this=this@entry=0x81b0ac8) at bnet.cpp:824
#12 0x0806a920 in CBNET::Update (this=0x81b0ac8, fd=0xbffff4d0, send_fd=0xbffff550) at bnet.cpp:550
#13 0x080d0ec0 in CGHost::Update (this=0x818aa38, usecBlock=50000) at ghost.cpp:1047
#14 0x08051686 in main (argc=1, argv=0xbffff754) at ghost.cpp:424
ladislav-zezula commented 10 years ago

Try the following commit: 48dbf357a334725059dd7ab12c4af041417e4dc4. The assert should be fixed.

Profforgr commented 10 years ago

Try the following commit: 48dbf35. The assert should be fixed.

Unfortunely the error persists. I tried few times of reinstalling (rm directory && git clone) and i am sure i am using last vesion from repo.

ghost++_i386: src/SBaseFileTable.cpp:265: ULONGLONG DetermineArchiveSize_V1(TMPQArchive*, TMPQHeader*, ULONGLONG, ULONGLONG): Assertion `pHeader->wFormatVersion == 0' failed.

Program received signal SIGABRT, Aborted.
0xb7fe1416 in __kernel_vsyscall ()
(gdb) backtrace
#0  0xb7fe1416 in __kernel_vsyscall ()
#1  0xb785f941 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0xb7862d72 in *__GI_abort () at abort.c:92
#3  0xb7858b58 in *__GI___assert_fail (assertion=0xb7f763a4 "pHeader->wFormatVersion == 0", file=0xb7f76340 "src/SBaseFileTable.cpp", line=265,
    function=0xb7f77040 "ULONGLONG DetermineArchiveSize_V1(TMPQArchive*, TMPQHeader*, ULONGLONG, ULONGLONG)") at assert.c:81
#4  0xb7f2d0e0 in DetermineArchiveSize_V1(_TMPQArchive*, _TMPQHeader*, unsigned long long, unsigned long long) () from /usr/local/lib/libStorm.so
#5  0xb7f2d485 in ConvertMpqHeaderToFormat4(_TMPQArchive*, unsigned long long, unsigned long long, unsigned int) () from /usr/local/lib/libStorm.so
#6  0xb7f3ca53 in SFileOpenArchive () from /usr/local/lib/libStorm.so
#7  0x0811cc92 in CMap::Load (this=0xb4002fb0, CFG=0xbfffe45c, nCFGFile=<error reading variable: Cannot access memory at address 0x0>) at map.cpp:249
#8  0x0805b66e in CBNET::BotCommand (this=this@entry=0x81b0ac8, Message=..., User=..., Whisper=Whisper@entry=true, ForceRoot=ForceRoot@entry=false)
    at bnet.cpp:1965
#9  0x0805e153 in CBNET::BotCommand (this=0x81b0ac8, Message=..., User=..., Whisper=true, ForceRoot=false) at bnet.cpp:2190
#10 0x08061558 in CBNET::ProcessChatEvent (this=0x81b0ac8, chatEvent=0xbfffeb68) at bnet.cpp:1141
#11 0x08065b4b in CBNET::ProcessPackets (this=this@entry=0x81b0ac8) at bnet.cpp:824
#12 0x0806a920 in CBNET::Update (this=0x81b0ac8, fd=0xbffff4d0, send_fd=0xbffff550) at bnet.cpp:550
#13 0x080d0ec0 in CGHost::Update (this=0x818aa38, usecBlock=50000) at ghost.cpp:1047
#14 0x08051686 in main (argc=1, argv=0xbffff754) at ghost.cpp:424
ladislav-zezula commented 10 years ago

Re[2]: [StormLib] Add support for highly-protected maps (#12)

I can't see how this could happen. The function DetermineArchiveSize_V1 is only called from one place, and all paths leading to it are only if the format is 0x00 (MPQ_V1).

This is the stack trace I get for 32-bit testprogram, when the program is stopped at the ASSERT. The opened MPQ is Life_v2_7d.w3x, which you sent me.

StormLib_test.exe!SFileOpenArchive(const wchar_t * szMpqName=0x0018f7a4, unsigned long dwPriority=0x00000000, unsigned long dwFlags=0x00000100, void * * phMpq=0x0018f9b4) StormLib_test.exe!OpenExistingArchive(TLogHelper * pLogger=0x0018fe18, const char * szFullPath=0x0018fab4, unsigned long dwFlags=0x00000100, void * * phMpq=0x0018fe00) StormLib_test.exe!OpenExistingArchiveWithCopy(TLogHelper * pLogger=0x0018fe18, const char * szFileName=0x00586d58, const char * szCopyName=0x00000000, void * * phMpq=0x0018fe00) StormLib_test.exe!TestOpenArchive(const char * szPlainName=0x00586d58, const char * szListFile=0x00000000) StormLib_test.exe!main(int argc=0x00000001, char * * argv=0x06e47fa8)

ladislav-zezula commented 10 years ago

Fixed in commit 45d0dfbb815c5cf1177a0e4f4e6ee5677cdff237.