From 2ef48597a17efabf4a9780caa99e1a7fe8d2e179 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 29 Sep 2019 07:58:51 +0200 Subject: [PATCH] Tools/Patcher: backported module download --- .../connection_patcher/Patches/Windows.hpp | 4 +- .../connection_patcher/Patterns/Windows.hpp | 12 +-- src/tools/connection_patcher/Program.cpp | 94 ++++++++++++++++++- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/src/tools/connection_patcher/Patches/Windows.hpp b/src/tools/connection_patcher/Patches/Windows.hpp index 7a975a8725f..31464d6fd51 100644 --- a/src/tools/connection_patcher/Patches/Windows.hpp +++ b/src/tools/connection_patcher/Patches/Windows.hpp @@ -36,9 +36,9 @@ namespace Connection_Patcher struct x64 { - static const std::vector BNet() { return { }; } + static const std::vector BNet() { return { 0xB8, 0xD5, 0xF8, 0x7F, 0x82, 0x89, 0x41, 0x0C, 0x48, 0x8B, 0xC1, 0xC3 }; } static const std::vector Password() { return { 0x75 }; } - static const std::vector Signature() { return { }; } + static const std::vector Signature() { return { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE9 }; } }; }; } diff --git a/src/tools/connection_patcher/Patterns/Windows.hpp b/src/tools/connection_patcher/Patterns/Windows.hpp index dfd1a177af1..024cdb2a0e7 100644 --- a/src/tools/connection_patcher/Patterns/Windows.hpp +++ b/src/tools/connection_patcher/Patterns/Windows.hpp @@ -29,16 +29,16 @@ namespace Connection_Patcher { struct x86 { - static const std::vector BNet() { return { }; } - static const std::vector Password() { return { }; } - static const std::vector Signature() { return { }; } + static const std::vector BNet() { return { 0x8B, 0x75, 0x08, 0x8D, 0x78, 0x0C }; } + static const std::vector Password() { return { 0x74, 0x89, 0x8B, 0x16, 0x8B, 0x42, 0x04 }; } + static const std::vector Signature() { return { 0xE8, 0x00, 0x00, 0x00, 0x00, 0x84, 0xC0, 0x75, 0x5F, 0x33, 0xC0 }; } }; struct x64 { - static const std::vector BNet() { return { }; } - static const std::vector Password() { return { }; } - static const std::vector Signature() { return { }; } + static const std::vector BNet() { return { 0x8B, 0x02, 0x89, 0x41, 0x0C, 0x48, 0x8B, 0xC1, 0xC3 }; } + static const std::vector Password() { return { 0x74, 0x84, 0x48, 0x8B, 0x03 }; } + static const std::vector Signature() { return { 0xE8, 0x00, 0x00, 0x00, 0x00, 0x84, 0xC0, 0x0F, 0x85, 0x88, 0x00, 0x00, 0x00, 0x45, 0x33, 0xC0 }; } }; }; } diff --git a/src/tools/connection_patcher/Program.cpp b/src/tools/connection_patcher/Program.cpp index 87803c381c2..fd7cdae17e0 100644 --- a/src/tools/connection_patcher/Program.cpp +++ b/src/tools/connection_patcher/Program.cpp @@ -32,13 +32,21 @@ #include #include +#include +#include #if PLATFORM == PLATFORM_WINDOWS #include #endif +using namespace boost::asio; +using boost::asio::ip::tcp; + namespace Connection_Patcher { + void copyDir(boost::filesystem::path const& source, boost::filesystem::path const& destination); + void GetFile(const std::string& serverName, int port, const std::string& getCommand, std::ostream& out); + namespace { template @@ -70,14 +78,24 @@ namespace Connection_Patcher } template - void do_module(std::string moduleName, boost::filesystem::path path) + void do_module(const std::string& moduleName, const boost::filesystem::path& path) { boost::filesystem::path const modulePath - (path / std::string(&moduleName[0], 2) / std::string(&moduleName[2], 2)); + (path / std::string(&moduleName[0], 2) / std::string(&moduleName[2], 2)); boost::filesystem::path const module(modulePath / moduleName); if (!boost::filesystem::exists(module)) - throw std::runtime_error("base module does not exist. run client once."); + { + std::cout << "Base module doesn't exist, downloading it...\n"; + + if (!boost::filesystem::exists(modulePath)) + boost::filesystem::create_directories(modulePath); + + std::ofstream outFile(module.string(), std::ofstream::out | std::ofstream::binary); + GetFile("xx.depot.battle.net", 1119, "/" + moduleName, outFile); + outFile.close(); + std::cout << "Done.\n"; + } PatchModule(module, path); } @@ -121,6 +139,73 @@ namespace Connection_Patcher fs::copy_file(current, destination / current.filename()); } } + + // adapted from http://stackoverflow.com/questions/21422094/boostasio-download-image-file-from-server + void GetFile(const std::string& serverName, int port, const std::string& getCommand, std::ostream& out) + { + io_context io_service; + boost::system::error_code error = boost::asio::error::host_not_found; + + // Get a list of endpoints corresponding to the server name. + tcp::resolver resolver(io_service); + tcp::resolver::results_type endpoints = resolver.resolve(serverName, std::to_string(port), error); + if (error) + throw std::runtime_error("Meh..."); + + // Try each endpoint until we successfully establish a connection. + error = boost::asio::error::host_not_found; + tcp::socket socket(io_service); + boost::asio::connect(socket, endpoints, error); + if (error) + throw std::runtime_error("Meh..."); + + boost::asio::streambuf request; + std::ostream request_stream(&request); + + request_stream << "GET " << getCommand << " HTTP/1.0\r\n"; + request_stream << "Host: " << serverName << ':' << port << "\r\n"; + request_stream << "Accept: */*\r\n"; + request_stream << "Connection: close\r\n\r\n"; + + // Send the request. + boost::asio::write(socket, request); + + // Read the response status line. + boost::asio::streambuf response; + boost::asio::read_until(socket, response, "\r\n"); + + // Check that response is OK. + std::istream response_stream(&response); + std::string http_version; + response_stream >> http_version; + unsigned int status_code; + response_stream >> status_code; + std::string status_message; + std::getline(response_stream, status_message); + + + // Read the response headers, which are terminated by a blank line. + boost::asio::read_until(socket, response, "\r\n\r\n"); + + // Process the response headers. + std::string header; + while (std::getline(response_stream, header) && header != "\r") + { + } + + // Write whatever content we already have to output. + if (response.size() > 0) + { + out << &response; + } + + // Read until EOF, writing data to output as we go. + while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)) + { + out << &response; + } + } + } int main(int argc, char** argv) @@ -186,7 +271,7 @@ int main(int argc, char** argv) do_patches (&patcher, renamed_binary_path); - do_module + do_module ("97eeb2e28e9e56ed6a22d09f44e2ff43c93315e006bbad43bafc0defaa6f50ae.auth" , "/Users/Shared/Blizzard/Battle.net/Cache/" ); @@ -197,6 +282,7 @@ int main(int argc, char** argv) } std::cout << "Successfully created your patched binaries.\n"; + std::cin.get(); return 0; }