Closed HarpyWar closed 8 years ago
This can be tested with the latest commit (https://github.com/HarpyWar/pvpgn/commit/10650635614a1249726ed02627cccaa094fe1bb4).
lua/handle_user.lua
to send SID_REQUIREDWORK when user login:--api.client_requiredwork(account.name, "IX86ExtraWork.mpq")
lua/handle_client.lua
can be uncommented to handle SID_EXTRAWORK from a client (not necessary, because the same log event is in c++ code):--DEBUG(string.format("Received EXTRAWORK packet with GameType: %d and Length: %d (%s)", gametype, length, data))
bnetd::file_send: [656] sending file "IX86ExtraWork.mpq" ("files/IX86ExtraWork.mpq") of length 3602
or another line if the file was cached in bncache.dat
:
bnetd::_client_fileinforeq: [656] file requested: "IX86ExtraWork.mpq" - type = 0x80000006
The client won't load the dll because it requires the mpq file to be signed.
I can't find original IX86ExtraWork.mpq
nowhere to at least test a response. This file is not more stored in official Battle.net servers.
Well, may be someone will find the way to bypass or make a sign, it will be a ready tutorial.
A bypass will require client modifications and creating the signature will require a certain private RSA key. I'm not able to find the original file too
Yes, I think it is possible to disable signature check (or add own) using game loader or a launcher. For instance, Warcraft 3 and Diablo 2 don't work without a loader, and w3l.exe sources are public.
Addition that can be interesting. I found this chunk in Starcraft bncache.dat
while testing:
0000E628 00 00 EE 23 00 00 00 00 53 59 53 44 45 53 43 2E 64 6C 6C 00 45 78 74 72 î# SYSDESC.dll Extr
0000E640 61 57 6F 72 6B 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 45 52 aWork ER
0000E658 52 3A 20 44 69 72 65 63 74 44 72 61 77 43 72 65 61 74 65 20 66 61 69 6C R: DirectDrawCreate fail
0000E670 65 64 0A 00 00 00 45 52 52 3A 20 51 75 65 72 79 49 6E 74 65 72 66 61 63 ed ERR: QueryInterfac
0000E688 65 20 66 61 69 6C 65 64 0A 00 45 52 52 3A 20 47 65 74 44 65 76 69 63 65 e failed ERR: GetDevice
0000E6A0 49 64 65 6E 74 69 66 69 65 72 20 66 61 69 6C 65 64 0A 00 00 00 00 56 69 Identifier failed Vi
0000E6B8 64 25 64 3A 20 56 65 6E 64 6F 72 20 25 30 38 78 20 44 65 76 69 63 65 20 d%d: Vendor %08x Device
0000E6D0 25 30 38 78 20 22 25 73 22 0A 00 00 00 00 3F 00 00 00 41 75 64 25 64 3A %08x "%s" ? Aud%d:
0000E6E8 20 4D 6F 64 75 6C 65 20 22 25 73 22 20 44 65 76 69 63 65 20 22 25 73 22 Module "%s" Device "%s"
0000E700 0A 00 45 52 52 3A 20 52 65 67 4F 70 65 6E 4B 65 79 45 78 20 66 61 69 6C ERR: RegOpenKeyEx fail
0000E718 65 64 0A 00 00 00 45 52 52 3A 20 52 65 67 51 75 65 72 79 56 61 6C 75 65 ed ERR: RegQueryValue
0000E730 45 78 20 66 61 69 6C 65 64 0A 00 00 00 00 45 52 52 3A 20 52 65 67 51 75 Ex failed ERR: RegQu
0000E748 65 72 79 56 61 6C 75 65 45 78 20 72 65 74 75 72 6E 65 64 20 61 6E 20 75 eryValueEx returned an u
0000E760 6E 65 78 70 65 63 74 65 64 20 74 79 70 65 20 25 64 0A 00 00 00 00 44 58 nexpected type %d DX
0000E778 3A 20 20 20 25 73 0A 00 00 00 56 65 72 73 69 6F 6E 00 53 4F 46 54 57 41 : %s Version SOFTWA
0000E790 52 45 5C 4D 69 63 72 6F 73 6F 66 74 5C 44 69 72 65 63 74 58 00 00 45 52 RE\Microsoft\DirectX ER
0000E7A8 52 3A 20 47 65 74 56 65 72 73 69 6F 6E 45 78 20 66 61 69 6C 65 64 0A 00 R: GetVersionEx failed
0000E7C0 00 00 57 69 6E 4E 54 00 00 00 4F 53 3A 20 20 20 25 73 20 25 64 2E 25 64 WinNT OS: %s %d.%d
0000E7D8 20 22 25 73 22 20 42 75 69 6C 64 20 25 64 0A 00 00 00 57 69 6E 39 78 00 "%s" Build %d Win9x
0000E7F0 00 00 52 41 4D 3A 20 20 25 64 20 4D 42 0A 00 00 00 00 00 00 00 00 43 50 RAM: %d MB CP
0000E808 55 3A 20 20 25 73 20 54 79 70 65 20 25 58 20 46 61 6D 69 6C 79 20 25 58 U: %s Type %X Family %X
0000E820 20 4D 6F 64 65 6C 20 25 58 20 53 74 65 70 70 69 6E 67 20 25 58 20 42 72 Model %X Stepping %X Br
0000E838 61 6E 64 20 25 58 20 25 64 20 4D 48 7A 0A 00 00 00 00 47 61 6D 65 3A 20 and %X %d MHz Game:
0000E850 25 73 0A 00 00 00 55 6E 6B 6E 6F 77 6E 00 57 6F 72 6C 64 4F 66 57 61 72 %s Unknown WorldOfWar
0000E868 63 72 61 66 74 00 57 61 72 63 72 61 66 74 33 00 00 00 44 69 61 62 6C 6F craft Warcraft3 Diablo
0000E880 32 00 53 74 61 72 63 72 61 66 74 00 00 00 53 79 73 44 65 73 63 00 53 4F 2 Starcraft SysDesc SO
0000E898 46 54 57 41 52 45 5C 42 61 74 74 6C 65 2E 6E 65 74 5C 4F 70 74 69 6D 69 FTWARE\Battle.net\Optimi
0000E8B0 7A 65 00 00 00 00 45 52 52 3A 20 4C 65 6E 67 74 68 20 25 64 0A 00 45 52 ze ERR: Length %d ER
0000E8C8 52 3A 20 54 79 70 65 20 25 64 0A 00 00 00 53 79 73 74 65 6D 20 44 65 62 R: Type %d System Deb
0000E8E0 75 67 20 49 6E 66 6F 20 25 64 2E 25 30 32 64 0A 00 00 00 00 00 00 47 65 ug Info %d.%02d Ge
0000E8F8 6E 75 69 6E 65 54 4D 78 38 36 00 00 00 00 43 65 6E 74 61 75 72 48 61 75 nuineTMx86 CentaurHau
0000E910 6C 73 00 00 00 00 43 79 72 69 78 49 6E 73 74 65 61 64 00 00 00 00 41 75 ls CyrixInstead Au
0000E928 74 68 65 6E 74 69 63 41 4D 44 00 00 00 00 47 65 6E 75 69 6E 65 49 6E 74 thenticAMD GenuineInt
0000E940 65 6C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 el
It may mean that gametype enumeration sequence is wrong on bnetdocs. It should be:
0x01: Starcraft
0x02: Diablo II
0x03: Warcraft III
0x04: World of Warcraft
You can create weak signature now by using the private key.
I've commited this: https://github.com/tesseract2048/StormLib
@tesseract2048 could you please give a simple example how to sign MPQ using StormLib?
Judging by the commit, you call SFileAllocateWeakSignature(HANDLE hMpq), reopen archive and then SFileSignArchiveWeak(HANDLE hMpq)
Thank you @tesseract2048 for informing us, I was about to put together some resources to crack the private key(which would probably take months).
Actually you can get it done within a week in a small cluster (~300 cores) with CADO-NFS.
I don't have that much resources available to use so it would have been months for me
@tesseract2048 can be maps from Starcraft or Warcraft 3 signed using the same way?
And I want to clarify yuor information. What is the key that you provide here, can it be used to sign MPQ, or we still need a cluster to find working key? I'm not familiar with program CADO-NFS, but may be someone have an access to a university super computer to get this job done faster.
@HarpyWar About signing maps, it depends. I'm almost sure that you can sign StarCraft maps with this but I think WarCraft 3 uses the Blizzard Strong Digital Signature RSA private/public key pair for more security. I'm going to guess that WarCraft 3 will accept the Blizzard Weak Digital Signature for the ExtraWork module(or else Blizzard would have to make a second copy of the mpq file and sign it every time they want to turn on ExtraWork). If that is true, just send a dll to disable signature verification checks. @tesseract2048 has already provided the Blizzard Weak Digital Signature private key so we don't need to use a cluster to factor it.
@HarpyWar Sorry I am not sure about map signing issues. The private key i provided is against what I uncovered in Storm.dll (Diablo II 1.11b), so yes it works with MPQs in Diablo II (including ExtraWork and VersionCheck). Sure you can use it with every Diablo II anti-cheating features (Warden depends, for it is complicated so i didn't invest time on testing it). But Warcraft III and other games are not verified yet (since I no longer work with games). As far as I know, signing War3 maps require a strong signature, which is much harder to factor (or say impossible so far).
I do think @xboi209 's approach is a good one, suppose you can send signed extra work / version check modules to disable map signing verification inside client.
BTW i think it's a good idea to integrate this feature with PvPGN, for example PvPGN can automatically sign these modules and send it to client, with only raw DLLs are provided manually.
@tesseract2048 That'd be a great feature to have, we just need to make sure that the signing and mpq manipulation is cross compatible between operating systems
Great! I'm not sure that it should be added into PvPGN, because it is not a server's function. It's better to sign MPQ using standalone exe program that can be runned after compile DLL on a developer's machine, automatically (using post-build IDE features) or manually.
Can someone write the console program with two usages depending on file extension:
app.exe file.dll key.ppk
(pack file into file.mpq
and sign with key.ppk
)
app.exe file.mpq key.ppk
(sign mpq with key.ppk
)
I've checked that StarCraft and WarCraft 3 maps are signed using Blizzard Strong Digital Signature key. We won't be able to sign custom maps. Also, we don't need .ppk files because the Blizzard Weak Digital Signature implenentation is very specific and that implementation only has this one public/private key pair so it's fine to hardcode it.
@tesseract2048 Is it normal for the (listfile) to be deleted when signing a mpq file?
TODO: -Universal IX86 CheckRevision mpq -Disable RSA verification via ExtraWork mpq(for all games)
@xboi209 I think (listfile) should be deleted by all means, for client does not require it.
https://github.com/HarpyWar/pvpgn/blob/master/src/bnetd/handle_bnet.cpp#L5393 The if statement on line 5393 should not be satisfied
@xboi209 It works fine with Warcraft 3 - data from DLL is correctly returned to a server! But I still getting error with a crash in Starcraft and also in Diablo 2 on Windows 8.1 / Windows 7 (with or withour admin rights). The client's crash occurred when calling DLL ExtraWork function, before sending data to a server.
I just compiled your ExtraWork DLL template and sign it with MPQSigner, then replace the result MPQ file in my server files directory.
That's strange, I recompiled the code and I got the same error which didn't happen before. Even more strange is that it only works on WarCraft 3.
Any news how to suppress that error?
No, I don't know the cause of the error but I tried removing all the unnecessary code in the function and the client still crashes, so knowing the return value of LoadLibrary should help. We'll need someone to hook the LoadLibrary function to tell us the return value before the client crashes.
Is that relevant to differences between versions of battle.net client library?
@tesseract2048 the same error occured in Starcraft and Diablo 2 with official DLL from Battle.net, that I found in the internet (link in the first message of the topic). But I can't find original MPQ - only DLL, then it was signed with your library using MPQSigner.
ExtraWork.cpp
#include <Windows.h>
__declspec(dllexport) BOOL __fastcall ExtraWork(void *) {
MessageBoxA(NULL, "it worked", NULL, MB_OK);
return FALSE;
}
ExtraWork.def
LIBRARY
ExtraWork
EXPORTS
ExtraWork
Code above worked for me, to be more specific:
dllexport
should be specified, and should be forced to have that name by defining in ExtraWork.def
__fastcall
should be used.So __declspec(dllexport)
was missing from my code, everything is good now.
Here is a wild idea: can this packet be pushed in the connecting to server stage and make W3 patch itself instead of using w3lh loader?
That might actually be possible. Client will start the logon sequence using SID_AUTHINFO and instead of immediately replying back to that packet, we could try sending ExtraWork to disable server signature verification before replying.
If someone has time, try to push AlertBox before the logon sequence and see what happens.
For what purpose?
I guess to see if the game accepts packets out of the blue like this.
I have added conn_client_requiredwork(c, "IX86ExtraWork.mpq");
in handle_init.cpp line 74 which should be asap after successful connection, placed the above provided IX86ExtraWork.mpq to ./var/files but nothing happened. Am I doing something wrong?
I don't think that's an acceptable place to put it(for clean code). I would suggest placing it in handle_bnet.cpp
at line 568. This is still bad code because ideally we should confirm that the client completely downloaded the file before the server moves on with the connection process.
Check your bncache.dat file to see if your client downloaded IX86ExtraWork.mpq.
This is just for testing purpose so position is far from final. I'll check it out.
Ok, I tried to put it where you recommended but EXTRAWORK is never sent from the client. Then I tried to put it on channel join just for a sanity check and it worked:
Apr 19 10:20:22 [info ] pvpgn::bnetd::_client_fileinforeq: [600] file requested: "IX86ExtraWork.mpq" - type = 0xa0000006
Apr 19 10:20:22 [debug] pvpgn::bnetd::_client_extrawork: [600] Received EXTRAWORK packet with GameType: 2 and Length: 29 (IX86ExtraWork v1.0 by xboi209)
It seems that client does not react to REQUIREWORK in early stage but more testing is probably needed.
After sending server → client SID_REQUIREDWORD packet, client should download mpq file and then call
ExtraWork
function from dll inside of mpq, with sending output from the function back from client → server SID_EXTRAWORK.I found two different versions of
IX86ExtraWork.dll
from official Battle.net and add one of them intoIX86ExtraWork.mpq
using MpqEditor. This file correctly received by a game client (I tried DIablo 2, Warcraft3 and Starcraft), but then nothing happened (no response from the client).I even create own dll that shows messagebox, but it doesn't work too. You can try it by yourself ExtraWorkTest.zip Code for ExtraWork.exe was taken from here: