mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Tools/Patcher: Properly sign certificate bundle
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
|
||||
#include "RSA.h"
|
||||
#include "BigNumber.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@@ -88,6 +90,13 @@ bool Trinity::Crypto::RSA::LoadFromString(std::string const& keyPem, KeyTag)
|
||||
return true;
|
||||
}
|
||||
|
||||
BigNumber Trinity::Crypto::RSA::GetModulus() const
|
||||
{
|
||||
BigNumber bn;
|
||||
BN_copy(bn.BN(), _rsa->n);
|
||||
return bn;
|
||||
}
|
||||
|
||||
template <typename KeyTag>
|
||||
bool Trinity::Crypto::RSA::Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, int32 paddingType)
|
||||
{
|
||||
@@ -97,6 +106,14 @@ bool Trinity::Crypto::RSA::Encrypt(uint8 const* data, std::size_t dataLength, ui
|
||||
return result != -1;
|
||||
}
|
||||
|
||||
bool Trinity::Crypto::RSA::Sign(int32 hashType, uint8 const* dataHash, std::size_t dataHashLength, uint8* output)
|
||||
{
|
||||
uint32 signatureLength = 0;
|
||||
int result = RSA_sign(hashType, dataHash, dataHashLength, output, &signatureLength, _rsa);
|
||||
std::reverse(output, output + GetOutputSize());
|
||||
return result != -1;
|
||||
}
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
namespace Crypto
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
*/
|
||||
|
||||
#include "Define.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
class BigNumber;
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
namespace Crypto
|
||||
@@ -27,11 +30,13 @@ namespace Crypto
|
||||
class TC_COMMON_API RSA
|
||||
{
|
||||
public:
|
||||
struct PublicKey {};
|
||||
struct PrivateKey {};
|
||||
|
||||
struct NoPadding : std::integral_constant<int32, RSA_NO_PADDING> {};
|
||||
struct PKCS1Padding : std::integral_constant<int32, RSA_PKCS1_PADDING> {};
|
||||
|
||||
struct PrivateKey {};
|
||||
struct PublicKey {};
|
||||
struct SHA256 : std::integral_constant<int32, NID_sha256> {};
|
||||
|
||||
RSA();
|
||||
RSA(RSA&& rsa);
|
||||
@@ -44,6 +49,7 @@ public:
|
||||
bool LoadFromString(std::string const& keyPem, KeyTag);
|
||||
|
||||
uint32 GetOutputSize() const { return uint32(RSA_size(_rsa)); }
|
||||
BigNumber GetModulus() const;
|
||||
|
||||
template <typename KeyTag, typename PaddingTag>
|
||||
bool Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, KeyTag, PaddingTag)
|
||||
@@ -51,10 +57,18 @@ public:
|
||||
return Encrypt<KeyTag>(data, dataLength, output, PaddingTag::value);
|
||||
}
|
||||
|
||||
template <typename HashTag>
|
||||
bool Sign(uint8 const* dataHash, std::size_t dataHashLength, uint8* output, HashTag)
|
||||
{
|
||||
return Sign(HashTag::value, dataHash, dataHashLength, output);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename KeyTag>
|
||||
bool Encrypt(uint8 const* data, std::size_t dataLength, uint8* output, int32 paddingType);
|
||||
|
||||
bool Sign(int32 hashType, uint8 const* dataHash, std::size_t dataHashLength, uint8* output);
|
||||
|
||||
RSA(RSA const& rsa) = delete;
|
||||
RSA& operator=(RSA const& rsa) = delete;
|
||||
|
||||
|
||||
@@ -226,33 +226,34 @@ uint8 const WorldPackets::Auth::ConnectTo::PiDigits[130] =
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIIEpAIBAAKCAQEA7rPc1NPDtFRRzmZbyzK48PeSU8YZ8gyFL4omqXpFn2DE683q\n"
|
||||
"f41Z2FeyYHsJTJtouMft7x6ADeZrN1tTkOsYEw1/Q2SD2pjmrMIwooKlxsvH+4af\n"
|
||||
"n6kCagNJxTj7wMhVzMDOJZG+hc/R0TfOzIPS6jCAB3uAn51EVCIpvoba20jFqfkT\n"
|
||||
"NpUjdvEO3IQNlAISqJfzOxTuqm+YBSdOH6Ngpana2BffM8viE1SLGLDKubuIZAbf\n"
|
||||
"dabXYQC7sFoOetR3CE0V4hCDsASqnot3qQaJXQhdD7gua8HLZM9uXNtPWGUIUfsN\n"
|
||||
"SBpvtj0fC93+Gx3wv7Ana/WOvMdAAf+nC4DWXwIDAQABAoIBACKa5q/gB2Y0Nyvi\n"
|
||||
"APrDXrZoXclRVd+WWxSaRaKaPE+vuryovI9DUbwgcpa0H5QAj70CFwdsd4oMVozO\n"
|
||||
"6519x56zfTiq8MaXFhIDkQNuR1Q7pMFdMfT2jogJ8/7olO7M3EtzxC8EIwfJKhTX\n"
|
||||
"r15M2h3jbBwplmsNZKOB1GVvrXjOm1KtOZ4CTTM0WrPaLVDT9ax8pykjmFw16vGP\n"
|
||||
"j/R5Dky9VpabtfZOu/AEW259XDEiQgTrB4Eg+S4GJjHqAzPZBmMy/xhlDK4oMXef\n"
|
||||
"qXScfD4w0RxuuCFr6lxLPZz0S35BK1kIWmIkuv+9eQuI4Hr1CyVwch4fkfvrp84x\n"
|
||||
"8tvAFnkCgYEA87NZaG9a8/Mob6GgY4BVLHJVOSzzFdNyMA+4LfSbtzgON2RSZyeD\n"
|
||||
"0JpDowwXssw5XOyUUctj2cLLdlMCpDfdzk4F/PEakloDJWpason3lmur0/5Oq3T9\n"
|
||||
"3+fnNUl4d3UOs1jcJ1yGQ/BfrTyRTcEoZx8Mu9mJ4ituVkKuLeG5vX0CgYEA+r/w\n"
|
||||
"QBJS6kDyQPj1k/SMClUhWhyADwDod03hHTQHc9BleJyjXmVy+/pWhN7aELhjgLbf\n"
|
||||
"o/Gm3aKJjCxS4qBmqUKwAvGoSVux1Bo2ZjcfF7sX9BXBOlFTG+bPVCZUoaksTyXN\n"
|
||||
"g7GsA1frKkWWkgQuOeK3o/p9IZoBl93vEgcTGgsCgYEAv5ucCIjFMllUybCCsrkM\n"
|
||||
"Ps4GQ9YbqmV9ulwhq8BPTlc8lkDCqWhgM3uXAnNXjrUTxQQd+dG4yFZoMrhBs2xZ\n"
|
||||
"cQPXoXDQO5GaN6jPduETUamGiD/DCvwJQCrNlxAVL5dR36FWN3x/9JriHwsoE8Jz\n"
|
||||
"SeEX2frIdpM/RYNX/6sipuECgYEA+rwFRDxOdvm8hGWuQ2WMxyQ7Nn07PEV/LxVM\n"
|
||||
"HkSRkyh23vVakyDEqty3uSOSUJfgv6ud07TnU8ac3fLQatdT8LrDgB4fVkN/fYU8\n"
|
||||
"kldaGwO1vxgl4OfDQCo7dXzisciViwtVBvQZ+jnm6J0vJBFUHAPt9+WZTIlQQIjm\n"
|
||||
"71LtseMCgYBSAhs6lshtz+ujR3fmc4QqJVGqeXvEBPAVm6yYoKYRLwVs/rFv3WLN\n"
|
||||
"LOwwBQ6lz7P9RqYYB5wVlaRvEhb9+lCve/xVcxMeZ5GkOBPxVygYV9l/wNdE25Nz\n"
|
||||
"OHYtKG3GK3GEcFDwZU2LPHq21EroUAdtRfbrJ4KW2yc8igtXKxTBYw==\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
std::string RSAPrivateKey = R"(-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA7rPc1NPDtFRRzmZbyzK48PeSU8YZ8gyFL4omqXpFn2DE683q
|
||||
f41Z2FeyYHsJTJtouMft7x6ADeZrN1tTkOsYEw1/Q2SD2pjmrMIwooKlxsvH+4af
|
||||
n6kCagNJxTj7wMhVzMDOJZG+hc/R0TfOzIPS6jCAB3uAn51EVCIpvoba20jFqfkT
|
||||
NpUjdvEO3IQNlAISqJfzOxTuqm+YBSdOH6Ngpana2BffM8viE1SLGLDKubuIZAbf
|
||||
dabXYQC7sFoOetR3CE0V4hCDsASqnot3qQaJXQhdD7gua8HLZM9uXNtPWGUIUfsN
|
||||
SBpvtj0fC93+Gx3wv7Ana/WOvMdAAf+nC4DWXwIDAQABAoIBACKa5q/gB2Y0Nyvi
|
||||
APrDXrZoXclRVd+WWxSaRaKaPE+vuryovI9DUbwgcpa0H5QAj70CFwdsd4oMVozO
|
||||
6519x56zfTiq8MaXFhIDkQNuR1Q7pMFdMfT2jogJ8/7olO7M3EtzxC8EIwfJKhTX
|
||||
r15M2h3jbBwplmsNZKOB1GVvrXjOm1KtOZ4CTTM0WrPaLVDT9ax8pykjmFw16vGP
|
||||
j/R5Dky9VpabtfZOu/AEW259XDEiQgTrB4Eg+S4GJjHqAzPZBmMy/xhlDK4oMXef
|
||||
qXScfD4w0RxuuCFr6lxLPZz0S35BK1kIWmIkuv+9eQuI4Hr1CyVwch4fkfvrp84x
|
||||
8tvAFnkCgYEA87NZaG9a8/Mob6GgY4BVLHJVOSzzFdNyMA+4LfSbtzgON2RSZyeD
|
||||
0JpDowwXssw5XOyUUctj2cLLdlMCpDfdzk4F/PEakloDJWpason3lmur0/5Oq3T9
|
||||
3+fnNUl4d3UOs1jcJ1yGQ/BfrTyRTcEoZx8Mu9mJ4ituVkKuLeG5vX0CgYEA+r/w
|
||||
QBJS6kDyQPj1k/SMClUhWhyADwDod03hHTQHc9BleJyjXmVy+/pWhN7aELhjgLbf
|
||||
o/Gm3aKJjCxS4qBmqUKwAvGoSVux1Bo2ZjcfF7sX9BXBOlFTG+bPVCZUoaksTyXN
|
||||
g7GsA1frKkWWkgQuOeK3o/p9IZoBl93vEgcTGgsCgYEAv5ucCIjFMllUybCCsrkM
|
||||
Ps4GQ9YbqmV9ulwhq8BPTlc8lkDCqWhgM3uXAnNXjrUTxQQd+dG4yFZoMrhBs2xZ
|
||||
cQPXoXDQO5GaN6jPduETUamGiD/DCvwJQCrNlxAVL5dR36FWN3x/9JriHwsoE8Jz
|
||||
SeEX2frIdpM/RYNX/6sipuECgYEA+rwFRDxOdvm8hGWuQ2WMxyQ7Nn07PEV/LxVM
|
||||
HkSRkyh23vVakyDEqty3uSOSUJfgv6ud07TnU8ac3fLQatdT8LrDgB4fVkN/fYU8
|
||||
kldaGwO1vxgl4OfDQCo7dXzisciViwtVBvQZ+jnm6J0vJBFUHAPt9+WZTIlQQIjm
|
||||
71LtseMCgYBSAhs6lshtz+ujR3fmc4QqJVGqeXvEBPAVm6yYoKYRLwVs/rFv3WLN
|
||||
LOwwBQ6lz7P9RqYYB5wVlaRvEhb9+lCve/xVcxMeZ5GkOBPxVygYV9l/wNdE25Nz
|
||||
OHYtKG3GK3GEcFDwZU2LPHq21EroUAdtRfbrJ4KW2yc8igtXKxTBYw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
)";
|
||||
|
||||
std::unique_ptr<Trinity::Crypto::RSA> ConnectToRSA;
|
||||
|
||||
|
||||
@@ -126,15 +126,6 @@ namespace Connection_Patcher
|
||||
return Constants::BinaryTypes(*reinterpret_cast<uint32_t const*>(data.data()));
|
||||
}
|
||||
|
||||
std::string GetFileChecksum(std::vector<unsigned char> const& data)
|
||||
{
|
||||
SHA256Hash h;
|
||||
h.UpdateData(data.data(), data.size());
|
||||
h.Finalize();
|
||||
|
||||
return ByteArrayToHexStr(h.GetDigest(), h.GetLength());
|
||||
}
|
||||
|
||||
std::set<size_t> SearchOffset(std::vector<unsigned char> const& binary, std::vector<unsigned char> const& pattern)
|
||||
{
|
||||
std::set<size_t> offsets;
|
||||
@@ -144,12 +135,6 @@ namespace Connection_Patcher
|
||||
|
||||
for (size_t j = 0; j < pattern.size(); j++)
|
||||
{
|
||||
if (pattern[j] == 0)
|
||||
{
|
||||
matches++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (binary[i + j] != pattern[j])
|
||||
break;
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace Connection_Patcher
|
||||
void CopyDir(boost::filesystem::path const & source, boost::filesystem::path const & destination);
|
||||
void DownloadFile(const std::string& serverName, int port, const std::string& getCommand, std::ostream& out);
|
||||
Constants::BinaryTypes GetBinaryType(std::vector<unsigned char> const& data);
|
||||
std::string GetFileChecksum(std::vector<unsigned char> const& data);
|
||||
std::set<size_t> SearchOffset(std::vector<unsigned char> const& binary, std::vector<unsigned char> const& pattern);
|
||||
uint32_t GetBuildNumber(std::vector<unsigned char> const& binary);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Connection_Patcher
|
||||
};
|
||||
}
|
||||
static std::string VersionsFile() { return "trinity6.github.io/%s/%s/build/versi"; };
|
||||
static std::vector<unsigned char> CertFileName() { return{ 't', 'c', '_', 'b', 'u', 'n', 'd', 'l', 'e', '.', 't', 'x', 't', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; }
|
||||
static std::vector<unsigned char> CertBundleUrl() { return { 'h', 't', 't', 'p', 's', ':', '/', '/', 't', 'r', 'i', 'n', 'i', 't', 'y', '6', '.', 'g', 'i', 't', 'h', 'u', 'b', '.', 'i', 'o', '/', 'B', 'n', 'e', 't', '/', 'z', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '/', 'c', 'l', 'i', 'e', 'n', 't', '/', 'b', 'g', 's', '-', 'k', 'e', 'y', '-', 'f', 'i', 'n', 'g', 'e', 'r', 'p', 'r', 'i', 'n', 't' }; }
|
||||
static std::string CertificateBundle()
|
||||
{
|
||||
return
|
||||
@@ -66,7 +66,39 @@ R"({
|
||||
"SigningCertificates": [
|
||||
{ "RawData": "-----BEGIN CERTIFICATE-----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-----END CERTIFICATE-----" }
|
||||
]
|
||||
}NGISerting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature_inserting_dummy_signature)";
|
||||
})";
|
||||
}
|
||||
static std::string CertificatePrivateKey()
|
||||
{
|
||||
return
|
||||
R"(-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAwN3EYmKhDGawGrh62wAgjh3wr4CcV6lp61Ev39jzTkgetXDB
|
||||
F2SWC9s/pzS/h10HQwL9P0cYlqbZHj/darOphcqplK05WsJC876lUASSeVWVPiHs
|
||||
mfpSzjx65qV2PfmcNE1SUEizOOfpaoxvLfVqh5y4MkuSxXxOXCXS9CnQBwQo8f/4
|
||||
uV6czHZgigi7CSID75VK3VhqvlTaLYFoEiOpjWNAQ7x/18sv+VoSVuX+alYez2PD
|
||||
wU+hl0CpzEIqtaavntce9sQ3uEd3eXYGAJp6X+bOVItRmUhb3WXoIXmHMaLe5oSc
|
||||
cINa17ZL7H2ISOqr/1Pfq84Ck/VStbzEfJdTZwIDAQABAoIBAHcu1DQERQd30a3B
|
||||
gNIi4vtPzzN1I6gcXgL3+cC3vasLcEapdflxxDNxeoVmWFFbEKi9iSf4VF6MnrFN
|
||||
wBM3ETRHh8IDxeSrFVqw3lFzcdyfIYnyxtZkVZVy1HQBne8wd/HuMkbAllg9IAYi
|
||||
4HWjKgDBvSX/g6Sca4QQL6uIxy/9s3Z4K2vU8KbvUpwo+ON4HMt61fgrIrbEUVCl
|
||||
TMCVEf8UphwHctmQJb/Pr0+BCTdiv04ga1dkt+ZyR2o0VN6T/zKDqk4m1sSl0GZz
|
||||
8sn63GbuTlwHcm9GgkaxoeeZJK1/sdOSIZN8W3PpnyHrAZJlNOY7G684F1mBaWV1
|
||||
PGCcVtkCgYEA8jCDTGub7ZyMk48x+8L3Devja3TQz7YNIGkVEbQBpNw4gDV8j1m6
|
||||
EgqFdzowkY+gbA76ylNfm6Aa66RDR/LbTbXlsNd8YkXcbU3xDQ96F6cS51VBkled
|
||||
hq+iAuGJB9VYN5yP1P/Oswg/AFMjOnsfBL/1zFo26364z9x8zazw0wsCgYEAy907
|
||||
mpkk59AQ4YIDSR9wK2YpXv6HoBPFld6m7PAnBWFO0uNtQ0YppbYbrhmDqrxUoFud
|
||||
ZiEHIa0gLlp9lHr+UdUAMPDlJ6gbMnJW3U5qiVuuZA13tiZFlv11qUeU1tQUzTUv
|
||||
ZoIISN15Im0PQzUFbTxSFbS+vTYjsedv1C9UOpUCgYEAkTaTUzvmV3cZNtSSFLFW
|
||||
ros0Zda56QDwJ/G5x06V+cJtQjpPwCf9kBms4ssKGgzzFDd7GdsZpVc/LPDlwnsU
|
||||
ESkyWnEpzEa1HvivwrP38bykcf5Ffbh45CvkyTNvlTnPVjDScNUcm24jUE+I/OSb
|
||||
uZ5bg7bH3TWzHDbIwg2iq/cCgYB+DPqvqoVhOAtYBBWX/vJSQ0bNT7/4QIFpG1RH
|
||||
KG5YK0SbrLeAYz+ZELKowWniBbSluj/mSAGq1usQ/i6rwijB3FvT5v8puA2o8X24
|
||||
NKY27BM2FgWxAJUCuREpa/Mhqdx6zanTTg9lTlt558kKGxyR4Dw445sUTwdfFuTU
|
||||
Y7dGyQKBgAG0vyOdfku9TlPX2a3LasM5jkbxljeTlCJUlahW7LSoQEmLoEhOM4Ja
|
||||
6CA5PADhA16pOUweKjOtSkNEcVEorFNjlH34PpnsysF+NsDBP5HEy0eYyHSYwg1Y
|
||||
7BGwQxUOoBaUKMu7jVQcffrKiWOGEXzBDSEZ3A30t7+JIS7qy1d1
|
||||
-----END RSA PRIVATE KEY-----
|
||||
)";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,18 +25,13 @@ namespace Connection_Patcher
|
||||
{
|
||||
namespace Patches
|
||||
{
|
||||
namespace Mac
|
||||
struct Mac
|
||||
{
|
||||
struct x64
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation()
|
||||
{
|
||||
static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x48, 0x8D, 0x55, 0xDC, 0x31, 0xDB, 0xB1, 0x01 }; }
|
||||
static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x45, 0x84, 0xFF, 0xB0, 0x01, 0xEB, 0x03, 0x44, 0x89 }; }
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation()
|
||||
{
|
||||
char const path[] = "org.trnity"; // not a typo, length must match original
|
||||
return std::vector<unsigned char>(std::begin(path), std::end(path));
|
||||
}
|
||||
};
|
||||
char const path[] = "org.trnity"; // not a typo, length must match original
|
||||
return std::vector<unsigned char>(std::begin(path), std::end(path));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,27 +25,13 @@ namespace Connection_Patcher
|
||||
{
|
||||
namespace Patches
|
||||
{
|
||||
namespace Windows
|
||||
struct Windows
|
||||
{
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation()
|
||||
{
|
||||
char const path[] = R"(Software\TrinityCore Developers\Battle.net\Launch Options\)";
|
||||
return std::vector<unsigned char>(std::begin(path), std::end(path));
|
||||
}
|
||||
|
||||
struct x86
|
||||
{
|
||||
static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x6A, 0x01 }; }
|
||||
static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x59, 0x59, 0x84, 0xC0, 0xEB }; }
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patches::Windows::LauncherLoginParametersLocation(); }
|
||||
};
|
||||
|
||||
struct x64
|
||||
{
|
||||
static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x41, 0xB1, 0x01 }; }
|
||||
static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0xEB }; }
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patches::Windows::LauncherLoginParametersLocation(); }
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,10 @@ namespace Connection_Patcher
|
||||
{
|
||||
static std::vector<unsigned char> Portal() { return { '.', 'a', 'c', 't', 'u', 'a' , 'l', '.', 'b', 'a', 't', 't', 'l', 'e', '.', 'n', 'e', 't', 0x00 }; }
|
||||
static std::vector<unsigned char> Modulus() { return { 0x91, 0xD5, 0x9B, 0xB7, 0xD4, 0xE1, 0x83, 0xA5 }; }
|
||||
static std::vector<unsigned char> BinaryVersion() { return{ 0x3C, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E }; }
|
||||
static std::vector<unsigned char> BinaryVersion() { return { 0x3C, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3E }; }
|
||||
static std::vector<unsigned char> VersionsFile() { return { '%', 's', '.', 'p', 'a', 't', 'c', 'h', '.', 'b', 'a', 't', 't', 'l', 'e', '.', 'n', 'e', 't', ':', '1', '1', '1', '9', '/', '%', 's', '/', 'v', 'e', 'r', 's', 'i', 'o', 'n', 's' }; }
|
||||
static std::vector<unsigned char> CertFileName() { return { 'c', 'a', '_', 'b', 'u', 'n', 'd', 'l', 'e', '.', 't', 'x', 't', '.', 's', 'i', 'g', 'n', 'e', 'd', 0x00 }; }
|
||||
static std::vector<unsigned char> CertBundleUrl() { return { 'h', 't', 't', 'p', ':', '/', '/', 'n', 'y', 'd', 'u', 's', '-', 'q', 'a', '.', 'w', 'e', 'b', '.', 'b', 'l', 'i', 'z', 'z', 'a', 'r', 'd', '.', 'n', 'e', 't', '/', 'B', 'n', 'e', 't', '/', 'z', 'x', 'x', '/', 'c', 'l', 'i', 'e', 'n', 't', '/', 'b', 'g', 's', '-', 'k', 'e', 'y', '-', 'f', 'i', 'n', 'g', 'e', 'r', 'p', 'r', 'i', 'n', 't' }; }
|
||||
static std::vector<unsigned char> CertSignatureModulus() { return { 0x85, 0xF3, 0x7B, 0x14, 0x5A, 0x9C, 0x48, 0xF6 }; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,18 +25,9 @@ namespace Connection_Patcher
|
||||
{
|
||||
namespace Patterns
|
||||
{
|
||||
namespace Mac
|
||||
struct Mac
|
||||
{
|
||||
struct x64
|
||||
{
|
||||
static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x48, 0x8D, 0x55, 0xDC, 0x31, 0xDB, 0x31, 0xC9 }; }
|
||||
static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x45, 0x84, 0xFF, 0xB0, 0x01, 0x75, 0x03, 0x44, 0x89 }; }
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation()
|
||||
{
|
||||
char const path[] = "net.battle";
|
||||
return std::vector<unsigned char>(std::begin(path), std::end(path));
|
||||
}
|
||||
};
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation() { return { 'n','e','t','.','b','a','t','t','l','e',0 }; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,27 +25,13 @@ namespace Connection_Patcher
|
||||
{
|
||||
namespace Patterns
|
||||
{
|
||||
namespace Windows
|
||||
struct Windows
|
||||
{
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation()
|
||||
{
|
||||
char const path[] = R"(Software\Blizzard Entertainment\Battle.net\Launch Options\)";
|
||||
return std::vector<unsigned char>(std::begin(path), std::end(path));
|
||||
}
|
||||
|
||||
struct x86
|
||||
{
|
||||
static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x6A, 0x00, 0x50, 0x8D, 0x45, 0xF8, 0x50, 0x68 }; }
|
||||
static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x59, 0x59, 0x84, 0xC0, 0x75, 0x08, 0x46, 0x83, 0xFE, 0x02 }; }
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patterns::Windows::LauncherLoginParametersLocation(); }
|
||||
};
|
||||
|
||||
struct x64
|
||||
{
|
||||
static std::vector<unsigned char> CertBundleCASCLocalFile() { return{ 0x45, 0x33, 0xC9, 0x48, 0x89, 0x9C, 0x24, 0x90, 0x02 }; }
|
||||
static std::vector<unsigned char> CertBundleSignatureCheck() { return{ 0x75, 0x0B, 0x48, 0xFF, 0xC7, 0x48, 0x83, 0xFF, 0x02 }; }
|
||||
static std::vector<unsigned char> LauncherLoginParametersLocation() { return ::Connection_Patcher::Patterns::Windows::LauncherLoginParametersLocation(); }
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
#include "Patterns/Windows.hpp"
|
||||
|
||||
#include "Banner.h"
|
||||
#include "CompilerDefs.h"
|
||||
#include "BigNumber.h"
|
||||
#include "RSA.h"
|
||||
#include "SHA256.h"
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
@@ -57,16 +59,14 @@ namespace Connection_Patcher
|
||||
patcher->Patch(Patches::Common::Modulus(), Patterns::Common::Modulus());
|
||||
|
||||
std::cout << "patching BNet certificate file location\n";
|
||||
// replace name of the file with certificates
|
||||
patcher->Patch(Patches::Common::CertFileName(), Patterns::Common::CertFileName());
|
||||
// replace certificate bundle url
|
||||
patcher->Patch(Patches::Common::CertBundleUrl(), Patterns::Common::CertBundleUrl());
|
||||
|
||||
std::cout << "patching BNet certificate file to load from local path instead of CASC\n";
|
||||
// force loading tc_bundle.txt from local directory instead of CASC
|
||||
patcher->Patch(PATCH::CertBundleCASCLocalFile(), PATTERN::CertBundleCASCLocalFile());
|
||||
|
||||
std::cout << "patching BNet certificate file signature check\n";
|
||||
// remove signature check from certificate bundle
|
||||
patcher->Patch(PATCH::CertBundleSignatureCheck(), PATTERN::CertBundleSignatureCheck());
|
||||
std::cout << "patching BNet certificate file signature\n";
|
||||
Trinity::Crypto::RSA rsa;
|
||||
rsa.LoadFromString(Patches::Common::CertificatePrivateKey(), Trinity::Crypto::RSA::PrivateKey{});
|
||||
std::unique_ptr<uint8[]> modulusArray = rsa.GetModulus().AsByteArray(256);
|
||||
patcher->Patch(std::vector<uint8>(modulusArray.get(), modulusArray.get() + 256), Patterns::Common::CertSignatureModulus());
|
||||
|
||||
std::cout << "patching Versions\n";
|
||||
// sever the connection to blizzard's versions file to stop it from updating and replace with custom version
|
||||
@@ -90,11 +90,27 @@ namespace Connection_Patcher
|
||||
|
||||
void WriteCertificateBundle(boost::filesystem::path const& dest)
|
||||
{
|
||||
if (!boost::filesystem::exists(dest.parent_path()) &&
|
||||
!boost::filesystem::create_directories(dest.parent_path()))
|
||||
throw std::runtime_error("could not create " + dest.parent_path().string());
|
||||
|
||||
std::ofstream ofs(dest.string(), std::ofstream::binary);
|
||||
if (!ofs)
|
||||
throw std::runtime_error("could not open " + dest.string());
|
||||
|
||||
ofs << std::noskipws << Patches::Common::CertificateBundle();
|
||||
ofs << std::noskipws << Patches::Common::CertificateBundle() << "NGIS";
|
||||
|
||||
SHA256Hash signatureHash;
|
||||
signatureHash.UpdateData(Patches::Common::CertificateBundle());
|
||||
signatureHash.UpdateData("Blizzard Certificate Bundle");
|
||||
signatureHash.Finalize();
|
||||
std::array<uint8, 256> signature;
|
||||
|
||||
Trinity::Crypto::RSA rsa;
|
||||
rsa.LoadFromString(Patches::Common::CertificatePrivateKey(), Trinity::Crypto::RSA::PrivateKey{});
|
||||
rsa.Sign(signatureHash.GetDigest(), signatureHash.GetLength(), signature.data(), Trinity::Crypto::RSA::SHA256{});
|
||||
|
||||
ofs.write(reinterpret_cast<char const*>(signature.data()), signature.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +165,23 @@ int main(int argc, char** argv)
|
||||
|
||||
std::string const binary_path(std::move(vm["path"].as<std::string>()));
|
||||
std::string renamed_binary_path(binary_path);
|
||||
std::wstring appDataPath;
|
||||
|
||||
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
|
||||
wchar_t* tempPath(nullptr);
|
||||
SHGetKnownFolderPath(FOLDERID_ProgramData, 0, NULL, &tempPath);
|
||||
appDataPath = std::wstring(tempPath);
|
||||
CoTaskMemFree(tempPath);
|
||||
#elif TRINITY_PLATFORM == TRINITY_PLATFORM_UNIX
|
||||
char* tempPath(nullptr);
|
||||
if ((tempPath = getenv("HOME")) == nullptr)
|
||||
tempPath = getpwuid(getuid())->pw_dir;
|
||||
std::string tempPathStr(tempPath);
|
||||
appDataPath.assign(tempPathStr.begin(), tempPathStr.end());
|
||||
appDataPath += std::wstring(L"/.wine/drive_c/users/Public/Application Data");
|
||||
#elif TRINITY_PLATFORM == TRINITY_PLATFORM_APPLE
|
||||
appDataPath = L"/Users/Shared";
|
||||
#endif
|
||||
std::cout << "Creating patched binary..." << std::endl;
|
||||
|
||||
Patcher patcher(binary_path);
|
||||
@@ -166,20 +198,13 @@ int main(int argc, char** argv)
|
||||
switch (patcher.GetType())
|
||||
{
|
||||
case Constants::BinaryTypes::Pe32:
|
||||
std::cout << "Win32 client...\n";
|
||||
|
||||
boost::algorithm::replace_all(renamed_binary_path, ".exe", "_Patched.exe");
|
||||
do_patches<Patches::Windows::x86, Patterns::Windows::x86>
|
||||
(&patcher, renamed_binary_path, wowBuild);
|
||||
WriteCertificateBundle(boost::filesystem::path(binary_path).remove_filename() / "tc_bundle.txt");
|
||||
break;
|
||||
case Constants::BinaryTypes::Pe64:
|
||||
std::cout << "Win64 client...\n";
|
||||
std::cout << (patcher.GetType() == Constants::BinaryTypes::Pe64 ? "Win64" : "Win32") << " client...\n";
|
||||
|
||||
boost::algorithm::replace_all(renamed_binary_path, ".exe", "_Patched.exe");
|
||||
do_patches<Patches::Windows::x64, Patterns::Windows::x64>
|
||||
do_patches<Patches::Windows, Patterns::Windows>
|
||||
(&patcher, renamed_binary_path, wowBuild);
|
||||
WriteCertificateBundle(boost::filesystem::path(binary_path).remove_filename() / "tc_bundle.txt");
|
||||
WriteCertificateBundle(boost::filesystem::path(appDataPath) / L"Blizzard Entertainment/Battle.net/Cache/web_cert_bundle");
|
||||
break;
|
||||
case Constants::BinaryTypes::Mach64:
|
||||
std::cout << "Mac client...\n";
|
||||
@@ -189,14 +214,14 @@ int main(int argc, char** argv)
|
||||
, boost::filesystem::path(renamed_binary_path).parent_path()/*MacOS*/.parent_path()/*Contents*/.parent_path()
|
||||
);
|
||||
|
||||
do_patches<Patches::Mac::x64, Patterns::Mac::x64>
|
||||
do_patches<Patches::Mac, Patterns::Mac>
|
||||
(&patcher, renamed_binary_path, wowBuild);
|
||||
|
||||
{
|
||||
namespace fs = boost::filesystem;
|
||||
fs::permissions(renamed_binary_path, fs::add_perms | fs::others_exe | fs::group_exe | fs::owner_exe);
|
||||
}
|
||||
WriteCertificateBundle(boost::filesystem::path(binary_path).parent_path()/*MacOS*/.parent_path()/*Contents*/.parent_path()/*World of Warcraft.app*/.parent_path() / "tc_bundle.txt");
|
||||
WriteCertificateBundle(boost::filesystem::path(appDataPath) / "Blizzard/Battle.net/Cache/web_cert_bundle");
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Type: " + std::to_string(static_cast<uint32_t>(patcher.GetType())) + " not supported!");
|
||||
|
||||
Reference in New Issue
Block a user