diff options
| author | auth12 <[email protected]> | 2020-07-21 13:07:42 -0700 |
|---|---|---|
| committer | auth12 <[email protected]> | 2020-07-21 13:07:42 -0700 |
| commit | f09669dd5846d95b063712571ccb7519910a0d6e (patch) | |
| tree | 902f5ad201651f2d96ccf619e90b76cfa06a7b9b /client/src | |
| parent | Syscalls. (diff) | |
| download | loader-f09669dd5846d95b063712571ccb7519910a0d6e.tar.xz loader-f09669dd5846d95b063712571ccb7519910a0d6e.zip | |
Added game selection.
Started process wrapper.
Removed asmjit.
Diffstat (limited to 'client/src')
| -rw-r--r-- | client/src/client/ca.h | 37 | ||||
| -rw-r--r-- | client/src/client/client.cpp | 168 | ||||
| -rw-r--r-- | client/src/client/client.h | 212 | ||||
| -rw-r--r-- | client/src/client/enc.cpp | 56 | ||||
| -rw-r--r-- | client/src/client/enc.h | 4 | ||||
| -rw-r--r-- | client/src/include.h | 1 | ||||
| -rw-r--r-- | client/src/injection/mapper.h | 19 | ||||
| -rw-r--r-- | client/src/injection/process.cpp | 71 | ||||
| -rw-r--r-- | client/src/injection/process.h | 19 | ||||
| -rw-r--r-- | client/src/main.cpp | 305 | ||||
| -rw-r--r-- | client/src/shellcode/shellcode.cpp | 31 | ||||
| -rw-r--r-- | client/src/shellcode/shellcode.h | 35 | ||||
| -rw-r--r-- | client/src/util/events.h | 28 | ||||
| -rw-r--r-- | client/src/util/io.cpp | 8 | ||||
| -rw-r--r-- | client/src/util/io.h | 4 | ||||
| -rw-r--r-- | client/src/util/native.h | 6 | ||||
| -rw-r--r-- | client/src/util/pe.h | 74 | ||||
| -rw-r--r-- | client/src/util/syscalls.cpp | 8 | ||||
| -rw-r--r-- | client/src/util/syscalls.h | 10 | ||||
| -rw-r--r-- | client/src/util/util.cpp | 54 | ||||
| -rw-r--r-- | client/src/util/util.h | 22 |
21 files changed, 637 insertions, 535 deletions
diff --git a/client/src/client/ca.h b/client/src/client/ca.h new file mode 100644 index 0000000..fca03c4 --- /dev/null +++ b/client/src/client/ca.h @@ -0,0 +1,37 @@ +#pragma once + + +const static std::string root_cert = R"( +-----BEGIN CERTIFICATE----- +MIIFgTCCA2mgAwIBAgIUI1iNRm7wAiOk64UxFSCPziYMdyAwDQYJKoZIhvcNAQEL +BQAwUDELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9u +dHJlYWwxDDAKBgNVBAoMA2FscDEPMA0GA1UECwwGbG9hZGVyMB4XDTIwMDYyOTA4 +NDgxMloXDTIzMDQxOTA4NDgxMlowUDELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1 +ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxDDAKBgNVBAoMA2FscDEPMA0GA1UECwwG +bG9hZGVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvPv6+6+Nn3D5 +YPa6SwvS7dzZNe8kPqkAwZy4PMCQQ9MmQQILJMjou/6i4xN0YL2bZ24VoVhOAmVa +sZDLV1Qmra+zDJa4no5bBIxsA/HZc3QAHRzkye9Pw8avBAw67X7AzWH5z7i2Ce+l +F4ezNG6i7PJ3QC+jkJRqzm0gh/BIjHl7takuBunNS7l1tP+M4YUIqN6AV/9sLodE +YS9PL8fP9Gk6Lds90OSj4DBmsYJdYLfxdPrQ609ijKOjQtphUZ8/JnaED7KGnFV3 +FIQV7L/usmxUKUbwxa+36TXpC+qYGKXTdVpu++VKcgHU0u8H03X/4LlR0DUkby/P +nFxJFL1WWzbYIH3CBCx2YeaBneT6EUZvCBNHwL1fl8sG8FOiRoV1G2sy7eBadofi +R+l7Pm4iTzsl1zF9ODCsE3EvJdZ/WxbSk5OU0oLJyeCJszhA/jPXu9ogKjFG1LVd +5JEYGvg4SKKiEUD6G/luCTV9WKcajm4v+BtzTy/ftl1e4zbQ/Vod44BE/0Rj0Z+l +yK7XI3RYZwO+McBjT3/bUAED1dB3u8kOyHf4k+boIYaI3LImXVGZue7tB+qQv6ZB +NY9m3FM6yVdV4peWKBsuSucGDVElBD0SgaeOvmLPFgVaQjmabRVUReYHvWoVHLDZ +WgPZe72SkPJ1Lu85Ux52PMDeKrIigC0CAwEAAaNTMFEwHQYDVR0OBBYEFE4IyL3j +3kdYSMpOfxRGmUSmLbGAMB8GA1UdIwQYMBaAFE4IyL3j3kdYSMpOfxRGmUSmLbGA +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAIilajIQyW05OGcH +PY8ePZupbnOsjvHjHk+CtvrMcf6CAXZkbkgfkAddJcS4D7HoZG9v5GONLZSIfVqT +E7iKSQm4uYaAE/MqaHIdZwPrE9Z/mp5sGP1zdNFPuqil4JvSusP2aV6D5++1//P3 +Hw9t588U5phGalL6MP9NezXnuuRNC6Nz5CIkawlO2O4bg2BX7wxFiF5YeZEtdKI4 +CKAyoTlVPgc0VkzSPTUGwK2MYOq3BqVrtmvNthItcXp6ML5dhRv2Grk9pEU/xirv +ahIxwusFXiSmW2vgfPFGdNb3elnHGs7H4291oNNvtQjlHvjZXOSRjeBnLMunUsyn +81zDbaRC91TZPPogUFiKq3Avh80d/QnoypdjhPmhsOGwPikjolfJ45jYO/f27CVT +AqexIUOuKaJudeejWX3Vj3xlyl4x8kxPk6zNnBLY9fAur5i/UTLOfZtbMAP1T1ZJ +vQZ5ncJFy3SkN4yyzeOXAXXZMh3xIEALtPqH4UFWdvLcMUIHUmCa22zYOK9zcKFm +qwSN/mNqYvYFS9nT2CkmjcXzbXazijfjnie94nHDtCyZzBwKz76xuldDcE+NMXy2 +xf2P4NoAmulUDxgHLhsXJVA5OS9kGuJNQ6i2axZpRhPBN6kUFfT14VjZ/Co/Fkty +hTbB0ZS9vX7ug3j2KF0WPHyJaXcS +-----END CERTIFICATE----- +)";
\ No newline at end of file diff --git a/client/src/client/client.cpp b/client/src/client/client.cpp index 8e71e81..3fa55fc 100644 --- a/client/src/client/client.cpp +++ b/client/src/client/client.cpp @@ -1,106 +1,108 @@ #include "../include.h" #include "client.h" +#include "ca.h" + void tcp::client::start(const std::string_view server_ip, const uint16_t port) { - wolfSSL_library_init(); - - m_ssl_ctx = wolfSSL_CTX_new(wolfTLS_client_method()); - - int ret = wolfSSL_CTX_load_verify_locations(m_ssl_ctx, "ssl/rootCA.crt", nullptr); - if (ret != 1) { - io::logger->error("failed to load ca."); - return; - } - wolfSSL_CTX_set_verify(m_ssl_ctx, SSL_VERIFY_PEER, 0); - - WSADATA data; - ret = WSAStartup(MAKEWORD(2, 2), &data); - if (ret != 0) { - io::logger->error("failed to initialize WSA."); - return; - } - - m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (m_socket == -1) { - io::logger->error("failed to create socket."); - return; - } - - sockaddr_in server_addr; - - server_addr.sin_family = AF_INET; - server_addr.sin_addr.s_addr = inet_addr(server_ip.data()); - server_addr.sin_port = htons(port); - - ret = connect(m_socket, reinterpret_cast<sockaddr*>(&server_addr), - sizeof(server_addr)); - if (ret < 0) { - io::logger->error("failed to connect to server."); - return; - } - - m_server_ssl = wolfSSL_new(m_ssl_ctx); - wolfSSL_set_fd(m_server_ssl, m_socket); - - ret = wolfSSL_connect(m_server_ssl); - - if (ret != 1) { - ret = wolfSSL_get_error(m_server_ssl, ret); - io::logger->error("secure connection failed, code {}", ret); - return; - } - - m_active = true; - - connect_event.call(); + wolfSSL_library_init(); + + m_ssl_ctx = wolfSSL_CTX_new(wolfTLS_client_method()); + + int ret = wolfSSL_CTX_load_verify_buffer(m_ssl_ctx, reinterpret_cast<const unsigned char*>(root_cert.data()), root_cert.size(), SSL_FILETYPE_PEM); + if (ret != 1) { + io::logger->error("failed to load ca."); + return; + } + wolfSSL_CTX_set_verify(m_ssl_ctx, SSL_VERIFY_PEER, 0); + + WSADATA data; + ret = WSAStartup(MAKEWORD(2, 2), &data); + if (ret != 0) { + io::logger->error("failed to initialize WSA."); + return; + } + + m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (m_socket == -1) { + io::logger->error("failed to create socket."); + return; + } + + sockaddr_in server_addr; + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(server_ip.data()); + server_addr.sin_port = htons(port); + + ret = connect(m_socket, reinterpret_cast<sockaddr*>(&server_addr), + sizeof(server_addr)); + if (ret < 0) { + io::logger->error("failed to connect to server."); + return; + } + + m_server_ssl = wolfSSL_new(m_ssl_ctx); + wolfSSL_set_fd(m_server_ssl, m_socket); + + ret = wolfSSL_connect(m_server_ssl); + + if (ret != 1) { + ret = wolfSSL_get_error(m_server_ssl, ret); + io::logger->error("secure connection failed, code {}", ret); + return; + } + + m_active = true; + + connect_event.call(); } int tcp::client::read_stream(std::vector<char>& out) { - size_t size; - read(&size, sizeof(size)); + size_t size; + read(&size, sizeof(size)); - size = ntohl(size); - out.resize(size); + size = ntohl(size); + out.resize(size); - constexpr size_t chunk_size = 4096; - size_t total = 0; + constexpr size_t chunk_size = 4096; + size_t total = 0; - while (size > 0) { - auto to_read = std::min(size, chunk_size); + while (size > 0) { + auto to_read = std::min(size, chunk_size); - int ret = read(&out[total], to_read); - if (ret <= 0) { - break; - } + int ret = read(&out[total], to_read); + if (ret <= 0) { + break; + } - size -= ret; - total += ret; - } + size -= ret; + total += ret; + } - return total; + return total; } int tcp::client::stream(std::vector<char>& data) { - auto size = data.size(); + auto size = data.size(); - auto networked_size = htonl(size); - write(&networked_size, sizeof(networked_size)); + auto networked_size = htonl(size); + write(&networked_size, sizeof(networked_size)); - // with 4kb chunk size, speed peaks at 90mb/s - constexpr size_t chunk_size = 4096; - size_t sent = 0; + // with 4kb chunk size, speed peaks at 90mb/s + constexpr size_t chunk_size = 4096; + size_t sent = 0; - while (size > 0) { - auto to_send = std::min(size, chunk_size); + while (size > 0) { + auto to_send = std::min(size, chunk_size); - int ret = write(&data[sent], to_send); - if (ret <= 0) { - break; - } + int ret = write(&data[sent], to_send); + if (ret <= 0) { + break; + } - sent += ret; - size -= ret; - } + sent += ret; + size -= ret; + } - return sent; + return sent; } diff --git a/client/src/client/client.h b/client/src/client/client.h index 8d5b80a..cdc00d6 100644 --- a/client/src/client/client.h +++ b/client/src/client/client.h @@ -1,115 +1,123 @@ #pragma once +#include <wolfssl/IDE/WIN/user_settings.h> #include <wolfssl/ssl.h> #include "../util/io.h" #include "../util/events.h" -#include "../injection/mapper.h" #include "packet.h" -namespace tcp { - -struct version_t { - uint8_t major; - uint8_t minor; - uint8_t patch; -}; - -struct game_data_t { - std::string name; - std::string version; - int id; -}; - -enum client_state { - idle = 0, logged_in, waiting -}; - -enum login_result { - login_fail = 15494, - hwid_mismatch = 11006, - login_success = 61539, - banned = 28618, - server_error = 98679 +struct mapper_data_t { + size_t image_size; + uint32_t entry; + uint32_t base; + std::string imports; + std::vector<char> image; }; -class client { - int m_socket; - std::atomic<bool> m_active; - - WOLFSSL* m_server_ssl; - WOLFSSL_CTX* m_ssl_ctx; - - public: - int state; - mmap::mapper_data_t mapper_data; - std::vector<game_data_t> games; - - std::string session_id; - event<packet_t&> receive_event; - event<> connect_event; - - client() : m_socket{-1}, m_active{false}, state{client_state::idle} {} - - void start(const std::string_view server_ip, const uint16_t port); - - int write(const packet_t& packet) { - if (!packet) return 0; - return write(packet.message.data(), - packet.message.size()); - } - - int write(const void* data, size_t size) { - return wolfSSL_write(m_server_ssl, data, size); - } - - int read(void* data, size_t size) { - return wolfSSL_read(m_server_ssl, data, size); - } - - int read_stream(std::vector<char>& out); - int stream(std::vector<char>& data); - - int stream(std::string &str) { - std::vector<char> vec(str.begin(), str.end()); - return stream(vec); - } - - int read_stream(std::string &str) { - std::vector<char> out; - int ret = read_stream(out); - str.assign(out.begin(), out.end()); - return ret; - } - - int get_socket() { return m_socket; } - - operator bool() const { return m_active; } - - void shutdown() { - closesocket(m_socket); - wolfSSL_shutdown(m_server_ssl); - wolfSSL_free(m_server_ssl); - - m_active = false; - } - - static void monitor(client& client) { - while (!client) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - std::array<char, message_len> buf; - while (client) { - int ret = client.read(&buf[0], buf.size()); - if (ret <= 0) { - io::logger->error("connection lost."); - break; - } - std::string msg(buf.data(), ret); - packet_t packet(msg, packet_type::read); +namespace tcp { - client.receive_event.call(packet); - } - } -}; + struct version_t { + uint8_t major; + uint8_t minor; + uint8_t patch; + }; + + struct game_data_t { + std::string name; + std::string version; + int id; + }; + + enum client_state { + idle = 0, logged_in, waiting + }; + + enum login_result { + login_fail = 15494, + hwid_mismatch = 11006, + login_success = 61539, + banned = 28618, + server_error = 98679 + }; + + class client { + int m_socket; + std::atomic<bool> m_active; + + WOLFSSL* m_server_ssl; + WOLFSSL_CTX* m_ssl_ctx; + + public: + int state; + mapper_data_t mapper_data; + std::vector<game_data_t> games; + + std::string session_id; + event<packet_t&> receive_event; + event<> connect_event; + + client() : m_socket{ -1 }, m_active{ false }, state{ client_state::idle } {} + + void start(const std::string_view server_ip, const uint16_t port); + + int write(const packet_t& packet) { + if (!packet) return 0; + return write(packet.message.data(), + packet.message.size()); + } + + int write(const void* data, int size) { + return wolfSSL_write(m_server_ssl, data, size); + } + + int read(void* data, int size) { + return wolfSSL_read(m_server_ssl, data, size); + } + + int read_stream(std::vector<char>& out); + int stream(std::vector<char>& data); + + int stream(std::string& str) { + std::vector<char> vec(str.begin(), str.end()); + return stream(vec); + } + + int read_stream(std::string& str) { + std::vector<char> out; + int ret = read_stream(out); + str.assign(out.begin(), out.end()); + return ret; + } + + int get_socket() { return m_socket; } + + operator bool() const { return m_active; } + + void shutdown() { + closesocket(m_socket); + wolfSSL_shutdown(m_server_ssl); + wolfSSL_free(m_server_ssl); + + m_active = false; + } + + static void monitor(client& client) { + while (!client) std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + std::array<char, message_len> buf; + while (client) { + int ret = client.read(&buf[0], buf.size()); + if (ret <= 0) { + io::logger->error("connection lost."); + break; + } + std::string msg(buf.data(), ret); + packet_t packet(msg, packet_type::read); + + client.receive_event.call(packet); + } + } + }; } // namespace tcp diff --git a/client/src/client/enc.cpp b/client/src/client/enc.cpp index 97e1c29..b1287aa 100644 --- a/client/src/client/enc.cpp +++ b/client/src/client/enc.cpp @@ -3,33 +3,33 @@ namespace enc { -std::random_device r; - -void encrypt_message(std::string &str) { - std::default_random_engine e1(r()); - std::uniform_int_distribution<int> gen(0, 255); - - char k1 = static_cast<char>(gen(e1)); - char k2 = static_cast<char>(gen(e1)); - for (int i = 0; i < str.size(); i++) { - char k = (i % 2) ? k1 : k2; - str[i] ^= k; - } - str.insert(str.begin(), k1); - str.insert(str.end(), k2); -} - -void decrypt_message(std::string &str) { - char k1 = str[0]; - char k2 = str[str.size() - 1]; - - str.erase(str.begin()); - str.erase(str.end() - 1); - - for (int i = 0; i < str.size(); i++) { - char k = (i % 2) ? k1 : k2; - str[i] ^= k; - } -} + std::random_device r; + + void encrypt_message(std::string& str) { + std::default_random_engine e1(r()); + std::uniform_int_distribution<int> gen(0, 255); + + char k1 = static_cast<char>(gen(e1)); + char k2 = static_cast<char>(gen(e1)); + for (int i = 0; i < str.size(); i++) { + char k = (i % 2) ? k1 : k2; + str[i] ^= k; + } + str.insert(str.begin(), k1); + str.insert(str.end(), k2); + } + + void decrypt_message(std::string& str) { + char k1 = str[0]; + char k2 = str[str.size() - 1]; + + str.erase(str.begin()); + str.erase(str.end() - 1); + + for (int i = 0; i < str.size(); i++) { + char k = (i % 2) ? k1 : k2; + str[i] ^= k; + } + } }; // namespace enc
\ No newline at end of file diff --git a/client/src/client/enc.h b/client/src/client/enc.h index ae8d5a6..e85e296 100644 --- a/client/src/client/enc.h +++ b/client/src/client/enc.h @@ -2,7 +2,7 @@ namespace enc { -void encrypt_message(std::string &str); -void decrypt_message(std::string &str); + void encrypt_message(std::string& str); + void decrypt_message(std::string& str); }; // namespace enc
\ No newline at end of file diff --git a/client/src/include.h b/client/src/include.h index 4955913..d378325 100644 --- a/client/src/include.h +++ b/client/src/include.h @@ -7,6 +7,7 @@ #include <ws2tcpip.h> #include <iphlpapi.h> #include <winternl.h> +#include <ntstatus.h> #include <algorithm> #include <array> diff --git a/client/src/injection/mapper.h b/client/src/injection/mapper.h index 0d9026e..d1cfa5c 100644 --- a/client/src/injection/mapper.h +++ b/client/src/injection/mapper.h @@ -2,12 +2,13 @@ namespace mmap { -struct mapper_data_t { - size_t image_size; - uint32_t entry; - uint32_t base; - std::string imports; - std::vector<char> image; -}; - -}; // namespace mmap
\ No newline at end of file + void thread(tcp::client& client) { + while (client.mapper_data.imports.empty()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + + + } + +};
\ No newline at end of file diff --git a/client/src/injection/process.cpp b/client/src/injection/process.cpp new file mode 100644 index 0000000..954e9a8 --- /dev/null +++ b/client/src/injection/process.cpp @@ -0,0 +1,71 @@ +#include "../include.h" +#include "../util/io.h" +#include "../util/syscalls.h" +#include "../util/util.h" +#include "process.h" + +process::process(const SYSTEM_PROCESS_INFORMATION* info) { + std::wstring name; + name.resize(info->ImageName.Length); + + std::memcpy(&name[0], &info->ImageName.Buffer[0], name.size()); + + m_name = util::wide_to_multibyte(name); + m_id = int(info->UniqueProcessId); +} + +process::~process() { + m_name.clear(); +} + +bool process::open() { + CLIENT_ID cid = { HANDLE(m_id), 0 }; + OBJECT_ATTRIBUTES oa; + oa.Length = sizeof(oa); + oa.Attributes = 0; + oa.RootDirectory = 0; + oa.SecurityDescriptor = 0; + oa.ObjectName = 0; + oa.SecurityQualityOfService = 0; + + static auto nt_open = g_syscalls.get<native::NtOpenProcess>("NtOpenProcess"); + + if (!NT_SUCCESS(nt_open(&m_handle, PROCESS_ALL_ACCESS, &oa, &cid))) { + io::logger->error("failed to open handle to {}.", m_name); + return false; + } + + return true; +} + +bool process::read(const uintptr_t addr, void* data, const size_t size) { + static auto nt_read = g_syscalls.get<native::NtReadVirtualMemory>("NtReadVirtualMemory"); + if (!m_handle) { + io::logger->error("invalid process handle.", m_name); + return false; + } + + ULONG read; + if (!NT_SUCCESS(nt_read(m_handle, reinterpret_cast<void*>(addr), data, size, &read))) { + io::logger->error("failed to read to {}.", m_name); + return false; + } + + return true; +} + +bool process::write(const uintptr_t addr, void* data, const size_t size) { + static auto nt_write = g_syscalls.get<native::NtWiteVirtualMemory>("NtWiteVirtualMemory"); + if (!m_handle) { + io::logger->error("invalid process handle.", m_name); + return false; + } + + ULONG wrote; + if (!NT_SUCCESS(nt_write(m_handle, reinterpret_cast<void*>(addr), data, size, &wrote))) { + io::logger->error("failed to write to {}.", m_name); + return false; + } + + return true; +} diff --git a/client/src/injection/process.h b/client/src/injection/process.h new file mode 100644 index 0000000..574713a --- /dev/null +++ b/client/src/injection/process.h @@ -0,0 +1,19 @@ +#pragma once + +class process { + int m_id; + std::string m_name; + + HANDLE m_handle = INVALID_HANDLE_VALUE; +public: + process() = default; + process(const SYSTEM_PROCESS_INFORMATION* info); + ~process(); + + bool open(); + bool read(const uintptr_t addr, void* data, const size_t size); + bool write(const uintptr_t addr, void* data, const size_t size); + + auto &get_name() { return m_name; } + auto &get_id() { return m_id; } +};
\ No newline at end of file diff --git a/client/src/main.cpp b/client/src/main.cpp index 65a29e3..66dad15 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -3,158 +3,181 @@ #include "util/util.h" #include "util/syscalls.h" #include "client/client.h" -#include "shellcode/shellcode.h" +#include "injection/mapper.h" int main(int argc, char* argv[]) { - io::init(); + io::init(); + + if (!util::init()) { + return 0; + } + + g_syscalls.init(); + + + auto info = g_syscalls.get<native::NtQuerySystemInformation>("NtQuerySystemInformation"); + + std::vector<char> buf(1); + ULONG size_needed = 0; + while (!NT_SUCCESS(info(SystemProcessInformation, buf.data(), buf.size(), &size_needed))) { + buf.resize(size_needed); + }; + + auto pi = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(buf.data()); + for ( + auto info_casted = reinterpret_cast<uintptr_t>(pi); + pi->NextEntryOffset; + pi = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(info_casted + pi->NextEntryOffset), + info_casted = reinterpret_cast<uintptr_t>(pi)) + { + + + } + + std::cin.get(); + tcp::client client; + + std::thread t{ tcp::client::monitor, std::ref(client) }; + t.detach(); + + client.start("127.0.0.1", 6666); + + client.connect_event.add([&]() { io::logger->info("connected."); }); + + client.receive_event.add([&](tcp::packet_t& packet) { + if (!packet) return; + auto message = packet(); + auto id = packet.id; - if (!util::init()) { - return 0; - } - g_syscalls.init(); + if (id == tcp::packet_id::session) { + client.session_id = packet.session_id; - using NtClose_t = long(__stdcall*)(HANDLE); - - HANDLE h = INVALID_HANDLE_VALUE; - auto status = g_syscalls.get<NtClose_t>("NtClose")(h); - - io::logger->info("{:x}", status); - - std::cin.get(); - - tcp::client client; - - std::thread t{tcp::client::monitor, std::ref(client)}; - t.detach(); - - client.start("127.0.0.1", 6666); - - client.connect_event.add([&]() { io::logger->info("connected."); }); - - client.receive_event.add([&](tcp::packet_t& packet) { - if (!packet) return; - auto message = packet(); - auto id = packet.id; + tcp::version_t v{ 0, 1, 0 }; + auto version = fmt::format("{}.{}.{}", v.major, v.minor, v.patch); + io::logger->info("current server version {}", message); - if (id == tcp::packet_id::session) { - client.session_id = packet.session_id; - - tcp::version_t v{0, 1, 0}; - auto version = fmt::format("{}.{}.{}", v.major, v.minor, v.patch); - io::logger->info("current server version {}", message); - - if (version != message) { - io::logger->error("please update your client."); - client.shutdown(); - } - - int ret = - client.write(tcp::packet_t("hwid", tcp::packet_type::write, - client.session_id, tcp::packet_id::hwid)); - if (ret <= 0) { - io::logger->error("internal error."); - client.shutdown(); - return; - } - } + if (version != message) { + io::logger->error("please update your client."); + client.shutdown(); + } + + int ret = + client.write(tcp::packet_t("hwid", tcp::packet_type::write, + client.session_id, tcp::packet_id::hwid)); + if (ret <= 0) { + io::logger->error("internal error."); + client.shutdown(); + return; + } + } + + if (id == tcp::packet_id::login_resp) { + auto j = nlohmann::json::parse(message); + + auto res = j["result"].get<int>(); + + if (res == tcp::login_result::banned) { + io::logger->error("your account is banned."); + client.shutdown(); + return; + } - if (id == tcp::packet_id::login_resp) { - auto j = nlohmann::json::parse(message); + if (res == tcp::login_result::login_fail) { + io::logger->error("please check your username or password."); + client.shutdown(); + return; + } - auto res = j["result"].get<int>(); + if (res == tcp::login_result::hwid_mismatch) { + io::logger->error("please reset your hwid on the forums."); + client.shutdown(); + return; + } - if (res == tcp::login_result::banned) { - io::logger->error("your account is banned."); - client.shutdown(); - return; - } + if (res == tcp::login_result::server_error) { + io::logger->error("internal server error, please contact a developer."); + client.shutdown(); + return; + } - if (res == tcp::login_result::login_fail) { - io::logger->error("please check your username or password."); - client.shutdown(); - return; - } + if (res == tcp::login_result::login_success) { + auto games = j["games"]; + for (auto& [key, value] : games.items()) { + std::string version = value["version"]; + int id = value["id"]; - if (res == tcp::login_result::hwid_mismatch) { - io::logger->error("please reset your hwid on the forums."); - client.shutdown(); - return; - } + client.games.emplace_back(tcp::game_data_t{ key, version, id }); + } + + io::logger->info("logged in."); + client.state = tcp::client_state::logged_in; + } + } - if (res == tcp::login_result::server_error) { - io::logger->error("internal server error, please contact a developer."); - client.shutdown(); - return; - } + if (id == tcp::packet_id::game_select) { + auto j = nlohmann::json::parse(message); + client.mapper_data.image_size = j["pe"][0]; + client.mapper_data.base = j["pe"][1]; + client.mapper_data.entry = j["pe"][2]; + + + client.read_stream(client.mapper_data.imports); + } + + if (id == tcp::packet_id::ban) { + io::logger->error( + "your computer is blacklisted, please contact a developer."); + client.shutdown(); + return; + } - if (res == tcp::login_result::login_success) { - auto games = j["games"]; - for (auto&[key, value] : games.items()) { - std::string version = value["version"]; - int id = value["id"]; - - client.games.emplace_back(tcp::game_data_t{key, version, id}); - } + io::logger->info("{}:{}->{} {}", packet.seq, packet.session_id, message, id); + }); - io::logger->info("logged in."); - client.state = tcp::client_state::logged_in; - } - } - - if (id == tcp::packet_id::game_select) { - /*auto pe = nlohmann::json::parse(message); - client.mapper_data.base = pe[0]; - client.mapper_data.entry = pe[1]; - client.mapper_data.image_size = pe[2]; - - - client.read_stream(client.mapper_data.imports);*/ - } - - if (id == tcp::packet_id::ban) { - io::logger->error( - "your computer is blacklisted, please contact a developer."); - client.shutdown(); - return; - } - - io::logger->info("{}:{}->{} {}", packet.seq, packet.session_id, message, - id); - }); - - while (client) { - if (client.state == tcp::client_state::idle) { - std::string u; - getline(std::cin, u); - - std::string p; - getline(std::cin, p); - - auto l = fmt::format("{},{}", u, p); - - int ret = client.write(tcp::packet_t(l, tcp::packet_type::write, - client.session_id, - tcp::packet_id::login_req)); - - if (ret <= 0) { - break; - } - } - - if (client.state == tcp::client_state::logged_in) { - for (auto& dat : client.games) { - io::logger->info("[{}]{} : {}", dat.id, dat.name, dat.version); - } - io::logger->info("please select a game :"); - - int id; - std::cin >> id; - - - - } - - } - - std::cin.get(); + while (client) { + if (client.state == tcp::client_state::idle) { + std::string u; + getline(std::cin, u); + + std::string p; + getline(std::cin, p); + + if (client.state == tcp::client_state::logged_in) + continue; + + auto l = fmt::format("{},{}", u, p); + + int ret = client.write(tcp::packet_t(l, tcp::packet_type::write, + client.session_id, + tcp::packet_id::login_req)); + + if (ret <= 0) { + break; + } + } + + if (client.state == tcp::client_state::logged_in) { + for (auto& dat : client.games) { + io::logger->info("[{}]{} : {}", dat.id, dat.name, dat.version); + } + io::logger->info("please select a game :"); + + int id; + std::cin >> id; + + nlohmann::json j; + j["id"] = id; + + int ret = client.write(tcp::packet_t(j.dump(), tcp::packet_type::write, + client.session_id, + tcp::packet_id::game_select)); + + if (ret <= 0) { + break; + } + } + + } + + std::cin.get(); } diff --git a/client/src/shellcode/shellcode.cpp b/client/src/shellcode/shellcode.cpp deleted file mode 100644 index 67cbabf..0000000 --- a/client/src/shellcode/shellcode.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "../include.h" -#include "shellcode.h" - -void sc::generator::start() {} - -void sc::generator::push(const std::vector<uintptr_t>& args) { - if (!m_x64) { - for (auto it = args.rbegin(); it != args.rend(); ++it) { - m_assembler.push(*it); - } - return; - } - - // 64bit impl -} - -void sc::generator::call(const uintptr_t addr) {} - -void sc::generator::end() { - if (m_x64) { - } - - void* func; - m_runtime.add(&func, &m_code); - - const size_t size = m_code.codeSize(); - - m_buf.resize(size); - - std::memcpy(&m_buf[0], func, size); -}
\ No newline at end of file diff --git a/client/src/shellcode/shellcode.h b/client/src/shellcode/shellcode.h deleted file mode 100644 index 4a87dca..0000000 --- a/client/src/shellcode/shellcode.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include <asmjit/asmjit.h> - -using namespace asmjit; - -namespace sc { - -class generator { - std::vector<uint8_t> m_buf; - - CodeHolder m_code; - JitRuntime m_runtime; - x86::Assembler m_assembler; - - bool m_x64; - public: - generator(const bool x64 = false) : m_x64{x64} { - Environment env(x64 ? Environment::kArchX64 : Environment::kArchX86); - - m_code.init(env); - m_code.attach(&m_assembler); - } - - void start(); - void push(const std::vector<uintptr_t> &args); - void call(const uintptr_t addr); - void save_ret(const uintptr_t addr); - void end(); - - auto &operator()() const { return m_buf; } - auto &operator->() const { return m_assembler; } -}; - -};
\ No newline at end of file diff --git a/client/src/util/events.h b/client/src/util/events.h index b8d7781..67c4b1f 100644 --- a/client/src/util/events.h +++ b/client/src/util/events.h @@ -2,23 +2,23 @@ template <typename... Args> class event { - using func_type = std::function<void(Args...)>; + using func_type = std::function<void(Args...)>; - std::mutex event_lock; - std::list<func_type> m_funcs; + std::mutex event_lock; + std::list<func_type> m_funcs; - public: - void add(const func_type& func) { - std::lock_guard<std::mutex> lock(event_lock); +public: + void add(const func_type& func) { + std::lock_guard<std::mutex> lock(event_lock); - m_funcs.push_back(std::move(func)); - } + m_funcs.push_back(std::move(func)); + } - void call(Args... params) { - std::lock_guard<std::mutex> lock(event_lock); + void call(Args... params) { + std::lock_guard<std::mutex> lock(event_lock); - for (auto& func : m_funcs) { - if (func) func(std::forward<Args>(params)...); - } - } + for (auto& func : m_funcs) { + if (func) func(std::forward<Args>(params)...); + } + } };
\ No newline at end of file diff --git a/client/src/util/io.cpp b/client/src/util/io.cpp index 06d2b9a..019ec3f 100644 --- a/client/src/util/io.cpp +++ b/client/src/util/io.cpp @@ -4,9 +4,9 @@ std::shared_ptr<spdlog::logger> io::logger; void io::init() { - spdlog::sink_ptr sink = - std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); - sink->set_pattern("%^~>%$ %v"); + spdlog::sink_ptr sink = + std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); + sink->set_pattern("%^~>%$ %v"); - logger = std::make_shared<spdlog::logger>("client", sink); + logger = std::make_shared<spdlog::logger>("client", sink); } diff --git a/client/src/util/io.h b/client/src/util/io.h index b1a09f9..a69940e 100644 --- a/client/src/util/io.h +++ b/client/src/util/io.h @@ -5,7 +5,7 @@ #include <spdlog/sinks/stdout_color_sinks.h> namespace io { -extern std::shared_ptr<spdlog::logger> logger; + extern std::shared_ptr<spdlog::logger> logger; -void init(); + void init(); }; // namespace io diff --git a/client/src/util/native.h b/client/src/util/native.h index 623e577..bb80bd1 100644 --- a/client/src/util/native.h +++ b/client/src/util/native.h @@ -206,4 +206,10 @@ namespace native { uint32_t ReferenceCount; }; + using NtQuerySystemInformation = NTSTATUS(__stdcall*)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); + using NtOpenProcess = NTSTATUS(__stdcall*)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, CLIENT_ID*); + using NtReadVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID, PVOID, ULONG, PULONG); + using NtAllocateVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID*, ULONG, PULONG, ULONG, ULONG); + using NtWiteVirtualMemory = NTSTATUS(__stdcall*)(HANDLE, PVOID, PVOID, ULONG, PULONG); + }; // namespace native
\ No newline at end of file diff --git a/client/src/util/pe.h b/client/src/util/pe.h index a4d835d..56ba8ea 100644 --- a/client/src/util/pe.h +++ b/client/src/util/pe.h @@ -2,54 +2,54 @@ namespace pe { -class image { - std::unordered_map<std::string, uintptr_t> m_exports; + class image { + std::unordered_map<std::string, uintptr_t> m_exports; - IMAGE_NT_HEADERS64 *m_nt; - uintptr_t m_base; - bool m_valid; + IMAGE_NT_HEADERS64* m_nt; + uintptr_t m_base; + bool m_valid; - public: - image(){}; - image(const uintptr_t base) : m_valid{false}, m_base{base}, m_nt{nullptr} { - auto dos = reinterpret_cast<IMAGE_DOS_HEADER *>(base); - if (!dos || dos->e_magic != IMAGE_DOS_SIGNATURE) { - return; - } + public: + image() {}; + image(const uintptr_t base) : m_valid{ false }, m_base{ base }, m_nt{ nullptr } { + auto dos = reinterpret_cast<IMAGE_DOS_HEADER*>(base); + if (!dos || dos->e_magic != IMAGE_DOS_SIGNATURE) { + return; + } - m_nt = reinterpret_cast<IMAGE_NT_HEADERS64 *>(base + dos->e_lfanew); - if (m_nt->Signature != IMAGE_NT_SIGNATURE) { - return; - } + m_nt = reinterpret_cast<IMAGE_NT_HEADERS64*>(base + dos->e_lfanew); + if (m_nt->Signature != IMAGE_NT_SIGNATURE) { + return; + } - m_valid = true; - } + m_valid = true; + } - void parse_exports() { - auto dir = m_nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; - auto exp = - reinterpret_cast<IMAGE_EXPORT_DIRECTORY *>(m_base + dir.VirtualAddress); + void parse_exports() { + auto dir = m_nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + auto exp = + reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(m_base + dir.VirtualAddress); - if (exp->NumberOfFunctions == 0) return; + if (exp->NumberOfFunctions == 0) return; - auto names = reinterpret_cast<uint32_t *>(m_base + exp->AddressOfNames); - auto funcs = reinterpret_cast<uint32_t *>(m_base + exp->AddressOfFunctions); - auto ords = - reinterpret_cast<uint16_t *>(m_base + exp->AddressOfNameOrdinals); + auto names = reinterpret_cast<uint32_t*>(m_base + exp->AddressOfNames); + auto funcs = reinterpret_cast<uint32_t*>(m_base + exp->AddressOfFunctions); + auto ords = + reinterpret_cast<uint16_t*>(m_base + exp->AddressOfNameOrdinals); - if (!names || !funcs || !ords) return; + if (!names || !funcs || !ords) return; - for (size_t i{}; i < exp->NumberOfFunctions; i++) { - uintptr_t va = m_base + funcs[ords[i]]; - std::string name = reinterpret_cast<const char *>(m_base + names[i]); + for (size_t i{}; i < exp->NumberOfFunctions; i++) { + uintptr_t va = m_base + funcs[ords[i]]; + std::string name = reinterpret_cast<const char*>(m_base + names[i]); - m_exports[name] = va; - } - } + m_exports[name] = va; + } + } - auto &exports() { return m_exports; } + auto& exports() { return m_exports; } - operator bool() { return m_valid; } -}; + operator bool() { return m_valid; } + }; }; // namespace pe
\ No newline at end of file diff --git a/client/src/util/syscalls.cpp b/client/src/util/syscalls.cpp index 624ce5a..279a936 100644 --- a/client/src/util/syscalls.cpp +++ b/client/src/util/syscalls.cpp @@ -23,7 +23,7 @@ void syscalls::init() { uint16_t offset; auto idx = get_index(addr, offset); - if(!idx) continue; + if (!idx) continue; m_indexes[exp.first] = std::make_pair(idx, offset); @@ -49,7 +49,7 @@ void syscalls::init() { } } -bool syscalls::valid(const uintptr_t addr, const size_t &size) { +bool syscalls::valid(const uintptr_t addr, const size_t& size) { auto func = reinterpret_cast<uint8_t*>(addr); // mov r10, rcx @@ -70,13 +70,13 @@ bool syscalls::valid(const uintptr_t addr, const size_t &size) { return false; } -uint16_t syscalls::get_index(const uintptr_t va, uint16_t &offset) { +uint16_t syscalls::get_index(const uintptr_t va, uint16_t& offset) { auto func = reinterpret_cast<uint8_t*>(va); auto size = func_size(reinterpret_cast<uint8_t*>(va)); if (!valid(va, size)) { return 0; } - + for (size_t i{}; i < size; i++) { auto op = func[i]; if (op == 0xb8) { diff --git a/client/src/util/syscalls.h b/client/src/util/syscalls.h index 0d73e4e..45d0ee1 100644 --- a/client/src/util/syscalls.h +++ b/client/src/util/syscalls.h @@ -4,15 +4,15 @@ class syscalls { std::unordered_map<std::string, std::pair<uint16_t, uint16_t>> m_indexes; std::vector<char> m_stub; - void *m_call_table; + void* m_call_table; public: syscalls(); ~syscalls(); void init(); - bool valid(const uintptr_t func, const size_t &size); - uint16_t get_index(const uintptr_t va, uint16_t &offset); - size_t func_size(const uint8_t *func); - + bool valid(const uintptr_t func, const size_t& size); + uint16_t get_index(const uintptr_t va, uint16_t& offset); + size_t func_size(const uint8_t* func); + template<class T> T get(const std::string_view func) { return reinterpret_cast<T>(uintptr_t(m_call_table) + (m_indexes[func.data()].first * m_stub.size())); diff --git a/client/src/util/util.cpp b/client/src/util/util.cpp index a23c03c..dbee015 100644 --- a/client/src/util/util.cpp +++ b/client/src/util/util.cpp @@ -4,49 +4,49 @@ std::unordered_map<std::string, pe::image> util::loaded_modules; -std::string util::wide_to_multibyte(const std::wstring &str) { - std::string ret; - int32_t str_len; +std::string util::wide_to_multibyte(const std::wstring& str) { + std::string ret; + int32_t str_len; - // check if not empty str - if (str.empty()) - return{}; + // check if not empty str + if (str.empty()) + return{}; - // count size - str_len = WideCharToMultiByte(CP_UTF8, 0, &str[0], (int32_t) str.size(), 0, 0, 0, 0); + // count size + str_len = WideCharToMultiByte(CP_UTF8, 0, &str[0], (int32_t)str.size(), 0, 0, 0, 0); - // setup return value - ret = std::string(str_len, 0); + // setup return value + ret = std::string(str_len, 0); - // final conversion - WideCharToMultiByte(CP_UTF8, 0, &str[0], (int32_t) str.size(), &ret[0], str_len, 0, 0); + // final conversion + WideCharToMultiByte(CP_UTF8, 0, &str[0], (int32_t)str.size(), &ret[0], str_len, 0, 0); - return ret; + return ret; } native::_PEB* util::get_peb() { - return reinterpret_cast<native::_PEB*>(__readgsqword(0x60)); + return reinterpret_cast<native::_PEB*>(__readgsqword(0x60)); } bool util::init() { - auto peb = get_peb(); - if (!peb) return false; + auto peb = get_peb(); + if (!peb) return false; - if (!peb->Ldr->InMemoryOrderModuleList.Flink) return false; + if (!peb->Ldr->InMemoryOrderModuleList.Flink) return false; - auto* list = &peb->Ldr->InMemoryOrderModuleList; + auto* list = &peb->Ldr->InMemoryOrderModuleList; - for (auto i = list->Flink; i != list; i = i->Flink) { - auto entry = CONTAINING_RECORD(i, native::LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); - if (!entry) - continue; + for (auto i = list->Flink; i != list; i = i->Flink) { + auto entry = CONTAINING_RECORD(i, native::LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + if (!entry) + continue; - auto name = wide_to_multibyte(entry->BaseDllName.Buffer); - std::transform(name.begin(), name.end(), name.begin(), ::tolower); + auto name = wide_to_multibyte(entry->BaseDllName.Buffer); + std::transform(name.begin(), name.end(), name.begin(), ::tolower); - loaded_modules[name] = pe::image(entry->DllBase); - } + loaded_modules[name] = pe::image(entry->DllBase); + } - return true; + return true; } diff --git a/client/src/util/util.h b/client/src/util/util.h index b4bf699..8658ce6 100644 --- a/client/src/util/util.h +++ b/client/src/util/util.h @@ -5,22 +5,22 @@ namespace util { -extern std::unordered_map<std::string, pe::image> loaded_modules; + extern std::unordered_map<std::string, pe::image> loaded_modules; -std::string wide_to_multibyte(const std::wstring &str); + std::string wide_to_multibyte(const std::wstring& str); -native::_PEB *get_peb(); + native::_PEB* get_peb(); -bool init(); + bool init(); -static pe::image& ntdll() { - static pe::image nt{}; - if (!nt) { - nt = loaded_modules["ntdll.dll"]; - nt.parse_exports(); + static pe::image& ntdll() { + static pe::image nt{}; + if (!nt) { + nt = loaded_modules["ntdll.dll"]; + nt.parse_exports(); + } + return nt; } - return nt; -} }; // namespace util |