aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorauth12 <[email protected]>2020-07-27 09:46:17 -0700
committerauth12 <[email protected]>2020-07-27 09:46:17 -0700
commita2e89fde1acc5b189c55e0b8b38146194e455cd0 (patch)
tree1f130027975733e0704a583aebb1a1832a22ec11 /server
parentCompile fix. (diff)
downloadloader-a2e89fde1acc5b189c55e0b8b38146194e455cd0.tar.xz
loader-a2e89fde1acc5b189c55e0b8b38146194e455cd0.zip
Removed spdlog, using fmt wrapper instead.
More process class changes, support for 32/64bit processes. Injection process improvements. Other small changes.
Diffstat (limited to 'server')
-rw-r--r--server/src/client/blacklist.h6
-rw-r--r--server/src/client/client.cpp8
-rw-r--r--server/src/client/client.h5
-rw-r--r--server/src/forum/forum.cpp26
-rw-r--r--server/src/image/pe.h50
-rw-r--r--server/src/main.cpp137
-rw-r--r--server/src/server/packet.h10
-rw-r--r--server/src/server/server.h3
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;