Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
Repo
https://github.com/yfy227/repo
Admin
A very simple anti-debugging function.
Tokens:
3,001
Snippets:
16
Trust Score:
3.5
Update:
1 year ago
Context
Chat
Benchmark
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Starting Dynamic Security Check Scheduler C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This method starts a detached thread that periodically executes a random security check. It uses a SecureRandom instance to choose a check function and determines a random delay between checks to avoid predictable timing. ```C++ void start() { std::thread([this] { while (running) { int delay = rng.range(3000, 6000); // 3-6秒随机间隔 std::this_thread::sleep_for(std::chrono::milliseconds(delay)); execute_random_check(); } }).detach(); } void stop() { running = false; } ``` -------------------------------- ### Creating Global Protection Instance C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This line creates a global instance of the ProtectionManager class. The constructor of ProtectionManager is automatically called when the program starts (before main), initiating all the defined self-protection mechanisms. ```C++ ProtectionManager protection; ``` -------------------------------- ### Initializing Protection Manager C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt The ProtectionManager constructor initializes the main security features upon creation. It prevents core dumps, applies memory protection to critical functions, starts the dynamic check scheduler, and sets up signal handlers for detection of specific signals (SIGTRAP, SIGSEGV, SIGILL). ```C++ ProtectionManager() { CoreProtection::prevent_core_dump(); MemoryGuard::protect_all(); scheduler.start(); setup_signal_handlers(); } private: static void setup_signal_handlers() { struct sigaction sa{}; sa.sa_handler = [](int) { security_self_destruct("Signal triggered"); }; sigaction(SIGTRAP, &sa, nullptr); sigaction(SIGSEGV, &sa, nullptr); sigaction(SIGILL, &sa, nullptr); } ``` -------------------------------- ### Getting Self Executable Path C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static method retrieves the absolute path of the currently running executable. It uses the readlink system call on the /proc/self/exe symbolic link, which points to the executable file. ```C++ static std::string get_self_path() { char buf[PATH_MAX]; ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf)-1); return (len != -1) ? std::string(buf, len) : ""; } ``` -------------------------------- ### Implementing RAII for File Descriptors C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt The ScopedFD class provides Resource Acquisition Is Initialization (RAII) for Linux file descriptors (FDs). It automatically closes the FD when the object goes out of scope, preventing resource leaks. It takes an optional initial FD and provides a method to retrieve the wrapped FD. ```C++ class ScopedFD { int fd_; public: explicit ScopedFD(int fd = -1) : fd_(fd) {} ~ScopedFD() { if (fd_ != -1) close(fd_); } int get() const { return fd_; } }; ``` -------------------------------- ### Applying Memory Protection and Hook Checks C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static method iterates through a predefined list of function addresses and applies memory protection (PROT_READ) to the page containing the function code. It also performs a basic check for common hook instructions at the beginning of the function. ```C++ static void protect_all() { for (const auto& addr : function_addresses) { set_protection(addr); check_hooks(addr); } } private: static void set_protection(void* func) { const size_t page_size = sysconf(_SC_PAGESIZE); uintptr_t start = reinterpret_cast<uintptr_t>(func) & ~(page_size - 1); size_t length = page_size; if (mprotect(reinterpret_cast<void*>(start), length, PROT_READ) == -1) log_error("Memory protection failed", true); } static void check_hooks(void* func) { const uint8_t* code = static_cast<const uint8_t*>(func); const uint8_t danger_ops[] = {0xE9, 0xCC, 0x0F, 0x84}; // JMP, INT3, JZ 等指令 for (size_t i = 0; i < 1; ++i) { for (auto op : danger_ops) { if (code[i] == op) security_self_destruct("Hook detected"); } } } ``` -------------------------------- ### Implementing Dynamic Security Checks C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This class implements various dynamic security checks, including detecting Frida via TCP port and thread names, checking for LD_PRELOAD, detecting VPN interfaces, verifying memory integrity (via MemoryGuard), and checking for injected libraries in /proc/self/maps. These checks are executed randomly by the scheduler. ```C++ private: void execute_random_check() { switch (rng.range(0, 5)) { case 0: check_frida(); break; case 1: check_ld_preload(); break; case 2: check_vpn(); break; case 3: check_memory_integrity(); break; case 4: check_process_injection(); break; } } static void check_frida() { check_frida_port(27042); check_frida_threads(); } static void check_frida_port(int port) { int sock = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr{}; addr.sin_family = AF_INET; addr.sin_port = htons(port); inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); if (connect(sock, (sockaddr*)&addr, sizeof(addr)) == 0) security_self_destruct("Frida port detected"); close(sock); } static void check_frida_threads() { DIR* task_dir = opendir("/proc/self/task"); if (!task_dir) return; dirent* ent; while ((ent = readdir(task_dir))) { std::string comm_path = std::string("/proc/self/task/") + ent->d_name + "/comm"; std::ifstream comm(comm_path); std::string name; if (comm && getline(comm, name) && (name.find("gum-js") != std::string::npos || name.find("frida") != std::string::npos)) { security_self_destruct("Frida thread detected"); } } closedir(task_dir); } static void check_ld_preload() { if (getenv("LD_PRELOAD")) security_self_destruct("LD_PRELOAD detected"); } static void check_vpn() { ifaddrs* ifa; getifaddrs(&ifa); for (auto ptr = ifa; ptr; ptr = ptr->ifa_next) { std::string name(ptr->ifa_name); if (name.find("tun") != std::string::npos || name.find("ppp") != std::string::npos) { security_self_destruct("VPN detected"); } } freeifaddrs(ifa); } static void check_memory_integrity() { MemoryGuard::protect_all(); } static void check_process_injection() { std::ifstream maps("/proc/self/maps"); std::string line; while (getline(maps, line)) { if (line.find("libfrida") != std::string::npos) { security_self_destruct("Frida library injected"); } } } ``` -------------------------------- ### Initializing Protected Function Addresses C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static member definition initializes the list of function addresses that MemoryGuard will protect and check for hooks. It includes the addresses of the AntiDebug::ptrace_check and AntiDebug::tracerpid_check functions. ```C++ const std::vector<void*> MemoryGuard::function_addresses = { reinterpret_cast<void*>(AntiDebug::ptrace_check), reinterpret_cast<void*>(AntiDebug::tracerpid_check) }; ``` -------------------------------- ### Overwriting Self Executable C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static method attempts to overwrite the running executable file on disk. It copies the current executable to a temporary file, appends a random termination message, renames the temporary file to the original executable path, and exits. ```C++ static void overwrite_self() { std::string path = get_self_path(); if (path.empty()) log_error("Get self path failed", true); ScopedFD src(open(path.c_str(), O_RDONLY)); if (src.get() == -1) log_error("Open self failed", true); struct stat st; if (fstat(src.get(), &st) == -1) log_error("Fstat failed", true); std::string tmp = path + ".tmp"; ScopedFD dst(open(tmp.c_str(), O_WRONLY|O_CREAT|O_EXCL, 0600)); if (dst.get() == -1) log_error("Create temp failed", true); off_t offset = 0; if (sendfile(dst.get(), src.get(), &offset, st.st_size) == -1) log_error("File copy failed", true); std::string msg = "Terminated:" + std::to_string(SecureRandom().range(1,10000)) + "\n"; write(dst.get(), msg.data(), msg.size()); fsync(dst.get()); if (rename(tmp.c_str(), path.c_str()) == -1) log_error("Final rename failed", true); } ``` -------------------------------- ### Checking for Ptrace Debugging C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static method attempts to use the ptrace system call with the PTRACE_TRACEME request. If successful, it means the process is not being traced by another process. If it fails with errno indicating EPERM, it suggests a debugger is already attached. ```C++ PROTECT_FUNCTION static void ptrace_check() { if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) security_self_destruct("Ptrace detected"); } ``` -------------------------------- ### Preventing Core Dumps C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static method prevents the process from generating core dump files upon crashing. It sets the RLIMIT_CORE resource limit to zero using the setrlimit system call, enhancing security by preventing attackers from analyzing a crash dump. ```C++ static void prevent_core_dump() { rlimit limit{0, 0}; setrlimit(RLIMIT_CORE, &limit); } ``` -------------------------------- ### Checking TracerPid in Proc Status C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This static method checks the `/proc/self/status` file for the `TracerPid` field. If `TracerPid` is non-zero, it potentially indicates a debugger is attached. It then calls a helper function to check the name of the tracing process. ```C++ PROTECT_FUNCTION static void tracerpid_check() { std::ifstream status("/proc/self/status"); std::string line; while (getline(status, line)) { if (line.find("TracerPid:") == 0) { //兼容写法 int pid = std::stoi(line.substr(11)); if (pid != 0) check_debugger_process(pid); break; } } } private: static void check_debugger_process(int pid) { std::string comm = "/proc/" + std::to_string(pid) + "/comm"; std::ifstream f(comm); std::string name; if (f && getline(f, name) && (name.find("gdb") != std::string::npos || name.find("lldb") != std::string::npos)) { security_self_destruct("Debugger: " + name); } } ``` -------------------------------- ### Logging Security Errors C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This utility function logs security-related error messages to standard error. It optionally includes the system error message (`strerror(errno)`) and can trigger a critical exit if specified. This helps in debugging or reacting to critical failures. ```C++ void log_error(const std::string& msg, bool critical = false) { std::cerr << "[SECURITY] " << msg << " (" << strerror(errno) << ")\n"; if (critical) exit(EXIT_FAILURE); } ``` -------------------------------- ### Generating Secure Random Integers C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt The SecureRandom class wraps standard C++ random number generation facilities (std::random_device and std::mt19937) to provide a method for generating integers within a specified range. It seeds the generator using std::random_device for better randomness. ```C++ class SecureRandom { std::random_device rd; std::mt19937 gen; public: SecureRandom() : gen(rd()) {} int range(int min, int max) { std::uniform_int_distribution<> dist(min, max); return dist(gen); } }; ``` -------------------------------- ### Defining Security Self-Destruct Function C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt This function is called when a security threat or anomaly is detected. It logs the reason for the self-destruction, calls CoreProtection::overwrite_self to corrupt the executable file on disk, and then exits the process with a failure status. ```C++ void security_self_destruct(const std::string& reason) { log_error(reason, false); CoreProtection::overwrite_self(); exit(EXIT_FAILURE); } ``` -------------------------------- ### Defining Security Compiler Attributes C++ Source: https://github.com/yfy227/repo/blob/main/正式版v1.0.txt These macros define GCC/Clang attributes for functions. PROTECT_FUNCTION places the function in a special section and prevents inlining, potentially complicating analysis. SECURITY_ALWAYS_INLINE forces the compiler to inline the function. ```C++ #define PROTECT_FUNCTION __attribute__((section(".protected"))) __attribute__((noinline)) #define SECURITY_ALWAYS_INLINE __attribute__((always_inline)) ```