Some demonware fixes
This commit is contained in:
parent
f6eebe2471
commit
1e8f93e6ea
@ -20,6 +20,10 @@ namespace console
|
|||||||
|
|
||||||
void print_message(const char* message)
|
void print_message(const char* message)
|
||||||
{
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
OutputDebugStringA(message);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (started && !terminate_runner)
|
if (started && !terminate_runner)
|
||||||
{
|
{
|
||||||
game::Com_Printf(0, 0, "%s", message);
|
game::Com_Printf(0, 0, "%s", message);
|
||||||
|
@ -18,12 +18,13 @@ namespace demonware
|
|||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
volatile bool exit_server;
|
std::atomic_bool exit_server{false};
|
||||||
std::thread server_thread;
|
std::thread server_thread{};
|
||||||
utils::concurrency::container<std::unordered_map<SOCKET, bool>> blocking_sockets;
|
utils::concurrency::container<std::unordered_map<SOCKET, bool>> blocking_sockets{};
|
||||||
utils::concurrency::container<std::unordered_map<SOCKET, tcp_server*>> socket_map;
|
utils::concurrency::container<std::unordered_map<SOCKET, tcp_server*>> socket_map{};
|
||||||
server_registry<tcp_server> tcp_servers;
|
server_registry<tcp_server> tcp_servers{};
|
||||||
server_registry<udp_server> udp_servers;
|
server_registry<udp_server> udp_servers{};
|
||||||
|
std::unordered_map<void*, void*> original_imports{};
|
||||||
|
|
||||||
tcp_server* find_server(const SOCKET socket)
|
tcp_server* find_server(const SOCKET socket)
|
||||||
{
|
{
|
||||||
@ -118,7 +119,7 @@ namespace demonware
|
|||||||
int getaddrinfo_stub(const char* name, const char* service,
|
int getaddrinfo_stub(const char* name, const char* service,
|
||||||
const addrinfo* hints, addrinfo** res)
|
const addrinfo* hints, addrinfo** res)
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[ network ]: [getaddrinfo]: \"%s\" \"%s\"\n", name, service);
|
printf("[ network ]: [getaddrinfo]: \"%s\" \"%s\"\n", name, service);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ namespace demonware
|
|||||||
|
|
||||||
hostent* gethostbyname_stub(const char* name)
|
hostent* gethostbyname_stub(const char* name)
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[ network ]: [gethostbyname]: \"%s\"\n", name);
|
printf("[ network ]: [gethostbyname]: \"%s\"\n", name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -424,63 +425,6 @@ namespace demonware
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bd_logger_stub()
|
|
||||||
{
|
|
||||||
//printf("logged\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
|
||||||
void a(unsigned int n)
|
|
||||||
{
|
|
||||||
printf("bdAuth: Auth task failed with HTTP code [%u]\n", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void b(unsigned int n)
|
|
||||||
{
|
|
||||||
printf("bdAuth: Decoded client ticket of unexpected size [%u]\n", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void c(unsigned int n)
|
|
||||||
{
|
|
||||||
printf("bdAuth: Decoded server ticket of unexpected size [%u]\n", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void d()
|
|
||||||
{
|
|
||||||
printf("bdAuth: Auth ticket magic number mismatch\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void e()
|
|
||||||
{
|
|
||||||
printf("bdAuth: Cross Authentication completed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void f()
|
|
||||||
{
|
|
||||||
printf("bdAuth: Auth task reply contains invalid data / format\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void g(unsigned int n)
|
|
||||||
{
|
|
||||||
printf("bdAuth: Auth task returned with error code [%u]\n", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void h(unsigned int n)
|
|
||||||
{
|
|
||||||
printf("bdAuth: Invalid or No Task ID [%u] in Auth reply\n", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void i()
|
|
||||||
{
|
|
||||||
printf("bdAuth: Received reply from DemonWare Auth server\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void l()
|
|
||||||
{
|
|
||||||
printf("bdAuth: Unknown error\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
utils::hook::detour handle_auth_reply_hook;
|
utils::hook::detour handle_auth_reply_hook;
|
||||||
|
|
||||||
bool handle_auth_reply_stub(void* a1, void* a2, void* a3)
|
bool handle_auth_reply_stub(void* a1, void* a2, void* a3)
|
||||||
@ -503,14 +447,16 @@ namespace demonware
|
|||||||
{
|
{
|
||||||
const utils::nt::library game_module{};
|
const utils::nt::library game_module{};
|
||||||
|
|
||||||
auto result = false;
|
std::optional<std::pair<void*, void*>> result{};
|
||||||
result = result || utils::hook::iat(game_module, "wsock32.dll", process, stub);
|
if(!result) result = utils::hook::iat(game_module, "wsock32.dll", process, stub);
|
||||||
result = result || utils::hook::iat(game_module, "WS2_32.dll", process, stub);
|
if(!result) result = utils::hook::iat(game_module, "WS2_32.dll", process, stub);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to hook: " + process);
|
throw std::runtime_error("Failed to hook: " + process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
original_imports[result->first] = result->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,9 +492,9 @@ namespace demonware
|
|||||||
register_hook("getpeername", io::getpeername_stub);
|
register_hook("getpeername", io::getpeername_stub);
|
||||||
register_hook("getsockname", io::getsockname_stub);
|
register_hook("getsockname", io::getsockname_stub);
|
||||||
|
|
||||||
//utils::hook::set<uint8_t>(0x7C0AD9_b, 0x0); // CURLOPT_SSL_VERIFYPEER
|
utils::hook::set<uint8_t>(0x14293E829_g, 0x0); // CURLOPT_SSL_VERIFYPEER
|
||||||
//utils::hook::set<uint8_t>(0x7C0AC5_b, 0xAF); // CURLOPT_SSL_VERIFYHOST
|
utils::hook::set<uint8_t>(0x15F3CCFED_g, 0xAF); // CURLOPT_SSL_VERIFYHOST
|
||||||
//utils::hook::set<uint8_t>(0xA1327C_b, 0x0); // HTTPS -> HTTP
|
utils::hook::set<uint8_t>(0x1430B9810_g, 0x0); // HTTPS -> HTTP
|
||||||
|
|
||||||
utils::hook::copy_string(0x1430B96E0_g, "http://prod.umbrella.demonware.net");
|
utils::hook::copy_string(0x1430B96E0_g, "http://prod.umbrella.demonware.net");
|
||||||
utils::hook::copy_string(0x1430B9BE0_g, "http://prod.uno.demonware.net/v1.0");
|
utils::hook::copy_string(0x1430B9BE0_g, "http://prod.uno.demonware.net/v1.0");
|
||||||
@ -587,6 +533,11 @@ namespace demonware
|
|||||||
{
|
{
|
||||||
server_thread.join();
|
server_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& import : original_imports)
|
||||||
|
{
|
||||||
|
utils::hook::set(import.first, import.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ namespace demonware
|
|||||||
std::memcpy(data.m_dec_key, &out_3[40], 16);
|
std::memcpy(data.m_dec_key, &out_3[40], 16);
|
||||||
std::memcpy(data.m_enc_key, &out_3[56], 16);
|
std::memcpy(data.m_enc_key, &out_3[56], 16);
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW] Response id: %s\n", utils::string::dump_hex(std::string(&out_2[8], 8)).data());
|
printf("[DW] Response id: %s\n", utils::string::dump_hex(std::string(&out_2[8], 8)).data());
|
||||||
printf("[DW] Hash verify: %s\n", utils::string::dump_hex(std::string(&out_3[20], 20)).data());
|
printf("[DW] Hash verify: %s\n", utils::string::dump_hex(std::string(&out_3[20], 20)).data());
|
||||||
printf("[DW] AES dec key: %s\n", utils::string::dump_hex(std::string(&out_3[40], 16)).data());
|
printf("[DW] AES dec key: %s\n", utils::string::dump_hex(std::string(&out_3[40], 16)).data());
|
||||||
|
@ -38,7 +38,7 @@ namespace demonware
|
|||||||
{
|
{
|
||||||
if (packet.starts_with("POST /auth/"))
|
if (packet.starts_with("POST /auth/"))
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [auth]: user requested authentication.\n");
|
printf("[DW]: [auth]: user requested authentication.\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
@ -81,7 +81,7 @@ namespace demonware
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [auth]: authenticating user %s\n", token.data() + 64);
|
printf("[DW]: [auth]: authenticating user %s\n", token.data() + 64);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ namespace demonware
|
|||||||
|
|
||||||
this->send_reply(&reply);
|
this->send_reply(&reply);
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [auth]: user successfully authenticated.\n");
|
printf("[DW]: [auth]: user successfully authenticated.\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ namespace demonware
|
|||||||
}
|
}
|
||||||
else if (size == 0xC8)
|
else if (size == 0xC8)
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [lobby]: received client_header_ack.\n");
|
printf("[DW]: [lobby]: received client_header_ack.\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ namespace demonware
|
|||||||
|
|
||||||
raw_reply reply(packet_2);
|
raw_reply reply(packet_2);
|
||||||
this->send_reply(&reply);
|
this->send_reply(&reply);
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [lobby]: sending server_header_ack.\n");
|
printf("[DW]: [lobby]: sending server_header_ack.\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
@ -98,7 +98,7 @@ namespace demonware
|
|||||||
|
|
||||||
if (type == 0x82)
|
if (type == 0x82)
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [lobby]: received client_auth.\n");
|
printf("[DW]: [lobby]: received client_auth.\n");
|
||||||
#endif
|
#endif
|
||||||
std::string packet_3(packet.data(), packet.size() - 8); // this 8 are client hash check?
|
std::string packet_3(packet.data(), packet.size() - 8); // this 8 are client hash check?
|
||||||
@ -113,7 +113,7 @@ namespace demonware
|
|||||||
raw_reply reply(response);
|
raw_reply reply(response);
|
||||||
this->send_reply(&reply);
|
this->send_reply(&reply);
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [lobby]: sending server_auth_done.\n");
|
printf("[DW]: [lobby]: sending server_auth_done.\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
@ -51,7 +51,7 @@ namespace demonware
|
|||||||
|
|
||||||
if (it != this->tasks_.end())
|
if (it != this->tasks_.end())
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW] %s: executing task '%d'\n", name_.data(), this->task_id_);
|
printf("[DW] %s: executing task '%d'\n", name_.data(), this->task_id_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace demonware
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: missing publisher file: %s\n", name.data());
|
printf("[DW]: [bdStorage]: missing publisher file: %s\n", name.data());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ namespace demonware
|
|||||||
buffer->read_uint16(&offset);
|
buffer->read_uint16(&offset);
|
||||||
buffer->read_string(&filename);
|
buffer->read_string(&filename);
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: list publisher files: %s\n", filename.data());
|
printf("[DW]: [bdStorage]: list publisher files: %s\n", filename.data());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ namespace demonware
|
|||||||
buffer->read_string(&unk);
|
buffer->read_string(&unk);
|
||||||
buffer->read_string(&filename);
|
buffer->read_string(&filename);
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: loading publisher file: %s\n", filename.data());
|
printf("[DW]: [bdStorage]: loading publisher file: %s\n", filename.data());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ namespace demonware
|
|||||||
|
|
||||||
if (this->load_publisher_resource(filename, data))
|
if (this->load_publisher_resource(filename, data))
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: sending publisher file: %s, size: %lld\n", filename.data(), data.size());
|
printf("[DW]: [bdStorage]: sending publisher file: %s, size: %lld\n", filename.data(), data.size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ namespace demonware
|
|||||||
info->filename = filename;
|
info->filename = filename;
|
||||||
info->data = data;
|
info->data = data;
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: set user file: %s\n", filename.data());
|
printf("[DW]: [bdStorage]: set user file: %s\n", filename.data());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ namespace demonware
|
|||||||
const auto path = get_user_file_path(filename);
|
const auto path = get_user_file_path(filename);
|
||||||
if (!utils::io::read_file(path, &data))
|
if (!utils::io::read_file(path, &data))
|
||||||
{
|
{
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: get user file: missing file: %s, %s, %s\n", game.data(), filename.data(), platform.data());
|
printf("[DW]: [bdStorage]: get user file: missing file: %s, %s, %s\n", game.data(), filename.data(), platform.data());
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
@ -222,7 +222,7 @@ namespace demonware
|
|||||||
reply->add(response);
|
reply->add(response);
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
#ifdef DW_DEBUG
|
#ifndef NDEBUG
|
||||||
printf("[DW]: [bdStorage]: get user file: %s, %s, %s\n", game.data(), filename.data(), platform.data());
|
printf("[DW]: [bdStorage]: get user file: %s, %s, %s\n", game.data(), filename.data(), platform.data());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -345,22 +345,22 @@ namespace utils::hook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub)
|
std::optional<std::pair<void*, void*>> iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub)
|
||||||
{
|
{
|
||||||
if (!library.is_valid()) return false;
|
if (!library.is_valid()) return {};
|
||||||
|
|
||||||
auto* const ptr = library.get_iat_entry(target_library, process);
|
auto* const ptr = library.get_iat_entry(target_library, process);
|
||||||
if (!ptr) return false;
|
if (!ptr) return {};
|
||||||
|
|
||||||
store_original_data(ptr, sizeof(*ptr));
|
store_original_data(ptr, sizeof(*ptr));
|
||||||
|
|
||||||
DWORD protect;
|
DWORD protect;
|
||||||
VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect);
|
VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect);
|
||||||
|
|
||||||
*ptr = stub;
|
std::swap(*ptr, stub);
|
||||||
|
|
||||||
VirtualProtect(ptr, sizeof(*ptr), protect, &protect);
|
VirtualProtect(ptr, sizeof(*ptr), protect, &protect);
|
||||||
return true;
|
return {{ptr, stub}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void nop(void* place, const size_t length)
|
void nop(void* place, const size_t length)
|
||||||
|
@ -147,7 +147,7 @@ namespace utils::hook
|
|||||||
void un_move();
|
void un_move();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub);
|
std::optional<std::pair<void*, void*>> iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub);
|
||||||
|
|
||||||
void nop(void* place, size_t length);
|
void nop(void* place, size_t length);
|
||||||
void nop(size_t place, size_t length);
|
void nop(size_t place, size_t length);
|
||||||
|
Loading…
Reference in New Issue
Block a user