diff options
Diffstat (limited to 'server')
| -rw-r--r-- | server/src/client/blacklist.h | 6 | ||||
| -rw-r--r-- | server/src/client/client.cpp | 8 | ||||
| -rw-r--r-- | server/src/client/client.h | 5 | ||||
| -rw-r--r-- | server/src/forum/forum.cpp | 26 | ||||
| -rw-r--r-- | server/src/image/pe.h | 50 | ||||
| -rw-r--r-- | server/src/main.cpp | 137 | ||||
| -rw-r--r-- | server/src/server/packet.h | 10 | ||||
| -rw-r--r-- | server/src/server/server.h | 3 |
8 files changed, 159 insertions, 86 deletions
diff --git a/server/src/client/blacklist.h b/server/src/client/blacklist.h index b2bc9f8..f016f17 100644 --- a/server/src/client/blacklist.h +++ b/server/src/client/blacklist.h @@ -19,7 +19,7 @@ class blacklist { m_data = nlohmann::json::parse(data); } - void add(const std::string_view hwid) { + void add(const uint32_t hwid) { m_data["hwids"].emplace_back(hwid); save(); @@ -31,9 +31,9 @@ class blacklist { o.close(); } - bool find(const std::string &key) { + bool find(const uint32_t key) { for (auto &item : m_data["hwids"]) { - if (item.get<std::string>() == key) { + if (item.get<uint32_t>() == key) { return true; } } diff --git a/server/src/client/client.cpp b/server/src/client/client.cpp index 9b46574..11a6cfb 100644 --- a/server/src/client/client.cpp +++ b/server/src/client/client.cpp @@ -19,8 +19,7 @@ bool tcp::client::init_ssl(SSL_CTX* server_ctx) { if (ret <= 0) { int err = SSL_get_error(m_ssl, ret); - io::logger->error("{} failed to accept ssl, return code {}.", m_ip, - err); + io::logger->error("{} failed to accept ssl, return code {}.", m_ip, err); return false; } @@ -38,7 +37,7 @@ void tcp::client::gen_session() { } } -int tcp::client::stream(std::vector<char>& data, float *dur/*= nullptr*/) { +int tcp::client::stream(std::vector<char>& data, float* dur /*= nullptr*/) { auto size = data.size(); auto networked_size = htonl(size); @@ -63,8 +62,7 @@ int tcp::client::stream(std::vector<char>& data, float *dur/*= nullptr*/) { auto end = std::chrono::steady_clock::now(); std::chrono::duration<float> time = end - start; - if(dur) - *dur = time.count(); + if (dur) *dur = time.count(); return sent; } diff --git a/server/src/client/client.h b/server/src/client/client.h index 54df957..ef61b75 100644 --- a/server/src/client/client.h +++ b/server/src/client/client.h @@ -25,7 +25,8 @@ class client { std::string m_session_id; public: - std::string hwid; + uint32_t hwid; + std::string hwid_data; std::string username; int state; @@ -63,7 +64,7 @@ class client { int stream(std::vector<char>& data, float* dur = nullptr); int read_stream(std::vector<char>& out); - int stream(std::string& str) { + int stream(const std::string_view str) { std::vector<char> vec(str.begin(), str.end()); return stream(vec); } diff --git a/server/src/forum/forum.cpp b/server/src/forum/forum.cpp index a714cc6..e79f5e8 100644 --- a/server/src/forum/forum.cpp +++ b/server/src/forum/forum.cpp @@ -41,7 +41,7 @@ int xenforo_forum::check_login(const std::string_view username, auto json = nlohmann::json::parse(response); - if(!json.contains("user")) { + if (!json.contains("user")) { io::logger->error("json response for user {} doesn't contain user field.", username); return forum_response::api_fail; @@ -57,16 +57,30 @@ int xenforo_forum::check_login(const std::string_view username, auto custom_fields = user["custom_fields"]; + if(!user.contains("is_banned")) { + io::logger->error( + "json response for user {} doesn't contain is_banned.", username); + return forum_response::api_fail; + } + data.banned = user["is_banned"].get<bool>(); - // data.active = check user groupm - if (custom_fields.contains("hwid")) { - data.hwid = custom_fields["hwid"].get<std::string>(); - } else { - io::logger->warn("hwid field doesn't exist for {}.", username); + + if(!user.contains("user_id")) { + io::logger->error( + "json response for user {} doesn't contain user_id.", username); + return forum_response::api_fail; } data.id = user["user_id"].get<int>(); + if(!custom_fields.contains("hwid")) { + io::logger->error("custom fields for user {} dont contain hwid.", username); + return forum_response::api_fail; + } + + // data.active = check user group + data.hwid = custom_fields["hwid"].get<std::string>(); + return forum_response::api_success; } diff --git a/server/src/image/pe.h b/server/src/image/pe.h index e5a7a68..23a0e4f 100644 --- a/server/src/image/pe.h +++ b/server/src/image/pe.h @@ -1,9 +1,5 @@ #pragma once -// Had to put implementation inside a header file because im using templated -// class to make it work in its separate source file, I had to do some weird -// fuckery but I didn't want to do it - namespace pe { struct import_t { @@ -29,8 +25,6 @@ class image { public: image() = default; - ~image() = default; - image(const std::string_view name) : m_image{nullptr} { if (!io::read_file(name, m_buffer)) { io::logger->error("failed to load image {}.", name); @@ -65,8 +59,8 @@ class image { for (size_t i = 0; i < n; i++) { auto section = nt->get_section(i); m_sections.emplace_back(section_t{section->name, section->size_raw_data, - section->ptr_raw_data, - section->virtual_address}); + section->ptr_raw_data, + section->virtual_address}); } }; @@ -96,7 +90,6 @@ class image { const auto ptr = m_image->rva_to_ptr(import_dir->rva); auto table = reinterpret_cast<win::import_directory_t *>(ptr); - for (uint32_t previous_name = 0; previous_name < table->rva_name; previous_name = table->rva_name, ++table) { auto name_ptr = m_image->rva_to_ptr(table->rva_name); @@ -106,8 +99,7 @@ class image { m_image->rva_to_ptr(table->rva_original_first_thunk)); auto step = x64 ? sizeof(uint64_t) : sizeof(uint32_t); - for (uint32_t index = 0; thunk->address; - index += step, ++thunk) { + for (uint32_t index = 0; thunk->address; index += step, ++thunk) { auto named_import = reinterpret_cast<win::image_named_import_t *>( m_image->rva_to_ptr(thunk->address)); @@ -116,7 +108,8 @@ class image { data.name = reinterpret_cast<const char *>(named_import->name); data.rva = table->rva_first_thunk + index; - std::transform(mod_name.begin(), mod_name.end(), mod_name.begin(), ::tolower); + std::transform(mod_name.begin(), mod_name.end(), mod_name.begin(), + ::tolower); m_imports[mod_name].emplace_back(std::move(data)); } @@ -136,18 +129,22 @@ class image { } void relocate(std::vector<char> &image, uintptr_t base) { - const auto delta = base - m_image->get_nt_headers()->optional_header.image_base; + const auto delta = + base - m_image->get_nt_headers()->optional_header.image_base; if (delta > 0) { for (auto &[base_rva, entry] : m_relocs) { if (x64) { - if(entry.type == win::rel_based_high_low || entry.type == win::rel_based_dir64) { - *reinterpret_cast<uint64_t *>(image.data() + base_rva + entry.offset) += delta; + if (entry.type == win::rel_based_high_low || + entry.type == win::rel_based_dir64) { + *reinterpret_cast<uint64_t *>(image.data() + base_rva + + entry.offset) += delta; } continue; } - + if (entry.type == win::rel_based_high_low) { - *reinterpret_cast<uint32_t *>(image.data() + base_rva + entry.offset) += delta; + *reinterpret_cast<uint32_t *>(image.data() + base_rva + + entry.offset) += delta; } } } @@ -162,17 +159,18 @@ class image { auto j = nlohmann::json::parse(imports.data()); for (auto &[mod, funcs] : m_imports) { for (auto &func : funcs) { - if(j[func.name].is_null()) { + if (!j.contains(func.name)) { + io::logger->warn("missing {} import address.", func.name); continue; - } - - auto addr = j[func.name]; + } + + auto addr = j[func.name]; - if(x64) { + if (x64) { *reinterpret_cast<uint64_t *>(image.data() + func.rva) = addr; continue; } - + *reinterpret_cast<uint32_t *>(image.data() + func.rva) = addr; } } @@ -187,8 +185,8 @@ class image { std::string get_json_imports() { nlohmann::json json; - for(auto &[mod, imports] : m_imports) { - for(auto &i : imports) { + for (auto &[mod, imports] : m_imports) { + for (auto &i : imports) { json[mod].emplace_back(i.name); } } @@ -196,6 +194,4 @@ class image { } }; - - }; // namespace pe
\ No newline at end of file diff --git a/server/src/main.cpp b/server/src/main.cpp index fdac519..9008b8f 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -8,11 +8,11 @@ constexpr std::string_view version{"0.1.0"}; int main(int argc, char* argv[]) { io::init(true); - - pe::image img("img.dll"); - tcp::server client_server("6666"); + // id 0 : notepad test dll + client_server.images[0] = pe::image<false>("img.dll"); + client_server.start(); client_server.connect_event.add([&](tcp::client& client) { @@ -66,11 +66,21 @@ int main(int argc, char* argv[]) { io::logger->info("{} : {}", packet_session, message); if (id == tcp::packet_id::hwid) { - client.hwid = message; + if (!nlohmann::json::accept(message)) { + io::logger->warn("{} sent invalid hwid packet.", ip); + + client_server.disconnect_event.call(client); + return; + } + auto j = nlohmann::json::parse(message); + if(j.contains("uid")) + client.hwid = j["uid"]; - io::logger->info("got hwid from {} : {}", ip, message); + client.hwid_data = message; - if (client_server.bl().find(message)) { + io::logger->info("got hwid from {} : {}", ip, client.hwid); + + if (client_server.bl().find(client.hwid)) { io::logger->warn("{} is hwid banned.", ip); client.write(tcp::packet_t(message, tcp::packet_type::write, session, @@ -97,7 +107,7 @@ int main(int argc, char* argv[]) { io::logger->info("{} is trying to login from {}.", user, ip); int ret = forum_response::api_success; - //int ret = client_server.forum().check_login(user, pass, data); + // int ret = client_server.forum().check_login(user, pass, data); if (ret == forum_response::api_success) { if (data.banned) { io::logger->warn("{} is forum banned, dropping...", user); @@ -115,21 +125,31 @@ int main(int argc, char* argv[]) { if (data.hwid.empty()) { io::logger->info("{} is new, registering hwid...", user); if (!client_server.forum().edit(data.id, "custom_fields[hwid]", - client.hwid)) { + std::to_string(client.hwid))) { io::logger->warn("failed to register hwid for {}.", user); } - data.hwid = client.hwid; + if (!client_server.forum().edit(data.id, "custom_fields[hwid_data]", + client.hwid_data)) { + io::logger->warn("failed to register hwid data for {}.", user); + } + + data.hwid = std::to_string(client.hwid); } // invalid hwid - if (data.hwid != client.hwid) { - io::logger->warn("{}'s hwid doesn't match."); + if (data.hwid != std::to_string(client.hwid)) { + io::logger->warn("{}'s hwid doesn't match.", user); if (!client_server.forum().edit(data.id, "custom_fields[new_hwid]", - client.hwid)) { + std::to_string(client.hwid))) { io::logger->warn("failed to write new hwid for {}.", user); } + if (!client_server.forum().edit(data.id, "custom_fields[new_hwid_data]", + client.hwid_data)) { + io::logger->warn("failed to write new hwid data for {}.", user); + } + json["result"] = tcp::client_response::hwid_mismatch; client.write(tcp::packet_t(json.dump(), tcp::packet_type::write, @@ -140,8 +160,10 @@ int main(int argc, char* argv[]) { } json["result"] = tcp::client_response::login_success; - json["games"]["csgo"] = {{"version", "0.1"}, {"id", 0}, {"process","csgo.exe"}}; - json["games"]["csgo beta"] = {{"version", "0.1"}, {"id", 1}, {"process","csgo.exe"}}; + json["games"]["test"] = { + {"version", "0.1"}, {"id", 0}, {"process", "notepad++.exe"}}; + json["games"]["csgo"] = { + {"version", "0.1"}, {"id", 1}, {"process", "csgo.exe"}}; client.write(tcp::packet_t(json.dump(), tcp::packet_type::write, session, tcp::packet_id::login_resp)); @@ -156,7 +178,8 @@ int main(int argc, char* argv[]) { ret == forum_response::api_fail) { json["result"] = tcp::client_response::server_error; - io::logger->info("internal server error on {}'s login request.", user); + io::logger->info("internal server error on {}'s login request.", + user); client.write(tcp::packet_t(json.dump(), tcp::packet_type::write, session, tcp::packet_id::login_resp)); @@ -174,31 +197,53 @@ int main(int argc, char* argv[]) { } if (id == tcp::packet_id::game_select) { - if(client.state != tcp::client_state::logged_in) { + if (client.state != tcp::client_state::logged_in) { return; } - if(!nlohmann::json::accept(message)) { - io::logger->error("{} sent invalid game select packet.", ip); + if (!nlohmann::json::accept(message)) { + io::logger->warn("{} sent invalid game select packet.", ip); client_server.disconnect_event.call(client); return; } auto resp = nlohmann::json::parse(message); - int id = resp["id"].get<int>(); + if(!resp.contains("id")) { + io::logger->warn( + "id doesn't exist in game select json response for {}.", ip); + + client_server.disconnect_event.call(client); + return; + } + int id = resp["id"]; + + auto& img = client_server.images[id]; + + if (!img) { + io::logger->warn("{} sent invalid game id."); + + client_server.disconnect_event.call(client); + return; + } + + io::logger->info("{} selected game id {}.", client.username, id); - nlohmann::json j; auto nt = img->get_nt_headers(); + nlohmann::json j; j["pe"].emplace_back(nt->optional_header.size_image); j["pe"].emplace_back(nt->optional_header.entry_point); - client.write(tcp::packet_t(j.dump(), tcp::packet_type::write, - session, tcp::packet_id::game_select)); auto imports = img.get_json_imports(); - if(client.stream(imports)) { + + j["size"] = imports.size(); + + client.write(tcp::packet_t(j.dump(), tcp::packet_type::write, session, + tcp::packet_id::game_select)); + + if (client.stream(imports) == imports.size()) { io::logger->info("sent imports to {}.", client.username); } @@ -206,16 +251,17 @@ int main(int argc, char* argv[]) { // select image // set message to be pe header // stream imports - // wait for client to send back a packet with allocation base and fixed imports + // wait for client to send back a packet with allocation base and fixed + // imports } if (id == tcp::packet_id::image) { - if(client.state != tcp::client_state::waiting) { + if (client.state != tcp::client_state::waiting) { return; } - if(!nlohmann::json::accept(message)) { - io::logger->error("{} sent invalid image packet.", ip); + if (!nlohmann::json::accept(message)) { + io::logger->warn("{} sent invalid image packet.", ip); client_server.disconnect_event.call(client); return; @@ -225,34 +271,47 @@ int main(int argc, char* argv[]) { client.read_stream(imports); auto j = nlohmann::json::parse(message); - auto alloc = j["alloc"].get<uintptr_t>(); + + if (!j.contains("alloc") || !j.contains("id")) { + io::logger->warn("{} sent invalid json image reponse.", ip); + + client_server.disconnect_event.call(client); + return; + } + + uintptr_t alloc = j["alloc"]; + int id = j["id"]; io::logger->info("{} allocated at {:x}", client.username, alloc); + auto& img = client_server.images[id]; + if (!img) { + io::logger->error("{} sent invalid game id."); + + client_server.disconnect_event.call(client); + return; + } + std::vector<char> image; img.copy(image); img.relocate(image, alloc); img.fix_imports(image, imports); - client.write(tcp::packet_t("ready", tcp::packet_type::write, - session, tcp::packet_id::image)); + client.write(tcp::packet_t("ready", tcp::packet_type::write, session, + tcp::packet_id::image)); - if(client.stream(image) == image.size()) { + if (client.stream(image) == image.size()) { io::logger->info("sent image to {}.", client.username); } - - std::ofstream imp("data/imports/" + client.username); - imp.write(imports.data(), imports.size()); - imp.close(); client.state = tcp::client_state::injected; // message contains allocation base - // fixed imports are streamed back/save them in a folder to see if anything went wrong - // stream back the fixed image - // set client status or just drop them + // fixed imports are streamed back/save them in a folder to see if + // anything went wrong stream back the fixed image set client status or + // just drop them } - //client.write(tcp::packet_t(message, tcp::packet_type::write, session)); + // client.write(tcp::packet_t(message, tcp::packet_type::write, session)); }); client_server.timeout_event.add([&](tcp::client& client) { diff --git a/server/src/server/packet.h b/server/src/server/packet.h index 626d340..6f717ac 100644 --- a/server/src/server/packet.h +++ b/server/src/server/packet.h @@ -40,10 +40,12 @@ struct packet_t { } auto json = nlohmann::json::parse(message); - id = json["id"]; - session_id = json["session_id"]; - message = json["message"]; - + if (json.contains("id") && json.contains("session_id") && + json.contains("message")) { + id = json["id"]; + session_id = json["session_id"]; + message = json["message"]; + } } else { nlohmann::json json; json["id"] = action; diff --git a/server/src/server/server.h b/server/src/server/server.h index 738558b..3e320a7 100644 --- a/server/src/server/server.h +++ b/server/src/server/server.h @@ -29,6 +29,9 @@ class server { event<packet_t&, client&> receive_event; event<client&> disconnect_event; event<client&> timeout_event; + + + std::unordered_map<int, pe::image<false>> images; server(const std::string_view port) : m_port{port}, m_active{false} {} ~server() = default; |