commit db899823d2ea73bfec2c30db17be13fc893e23d6 Author: Simplxs Date: Tue May 7 00:43:08 2024 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a8bc10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cbf7a36 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.15) + +project(SignerServer) + +# 平台宏定义 +if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") + add_definitions(-D _WIN_PLATFORM_) +elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") + add_definitions(-D _MAC_PLATFORM_) +elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + add_definitions(-D _LINUX_PLATFORM_) +endif() + + + +# 设置CPP标准 +set(CMAKE_CXX_STANDARD 17) + +file(GLOB SOURCE_FILES "./src/*.cpp") + +add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES}) \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..08276b4 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,17 @@ +#include "sign.h" +#include "server.h" + +#include + +int main() +{ + try + { + sign::InitSignCall(); + server::init(8080); + } + catch (const std::exception &e) + { + std::cerr << e.what() << std::endl; + } +} \ No newline at end of file diff --git a/src/proc_maps.cpp b/src/proc_maps.cpp new file mode 100644 index 0000000..65b36b2 --- /dev/null +++ b/src/proc_maps.cpp @@ -0,0 +1,117 @@ +#if defined(_MAC_PLATFORM_) || defined(_LINUX_PLATFORM_) + +#include "proc_maps.h" + +hak::proc_maps::proc_maps(uint64_t start, uint64_t end) +{ + this->_start = start; + this->_end = end; +} + +void hak::proc_maps::insert(std::shared_ptr maps) +{ // NOLINT(*-unnecessary-value-param) + if (maps == shared_from_this()) + return; + if (this->_tail == nullptr) + { + this->_tail = maps; + } + else + { + auto temp = this->_tail; + maps->_head = shared_from_this(); + maps->last()->_tail = temp; + this->_tail = maps; + } +} + +void hak::proc_maps::remove() +{ + _head->_tail = _tail; + _tail->_head = _head; +} + +auto hak::proc_maps::size() -> size_t +{ + size_t size = 1; + auto curr = shared_from_this(); + while ((curr = curr->next()) != nullptr) + { + size++; + } + return size; +} + +auto hak::proc_maps::start() const -> uint64_t +{ + return _start; +} + +auto hak::proc_maps::end() const -> uint64_t +{ + return _end; +} + +auto hak::proc_maps::next() -> std::shared_ptr & +{ + return _tail; +} + +auto hak::proc_maps::last() -> std::shared_ptr +{ + auto curr = shared_from_this(); + std::shared_ptr result = curr; + while ((curr = curr->next()) != nullptr) + { + result = curr; + } + return result; +} + +void llex_maps(pid_t pid, const std::function)> &callback) +{ + std::ifstream maps(std::string("/proc/") + (pid == 0 ? std::string("self") : std::to_string(pid)) + "/maps"); + if (!maps.is_open()) + throw "maps_not_found"; + std::string line; + bool last_is_cd = false; + while (getline(maps, line)) + { + std::istringstream iss(line); + std::vector tokens; + std::string token; + + while (getline(iss, token, ' ')) + tokens.push_back(token); + + auto address = tokens[0]; + std::string::size_type pos = address.find('-'); + uint64_t start_addr = std::stoull(address.substr(0, pos), nullptr, 16); + uint64_t end_addr = std::stoull(address.substr(pos + 1), nullptr, 16); + auto pmaps = std::make_shared(start_addr, end_addr); + auto perms = tokens[1]; + pmaps->readable = perms[0] == 'r'; + pmaps->writable = perms[1] == 'w'; + pmaps->executable = perms[2] == 'x'; + pmaps->is_private = perms[3] == 'p'; + pmaps->offset = std::stoull(tokens[2], nullptr, 16); + if (tokens.size() > 5) + for (int i = 5; i < tokens.size(); i++) + pmaps->module_name += tokens[i]; + callback(pmaps); + } +} + +auto hak::get_maps(pid_t pid) -> std::shared_ptr +{ + std::shared_ptr head; + llex_maps(pid, [&](std::shared_ptr maps) { // NOLINT(*-unnecessary-value-param) + if (head == nullptr) + head.swap(maps); + else + head->insert(maps); + }); + return head; +} + +#endif \ No newline at end of file diff --git a/src/proc_maps.h b/src/proc_maps.h new file mode 100644 index 0000000..1528c94 --- /dev/null +++ b/src/proc_maps.h @@ -0,0 +1,49 @@ +#ifndef PROC_MAPS_H +#define PROC_MAPS_H + +#include +#include +#include +#include +#include +#include + +#include "unistd.h" + +namespace hak { + class proc_maps: public std::enable_shared_from_this { + std::shared_ptr _head; + std::shared_ptr _tail; + + uint64_t _start; + uint64_t _end; + public: + proc_maps(uint64_t start, uint64_t end); + + bool readable = false; + bool writable = false; + bool executable = false; + bool is_private = false; + uint32_t offset = 0; + std::string module_name; + + void insert(std::shared_ptr maps); + + void remove(); + + // The speed of this api is not very fast~~~! + auto size() -> size_t; + + [[nodiscard]] auto start() const -> uint64_t; + + [[nodiscard]] auto end() const -> uint64_t; + + auto last() -> std::shared_ptr; + + auto next() -> std::shared_ptr&; + }; + + auto get_maps(pid_t pid = 0) -> std::shared_ptr; +} + +#endif // PROC_MAPS_H \ No newline at end of file diff --git a/src/server.cpp b/src/server.cpp new file mode 100644 index 0000000..9da6813 --- /dev/null +++ b/src/server.cpp @@ -0,0 +1,8 @@ +#include "server.h" +#include "sign.h" + + +void server::init(const int port) +{ + +} \ No newline at end of file diff --git a/src/server.h b/src/server.h new file mode 100644 index 0000000..a205293 --- /dev/null +++ b/src/server.h @@ -0,0 +1,5 @@ + +namespace server +{ + void init(const int port); +} \ No newline at end of file diff --git a/src/sign.cpp b/src/sign.cpp new file mode 100644 index 0000000..257ea40 --- /dev/null +++ b/src/sign.cpp @@ -0,0 +1,168 @@ +#include "sign.h" + +#include +#include +#include +#include +#include + +// #define _LINUX_PLATFORM_ +#define _WIN_PLATFORM_ + +#define _X64_ARCH_ + +#define CURRENT_ARCHITECTURE "x64" + +#if defined(_WIN_PLATFORM_) +#include +#include +#elif defined(_MAC_PLATFORM_) || defined(_LINUX_PLATFORM_) +#include +#include "proc_maps.h" +#endif + +// 签名函数定义 +#if defined(_WIN_PLATFORM_) +#define CURRENT_VERSION "9.9.9-23361" +#if defined(_X64_ARCH_) +std::map addrMap = { + {"9.9.2-16183", 0x2E0D0}, + {"9.9.9-23361", 0x2EB50}}; +#elif defined(_X86_ARCH_) +std::map addrMap = { + {"9.9.2-15962", 0x2BD70}, + {"9.9.2-16183", 0x2BD70}}; +#endif +#elif defined(_MAC_PLATFORM_) +#define CURRENT_VERSION "6.9.20-17153" +#if defined(_X64_ARCH_) +std::map addrMap = { + {"6.9.19-16183", 0x1B29469}}; +#elif defined(_ARM64_ARCH_) +std::map addrMap = { + {"6.9.20-17153", 0x1c73dd0}}; +#endif +#elif defined(_LINUX_PLATFORM_) +#define CURRENT_VERSION "3.2.7-23361" +#if defined(_X64_ARCH_) +std::map addrMap = { + {"3.1.2-12912", 0x33C38E0}, + {"3.1.2-13107", 0x33C3920}, + {"3.2.7-23361", 0x4C93C57}}; +#endif +#endif +int signOffsets = 767; // 562 in 3.1.2-12912 +int ExtraOffsets = 511; +int TokenOffsets = 255; + +std::vector Hex2Bin(std::string str) +{ + if (str.length() % 2 != 0) + throw std::invalid_argument("Hex string length must be even"); + std::vector bin(str.size() / 2); + for (size_t i = 0; i < str.size() / 2; i++) + { + std::stringstream ss; + ss << std::hex << str.substr(i * 2, 2); + ss >> bin[i]; + } + return bin; +} + +std::string Bin2Hex(const uint8_t *ptr, size_t length) +{ + const char table[] = "0123456789ABCDEF"; + std::string str; + str.resize(length * 2); + for (size_t i = 0; i < length; ++i) + { + str[2 * i] = table[ptr[i] / 16]; + str[2 * i + 1] = table[ptr[i] % 16]; + } + return str; +} + +typedef int (*SignFunctionType)(const char *cmd, const char *src, size_t src_len, int seq, unsigned char *result); +SignFunctionType SignFunction = nullptr; + +void sign::InitSignCall() +{ + uint64_t HookAddress = 0; +#if defined(_WIN_PLATFORM_) + HMODULE wrapperModule = GetModuleHandleW(L"wrapper.node"); + MODULEINFO modInfo; + if (wrapperModule == NULL || !GetModuleInformation(GetCurrentProcess(), wrapperModule, &modInfo, sizeof(MODULEINFO))) + return; + HookAddress = reinterpret_cast(wrapperModule) + addrMap[CURRENT_VERSION]; +#elif defined(_MAC_PLATFORM_) + auto pmap = hak::get_maps(); + do + { + // printf("start: %llx, end: %llx, offset: %x, module_name: %s\n", pmap->start(), pmap->end(), pmap->offset, pmap->module_name.c_str()); + if (pmap->module_name.find("wrapper.node") != std::string::npos && pmap->offset == 0) + { + HookAddress = pmap->start() + addrMap[CURRENT_VERSION]; + printf("HookAddress: %llx\n", HookAddress); + break; + } + } while ((pmap = pmap->next()) != nullptr); +#elif defined(_LINUX_PLATFORM_) + auto pmap = hak::get_maps(); + do + { + // printf("start: %lx, end: %lx, offset: %x, module_name: %s\n", pmap->start(), pmap->end(), pmap->offset, pmap->module_name.c_str()); + if (pmap->module_name.find("wrapper.node") != std::string::npos && pmap->offset == 0) + { + HookAddress = pmap->start() + addrMap[CURRENT_VERSION]; + printf("HookAddress: %lx\n", HookAddress); + break; + } + } while ((pmap = pmap->next()) != nullptr); +#endif + if (HookAddress == 0) + throw std::runtime_error("Can't find hook address"); + SignFunction = reinterpret_cast(HookAddress); +} + +std::tuple sign::CallSign(const std::string cmd, const std::string src, const int seq) +{ + if (SignFunction == nullptr) + throw std::runtime_error("Sign function not initialized"); + + char *signArgCmd = new char[1024]; + char *signArgSrc = new char[1024]; + int32_t signSrc = 0; + int32_t signSeq = 0; + uint8_t *signResult = new uint8_t[1024]; + // 设置最大长度 + size_t str_size = 1024; + + printf("signArgCmd: %s\n", signArgCmd); + printf("signArgSrc: %s\n", signArgSrc); + printf("signSrc: %d\n", signSrc); + printf("signSeq: %d\n", signSeq); + + SignFunction(signArgCmd, signArgSrc, signSrc, signSeq, signResult); + + printf("signResult: %s\n", Bin2Hex(signResult, 1024).c_str()); + + // 获取大小 + uint8_t *signSize = (uint8_t *)signResult + signOffsets; + uint8_t *extraSize = (uint8_t *)signResult + ExtraOffsets; + uint8_t *tokenSize = (uint8_t *)signResult + TokenOffsets; + // 读取 + uint32_t signSizeU32 = *signSize; + uint32_t extraSizeU32 = *extraSize; + uint32_t tokenSizeU32 = *tokenSize; + uint8_t *signData = signResult + 512; + uint8_t *extraData = signResult + 256; + uint8_t *tokenData = signResult; + std::string signDataHex = Bin2Hex(signData, signSizeU32); + std::string extraDataHex = Bin2Hex(extraData, extraSizeU32); + std::string tokenDataHex = Bin2Hex(tokenData, tokenSizeU32); + // 回收资源 + delete[] signArgCmd; + delete[] signArgSrc; + delete[] signResult; + return std::make_tuple(signDataHex, extraDataHex, tokenDataHex); +} \ No newline at end of file diff --git a/src/sign.h b/src/sign.h new file mode 100644 index 0000000..3a317b1 --- /dev/null +++ b/src/sign.h @@ -0,0 +1,8 @@ +#include +#include + +namespace sign +{ + void InitSignCall(); + std::tuple CallSign(const std::string cmd, const std::string src, const int seq); +} \ No newline at end of file