// ============================================================================
//  hwspoof.cpp —— 光速虚拟机 / VPhoneOS 内「华为 Mate30 全维伪装」工具
//  菜单：1 = 开启伪装   2 = 还原原始机型   3 = 自检   0 = 退出
//
//  目标机型：HUAWEI Mate30 (TAS-AN00 / HWTAS)
//            HarmonyOS 3.0 / Android 12 / SDK 31
//  适配环境：光速虚拟机 4.11.8 / 安卓12 / 64+32 混合，root 运行
//
//  编译（Termux 或 NDK，任一即可）：
//    clang++ -std=c++17 -O2 -static-libstdc++ -fPIE -pie -o hwspoof hwspoof.cpp
//
//  用法：
//    ./hwspoof            # 交互菜单
//    ./hwspoof 1          # 直接开启伪装
//    ./hwspoof 2          # 直接还原
//    ./hwspoof 3          # 自检
//
//  说明：
//   * 运行期属性优先用 resetprop（Magisk/KernelSU/APatch 自带）写入；
//     没有 resetprop 时自动降级为「改 build.prop 文件 + 重启生效」。
//   * 所有被改的属性、文件、设备节点都会备份到 /data/adb/hwspoof，
//     菜单 2 可完整还原。
//   * 不含任何联网代码。
// ============================================================================

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <sys/sysinfo.h>
#include <ctime>
#include <dirent.h>
#include <errno.h>

// ---------------------------------------------------------------------------
// 全局
// ---------------------------------------------------------------------------
static const char* TOOL_VER = "1.2";

static std::string g_state;      // 状态目录
static std::string g_resetprop;  // resetprop 路径，空 = 没有
static bool        g_dry = false;

// ---------------------------------------------------------------------------
// 基础工具
// ---------------------------------------------------------------------------
static bool fileExists(const std::string& p) {
    struct stat st;
    return ::stat(p.c_str(), &st) == 0;
}

static bool isDir(const std::string& p) {
    struct stat st;
    return ::stat(p.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
}

static bool mkdirs(const std::string& p) {
    if (p.empty()) return false;
    std::string cur;
    size_t i = 0;
    if (p[0] == '/') { cur = "/"; i = 1; }
    while (i <= p.size()) {
        size_t j = p.find('/', i);
        if (j == std::string::npos) j = p.size();
        if (j > i) {
            cur += p.substr(i, j - i);
            if (!isDir(cur)) {
                if (::mkdir(cur.c_str(), 0700) != 0 && errno != EEXIST) return false;
            }
            cur += "/";
        }
        i = j + 1;
    }
    return true;
}

static std::string readFile(const std::string& p) {
    std::ifstream f(p, std::ios::binary);
    if (!f) return "";
    std::ostringstream ss;
    ss << f.rdbuf();
    return ss.str();
}

static bool writeFile(const std::string& p, const std::string& data) {
    if (g_dry) { printf("  [dry] 写 %s (%zu B)\n", p.c_str(), data.size()); return true; }
    std::ofstream f(p, std::ios::binary | std::ios::trunc);
    if (!f) return false;
    f.write(data.data(), (std::streamsize)data.size());
    return f.good();
}

// 执行命令并取回 stdout（自带 fork/exec，不依赖 glibc 的 /bin/sh）
static const char* shPath() {
    return fileExists("/system/bin/sh") ? "/system/bin/sh" : "/bin/sh";
}

static std::string sh(const std::string& cmd) {
    int fd[2];
    if (::pipe(fd) != 0) return "";
    pid_t pid = ::fork();
    if (pid == 0) {
        ::dup2(fd[1], 1);
        ::dup2(fd[1], 2);
        ::close(fd[0]);
        ::close(fd[1]);
        ::execl(shPath(), "sh", "-c", cmd.c_str(), (char*)nullptr);
        ::_exit(127);
    }
    ::close(fd[1]);
    std::string out;
    char buf[4096];
    ssize_t n;
    while ((n = ::read(fd[0], buf, sizeof(buf))) > 0) out.append(buf, (size_t)n);
    ::close(fd[0]);
    int st = 0;
    ::waitpid(pid, &st, 0);
    while (!out.empty() && (out.back() == '\n' || out.back() == '\r')) out.pop_back();
    return out;
}

static int shCode(const std::string& cmd) {
    if (g_dry) { printf("  [dry] %s\n", cmd.c_str()); return 0; }
    pid_t pid = ::fork();
    if (pid == 0) {
        int dn = ::open("/dev/null", O_WRONLY);
        if (dn >= 0) { ::dup2(dn, 1); ::dup2(dn, 2); }
        ::execl(shPath(), "sh", "-c", cmd.c_str(), (char*)nullptr);
        ::_exit(127);
    }
    if (pid < 0) return -1;
    int st = 0;
    ::waitpid(pid, &st, 0);
    return WIFEXITED(st) ? WEXITSTATUS(st) : -1;
}

static std::string trim(const std::string& s) {
    size_t a = s.find_first_not_of(" \t\r\n");
    if (a == std::string::npos) return "";
    size_t b = s.find_last_not_of(" \t\r\n");
    return s.substr(a, b - a + 1);
}

static std::string lower(std::string s) {
    for (auto& c : s) c = (char)std::tolower((unsigned char)c);
    return s;
}

static bool startsWith(const std::string& s, const std::string& p) {
    return s.size() >= p.size() && s.compare(0, p.size(), p) == 0;
}

static std::vector<std::string> split(const std::string& s, char d) {
    std::vector<std::string> r;
    std::string cur;
    for (char c : s) {
        if (c == d) { r.push_back(cur); cur.clear(); }
        else cur += c;
    }
    r.push_back(cur);
    return r;
}

static bool isRoot() { return ::geteuid() == 0; }

// ---------------------------------------------------------------------------
// 属性读写
// ---------------------------------------------------------------------------
static std::string propGet(const std::string& k) {
    return trim(sh("getprop '" + k + "' 2>/dev/null"));
}

struct PropEntry { std::string k, v; };

static std::vector<PropEntry> propList() {
    std::vector<PropEntry> r;
    std::string all = sh("getprop 2>/dev/null");
    std::istringstream ss(all);
    std::string line;
    while (std::getline(ss, line)) {
        if (line.size() < 4 || line[0] != '[') continue;
        size_t p1 = line.find("]: [");
        if (p1 == std::string::npos) continue;
        std::string k = line.substr(1, p1 - 1);
        size_t p2 = line.rfind(']');
        if (p2 <= p1 + 5) continue;
        std::string v = line.substr(p1 + 4, p2 - (p1 + 4));
        r.push_back({k, v});
    }
    return r;
}

static std::string findResetprop() {
    const char* cands[] = {
        "/data/adb/magisk/resetprop",
        "/debug_ramdisk/resetprop",
        "/data/adb/ksu/bin/resetprop",
        "/data/adb/ap/bin/resetprop",
        "/system/bin/resetprop",
        "/system/xbin/resetprop",
    };
    for (auto c : cands) if (fileExists(c)) return c;

    std::string p = sh("command -v resetprop 2>/dev/null");
    if (!p.empty() && fileExists(p)) return p;

    std::string m = sh("command -v magisk 2>/dev/null");
    if (!m.empty()) {
        if (shCode("magisk resetprop 2>/dev/null | grep -q .") == 0) return m + " resetprop";
    }
    return "";
}

static bool propSet(const std::string& k, const std::string& v) {
    if (g_dry) { printf("  [dry] setprop %s=%s\n", k.c_str(), v.c_str()); return true; }
    if (!g_resetprop.empty()) {
        bool magiskStyle = (g_resetprop.find("magisk") != std::string::npos);
        std::string cmd = magiskStyle
            ? "magisk resetprop -n '" + k + "' '" + v + "' >/dev/null 2>&1"
            : "'" + g_resetprop + "' -n '" + k + "' '" + v + "' >/dev/null 2>&1";
        if (shCode(cmd) == 0) return true;
        cmd = magiskStyle
            ? "magisk resetprop '" + k + "' '" + v + "' >/dev/null 2>&1"
            : "'" + g_resetprop + "' '" + k + "' '" + v + "' >/dev/null 2>&1";
        if (shCode(cmd) == 0) return true;
    }
    return shCode("setprop '" + k + "' '" + v + "' >/dev/null 2>&1") == 0;
}

static bool propDel(const std::string& k) {
    if (g_dry) { printf("  [dry] delprop %s\n", k.c_str()); return true; }
    if (!g_resetprop.empty()) {
        bool magiskStyle = (g_resetprop.find("magisk") != std::string::npos);
        std::string cmd = magiskStyle
            ? "magisk resetprop --delete '" + k + "' >/dev/null 2>&1"
            : "'" + g_resetprop + "' --delete '" + k + "' >/dev/null 2>&1";
        if (shCode(cmd) == 0) return true;
    }
    return false;
}

// ---------------------------------------------------------------------------
// 目标机型：HUAWEI Mate30 TAS-AN00 / HarmonyOS 3.0 / Android 12 / SDK 31
// ---------------------------------------------------------------------------
static std::vector<PropEntry> profileMate30() {
    const std::string INC  = "3.0.0.168(C00E110R5P2)";
    const std::string FP   =
        "HUAWEI/TAS-AN00/HWTAS:12/HUAWEITAS-AN00/" + INC + ":user/release-keys";
    const std::string DESC =
        "TAS-AN00-user 12 HUAWEITAS-AN00 " + INC + " release-keys";

    return {
        // ---- 构建标识 ----
        {"ro.build.id",                     "HUAWEITAS-AN00"},
        {"ro.build.display.id",             "TAS-AN00 " + INC},
        {"ro.build.version.incremental",    INC},
        {"ro.build.version.sdk",            "31"},
        {"ro.build.version.release",        "12"},
        {"ro.build.version.release_or_codename", "12"},
        {"ro.build.version.codename",       "REL"},
        {"ro.build.version.all_codenames",  "REL"},
        {"ro.build.version.preview_sdk",    "0"},
        {"ro.build.version.security_patch", "2022-09-01"},
        {"ro.build.version.emui",           "EmotionUI_12.0.0"},
        {"ro.build.version.base_os",        ""},
        {"ro.build.date",                   "Thu Sep 15 10:26:33 CST 2022"},
        {"ro.build.date.utc",               "1663208793"},
        {"ro.build.type",                   "user"},
        {"ro.build.tags",                   "release-keys"},
        {"ro.build.user",                   "jenkins"},
        {"ro.build.host",                   "hwemui"},
        {"ro.build.flavor",                 "HUAWEITAS-AN00-user"},
        {"ro.build.product",                "HWTAS"},
        {"ro.build.characteristics",        "default"},
        {"ro.build.description",            DESC},

        // ---- 指纹（六个分区保持一致）----
        {"ro.build.fingerprint",            FP},
        {"ro.system.build.fingerprint",     FP},
        {"ro.vendor.build.fingerprint",     FP},
        {"ro.product.build.fingerprint",    FP},
        {"ro.odm.build.fingerprint",        FP},
        {"ro.bootimage.build.fingerprint",  FP},
        {"ro.system_ext.build.fingerprint", FP},

        // ---- 产品身份 ----
        {"ro.product.brand",        "HUAWEI"},
        {"ro.product.manufacturer", "HUAWEI"},
        {"ro.product.model",        "TAS-AN00"},
        {"ro.product.name",         "TAS-AN00"},
        {"ro.product.device",       "HWTAS"},
        {"ro.product.board",        "TAS"},
        {"ro.product.marketname",   "HUAWEI Mate 30"},
        {"ro.product.locale",       "zh-CN"},
        {"ro.product.locale.language", "zh"},
        {"ro.product.locale.region",   "CN"},
        {"ro.product.first_api_level", "29"},

        // ---- CPU / ABI ----
        {"ro.product.cpu.abi",       "arm64-v8a"},
        {"ro.product.cpu.abilist",   "arm64-v8a,armeabi-v7a,armeabi"},
        {"ro.product.cpu.abilist32", "armeabi-v7a,armeabi"},
        {"ro.product.cpu.abilist64", "arm64-v8a"},
        {"ro.zygote",                "zygote64_32"},

        // ---- 平台 / 硬件（只走运行期，不写 build.prop）----
        {"ro.board.platform",       "kirin990"},
        {"ro.hardware",             "kirin990"},
        {"ro.soc.manufacturer",     "HiSilicon"},
        {"ro.soc.model",            "Kirin 990"},
        {"ro.opengles.version",     "196610"},
        {"ro.sf.lcd_density",       "480"},

        // ---- 调试面归零 ----
        {"ro.secure",          "1"},
        {"ro.adb.secure",      "1"},
        {"ro.debuggable",      "0"},
        {"ro.force.debuggable","0"},
        {"service.adb.root",   "0"},

        // ---- 启动状态（绿锁）----
        {"ro.boot.verifiedbootstate",  "green"},
        {"ro.boot.flash.locked",       "1"},
        {"ro.boot.vbmeta.device_state","locked"},
        {"ro.boot.veritymode",         "enforcing"},
        {"ro.boot.warranty_bit",       "0"},
        {"ro.boot.hardware",           "kirin990"},
        {"ro.boot.hardware.sku",       "TAS-AN00"},

        // ---- 虚拟机关键项置 0 ----
        {"ro.kernel.qemu", "0"},
        {"ro.boot.qemu",   "0"},

        // ---- 语言 / 其他 ----
        {"persist.sys.locale",     "zh-CN"},
        {"persist.sys.usb.config", "mtp"},
        {"net.hostname",           "HUAWEI_Mate_30"},
        {"ro.config.hw_quickpoweron",  "true"},
        {"ro.config.hw_power_saving",  "true"},
        {"ro.config.hw_volte_on",      "true"},
        {"ro.config.hw_voicerecord",   "true"},
    };
}

// ---------------------------------------------------------------------------
// VM 痕迹关键字：命中的属性直接删除
// ---------------------------------------------------------------------------
static const std::vector<std::string> kBlacklist = {
    "qemu", "goldfish", "ranchu", "cuttlefish", "android_vm", "emulator",
    "vbox", "vmware", "virtualbox", "genymotion", "bluestacks", "ldplayer",
    "redroid", "vmos", "vphone", "vpgg", "microvirt", "houdini",
    "magisk", "kernelsu", "apatch", "zygisk", "lsposed", "edxposed",
    "xposed", "frida", "shamiko", "swiftshader",
    "gspace", "alphamask", "vvb2060",
    "vivo", "pd1824", "v1824a"
};

static bool keepKey(const std::string& k) {
    static const char* keepPrefix[] = {
        "ro.zygote", "ro.dalvik.", "dalvik.",
        "ro.product.cpu.abilist", "ro.build.version.sdk",
        "ro.boot.", "ro.hardware.", "ro.soc.", "ro.board.",
        "ro.opengles", "ro.sf.", "ro.product.cpu.",
        "init.svc.", "sys.", "net.", "persist.sys.",
    };
    for (auto p : keepPrefix) if (startsWith(k, p)) return true;
    return false;
}

static bool hitBlack(const std::string& s) {
    std::string t = lower(s);
    for (auto& b : kBlacklist) if (t.find(b) != std::string::npos) return true;
    return false;
}

// ---------------------------------------------------------------------------
// 备份 / 还原
// ---------------------------------------------------------------------------
static std::string bakProps()   { return g_state + "/props.bak"; }
static std::string bakDeleted() { return g_state + "/deleted.bak"; }
static std::string nodeBak()    { return g_state + "/nodes.bak"; }
static std::string fileBakDir() { return g_state + "/filebak"; }

struct BakRec { std::string k, v; bool present = false; };

static std::vector<BakRec> loadBak(const std::string& path) {
    std::vector<BakRec> r;
    std::string all = readFile(path);
    std::istringstream ss(all);
    std::string line;
    while (std::getline(ss, line)) {
        if (line.empty() || line[0] == '#') continue;
        auto f = split(line, '\t');
        if (f.size() < 3) continue;
        r.push_back({f[0], f[2], f[1] == "1"});
    }
    return r;
}

static void saveBak(const std::string& path, const std::vector<BakRec>& recs) {
    std::string out = "# hwspoof backup v" + std::string(TOOL_VER) + "\n";
    for (auto& b : recs)
        out += b.k + "\t" + (b.present ? "1" : "0") + "\t" + b.v + "\n";
    writeFile(path, out);
}

static int backupKeys(const std::vector<std::string>& keys, const std::string& path) {
    auto recs = loadBak(path);
    std::map<std::string, bool> have;
    for (auto& r : recs) have[r.k] = true;

    int added = 0;
    for (auto& k : keys) {
        if (have.count(k)) continue;
        BakRec b;
        b.k = k;
        b.v = propGet(k);
        b.present = !b.v.empty();
        recs.push_back(b);
        have[k] = true;
        ++added;
    }
    if (added) saveBak(path, recs);
    return added;
}

// ---------------------------------------------------------------------------
// build.prop 文件层
// ---------------------------------------------------------------------------
static std::vector<std::string> propFiles() {
    return {
        "/system/build.prop",
        "/vendor/build.prop",
        "/product/build.prop",
        "/odm/etc/build.prop",
        "/system/etc/prop.default",
        "/vendor/default.prop",
        "/system/system/build.prop",
    };
}

static bool remountRw() {
    bool ok = false;
    for (const char* m : {"/", "/system", "/vendor", "/product", "/odm"}) {
        if (shCode(std::string("mount -o rw,remount ") + m) == 0 ||
            shCode(std::string("mount -o remount,rw ") + m) == 0)
            ok = true;
    }
    return ok;
}

static std::string bakNameOf(const std::string& path) {
    std::string n;
    for (char c : path) n += (c == '/') ? '_' : c;
    return fileBakDir() + "/" + n;
}

static int patchPropFile(const std::string& path, const std::vector<PropEntry>& attrs) {
    if (!fileExists(path)) return 0;

    std::string bak = bakNameOf(path);
    if (!fileExists(bak)) {
        mkdirs(fileBakDir());
        writeFile(bak, readFile(path));
    }

    std::string data = readFile(path);
    std::istringstream ss(data);
    std::string line;
    std::map<std::string, std::string> want;
    for (auto& a : attrs) want[a.k] = a.v;

    std::map<std::string, bool> done;
    std::ostringstream out;
    int changed = 0;

    while (std::getline(ss, line)) {
        std::string t = line;
        if (!t.empty() && t.back() == '\r') t.pop_back();
        size_t eq = t.find('=');
        if (eq != std::string::npos && !t.empty() && t[0] != '#') {
            std::string k = trim(t.substr(0, eq));
            auto it = want.find(k);
            if (it != want.end()) {
                if (!done[k]) {
                    out << k << "=" << it->second << "\n";
                    done[k] = true;
                    ++changed;
                }
                continue;
            }
        }
        out << t << "\n";
    }
    for (auto& a : attrs) {
        if (done[a.k] || a.v.empty()) continue;
        out << a.k << "=" << a.v << "\n";
        ++changed;
    }

    if (changed) writeFile(path, out.str());
    return changed;
}

static void restorePropFiles() {
    if (!isDir(fileBakDir())) return;
    DIR* d = ::opendir(fileBakDir().c_str());
    if (!d) return;
    struct dirent* e;
    while ((e = ::readdir(d))) {
        std::string n = e->d_name;
        if (n == "." || n == "..") continue;
        std::string target = n;
        std::replace(target.begin(), target.end(), '_', '/');
        std::string bak = fileBakDir() + "/" + n;
        if (fileExists(target)) {
            writeFile(target, readFile(bak));
            printf("  还原文件 %s\n", target.c_str());
        }
    }
    ::closedir(d);
}

// ---------------------------------------------------------------------------
// /proc 伪装
// ---------------------------------------------------------------------------
static std::string fakeCpuinfo() {
    std::ostringstream o;
    for (int i = 0; i < 8; ++i) {
        const char* part = (i < 4) ? "0xd0b" : "0xd05";
        o << "processor\t: " << i << "\n"
          << "BogoMIPS\t: 26.00\n"
          << "Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm dcpop\n"
          << "CPU implementer\t: 0x41\n"
          << "CPU architecture: 8\n"
          << "CPU variant\t: 0x1\n"
          << "CPU part\t: " << part << "\n"
          << "CPU revision\t: 0\n\n";
    }
    o << "Hardware\t: HiSilicon Kirin 990\n";
    return o.str();
}

static std::string fakeVersion() {
    return "Linux version 4.14.116 (HWEMUI@hwemui) (clang version 10.0.0 "
           "(https://android.googlesource.com/toolchain/llvm-project) ) "
           "#1 SMP PREEMPT Thu Sep 15 10:26:33 CST 2022\n";
}

static std::string fakeCmdline() {
    return "console=ttyAMA0,115200n8 earlycon=pl011,0xfff32000 "
           "androidboot.hardware=kirin990 androidboot.selinux=enforcing "
           "androidboot.verifiedbootstate=green androidboot.flash.locked=1 "
           "buildvariant=user\n";
}

struct MountRec { std::string src, dst; };

static std::vector<MountRec> mountPlan() {
    return {
        {g_state + "/cpuinfo", "/proc/cpuinfo"},
        {g_state + "/version", "/proc/version"},
        {g_state + "/cmdline", "/proc/cmdline"},
        {g_state + "/config.gz", "/proc/config.gz"},
        {g_state + "/kallsyms", "/proc/kallsyms"},
        {g_state + "/modules", "/proc/modules"},
        {g_state + "/stat", "/proc/stat"},
    };
}

static int fakeProcApply() {
    if (::getenv("HWSPOOF_NOMOUNT")) {
        printf("  [配置] HWSPOOF_NOMOUNT=1，跳过所有 /proc 挂载（无内核环境推荐）\n");
        return 0;
    }
    writeFile(g_state + "/cpuinfo", fakeCpuinfo());
    writeFile(g_state + "/version", fakeVersion());
    writeFile(g_state + "/cmdline", fakeCmdline());

    int ok = 0;
    for (auto& m : mountPlan()) {
        if (!fileExists(m.src) || !fileExists(m.dst)) continue;
        std::string cmd = "mount -o bind '" + m.src + "' '" + m.dst + "' >/dev/null 2>&1 || "
                          "mount --bind '" + m.src + "' '" + m.dst + "' >/dev/null 2>&1";
        if (shCode(cmd) == 0) { ++ok; printf("  挂载 %s -> %s\n", m.src.c_str(), m.dst.c_str()); }
        else printf("  [跳过] %s 挂载失败（SELinux 或内核限制）\n", m.dst.c_str());
    }
    return ok;
}

static void fakeProcRestore() {
    for (auto& m : mountPlan()) {
        shCode("umount '" + m.dst + "' >/dev/null 2>&1");
        printf("  卸载 %s\n", m.dst.c_str());
    }
}

// ---------------------------------------------------------------------------
// 虚拟机设备节点
// ---------------------------------------------------------------------------
static const std::vector<std::string> kDevNodes = {
    "/dev/qemu_pipe", "/dev/goldfish_pipe", "/dev/qemu_trace",
    "/dev/goldfish_sync", "/dev/qemu_props", "/dev/vport0p1",
};

static int hideDevNodes() {
    std::string out = "# path\tmode\n";
    int n = 0;
    for (auto& p : kDevNodes) {
        struct stat st;
        if (::stat(p.c_str(), &st) != 0) continue;
        out += p + "\t" + std::to_string((unsigned)(st.st_mode & 07777)) + "\n";
        if (::chmod(p.c_str(), 0000) == 0) ++n;
    }
    if (n) writeFile(nodeBak(), out);
    return n;
}

static void restoreDevNodes() {
    std::string all = readFile(nodeBak());
    std::istringstream ss(all);
    std::string line;
    while (std::getline(ss, line)) {
        if (line.empty() || line[0] == '#') continue;
        auto f = split(line, '\t');
        if (f.size() < 2) continue;
        unsigned mode = (unsigned)std::strtoul(f[1].c_str(), nullptr, 8);
        if (mode == 0) mode = 0660;
        if (::chmod(f[0].c_str(), mode) == 0)
            printf("  恢复权限 %s (%04o)\n", f[0].c_str(), mode);
    }
}

// 只报告，不删除（删了可能花屏）
static void reportVmFiles() {
    const char* paths[] = {
        "/system/bin/qemu-props", "/vendor/bin/qemu-props",
        "/system/bin/goldfish", "/system/lib64/libgoldfish.so",
        "/vendor/lib64/egl/libEGL_swiftshader.so",
        "/vendor/lib64/hw/gralloc.goldfish.so",
    };
    bool any = false;
    for (auto p : paths) {
        if (fileExists(p)) {
            if (!any) printf("\n  发现 VM 库/文件（未删除，避免花屏）：\n");
            printf("    %s\n", p);
            any = true;
        }
    }
}

// 只写运行期、不能写进 build.prop 的键（写进文件会导致开机加载不到 HAL / 改分辨率）
static bool runtimeOnlyKey(const std::string& k) {
    if (k == "ro.hardware" || k == "ro.board.platform") return true;
    if (startsWith(k, "ro.hardware.")) return true;
    if (startsWith(k, "ro.soc.")) return true;
    if (startsWith(k, "ro.boot.")) return true;
    if (k == "ro.sf.lcd_density" || k == "ro.opengles.version") return true;
    return false;
}

// ---------------------------------------------------------------------------
// 伪装
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// 序列号：VM 默认值（GO1E...）是明显特征，换成华为样式并固定下来
// ---------------------------------------------------------------------------
static std::string genSerial() {
    static const char* hex = "0123456789ABCDEF";
    std::string s = "5";
    std::srand((unsigned)(::time(nullptr) ^ (::getpid() << 16)));
    for (int i = 0; i < 15; ++i) s += hex[std::rand() % 16];
    return s;
}

static void ensureSerial() {
    std::string cur = propGet("ro.serialno");
    bool bad = cur.empty() || cur == "unknown" || cur == "default" ||
               cur.find("GO1E") != std::string::npos ||
               cur.find("0123456789") != std::string::npos ||
               cur.find("emulator") != std::string::npos;
    std::string s = trim(readFile(g_state + "/serial"));
    if (s.size() < 8) {
        s = genSerial();
        writeFile(g_state + "/serial", s + "\n");
    }
    if (bad) {
        propSet("ro.serialno", s);
        propSet("ro.boot.serialno", s);
        printf("[*] 序列号：%s -> %s\n", cur.empty() ? "(空)" : cur.c_str(), s.c_str());
    }
}
static int doApply() {
    printf("\n=== 开始伪装：HUAWEI Mate30 TAS-AN00（HarmonyOS 3.0 / Android 12 / SDK31）===\n");

    if (!isRoot()) { printf("[!] 需要 root：请先 su 再运行\n"); return 1; }

    auto attrs = profileMate30();

    std::vector<PropEntry> fileAttrs;
    for (auto& a : attrs) if (!runtimeOnlyKey(a.k)) fileAttrs.push_back(a);

    mkdirs(g_state);
    ::chmod(g_state.c_str(), 0700);

    g_resetprop = findResetprop();
    if (!g_resetprop.empty()) printf("[*] resetprop: %s\n", g_resetprop.c_str());
    else printf("[!] 未找到 resetprop：运行期属性无法写入，将改用 build.prop + 重启\n");

    std::vector<std::string> keys;
    for (auto& a : attrs) keys.push_back(a.k);
    int bk = backupKeys(keys, bakProps());
    printf("[*] 已备份 %d 个原始属性到 %s\n", bk, bakProps().c_str());

    int ok = 0, fail = 0;
    for (auto& a : attrs) {
        if (a.v.empty()) { propDel(a.k); continue; }
        if (propSet(a.k, a.v)) ++ok; else ++fail;
    }
    printf("[*] 属性写入：成功 %d，失败 %d\n", ok, fail);

    ensureSerial();

    // 清理 VM / root 痕迹属性
    auto all = propList();
    int del = 0;
    std::vector<BakRec> delRecs = loadBak(bakDeleted());
    std::map<std::string, bool> delHave;
    for (auto& r : delRecs) delHave[r.k] = true;
    for (auto& p : all) {
        if (p.k.empty()) continue;
        // init.svc.* / ro.boottime.* 里的 goldfish 痕迹必须删，不能被 keepKey 保护
        bool forced = startsWith(p.k, "init.svc") || startsWith(p.k, "ro.boottime.");
        if (keepKey(p.k) && !(forced && hitBlack(p.k))) continue;
        if (!hitBlack(p.k) && !hitBlack(p.v)) continue;
        if (!delHave.count(p.k)) {
            delRecs.push_back({p.k, p.v, true});
            delHave[p.k] = true;
        }
        if (propDel(p.k)) ++del;
    }
    if (!delRecs.empty()) saveBak(bakDeleted(), delRecs);
    printf("[*] 清除 VM/root 痕迹属性：%d 条\n", del);

    // build.prop 文件层（只写安全键）
    if (remountRw()) {
        int total = 0;
        for (auto& f : propFiles()) {
            int c = patchPropFile(f, fileAttrs);
            if (c) { printf("  改写 %s（%d 项）\n", f.c_str(), c); total += c; }
        }
        if (total) printf("[*] build.prop 层共改写 %d 项\n", total);
        else printf("[*] build.prop 层：无匹配键或文件不存在\n");
    } else {
        printf("[!] 分区无法 remount rw，跳过 build.prop 层（VM 里需先打开 system 可写）\n");
    }

    int m = fakeProcApply();
    if (m) printf("[*] /proc 伪装：%d 项挂载成功\n", m);

    int dn = hideDevNodes();
    if (dn) printf("[*] 屏蔽 VM 设备节点 %d 个（仅改权限，可还原）\n", dn);

    shCode("settings put global device_name 'HUAWEI Mate 30'");
    shCode("settings put secure bluetooth_name 'HUAWEI Mate 30'");

    reportVmFiles();

    printf("\n[✓] 伪装完成\n");
    printf("    model       = %s\n", propGet("ro.product.model").c_str());
    printf("    brand       = %s\n", propGet("ro.product.brand").c_str());
    printf("    device      = %s\n", propGet("ro.product.device").c_str());
    printf("    fingerprint = %s\n", propGet("ro.build.fingerprint").c_str());
    printf("    sdk         = %s\n", propGet("ro.build.version.sdk").c_str());
    printf("\n    建议重启一次，让 build.prop 与 GMS 缓存全部刷新。\n");
    printf("    还原：菜单 2\n");
    return 0;
}

// ---------------------------------------------------------------------------
// 还原
// ---------------------------------------------------------------------------
static int doRestore() {
    printf("\n=== 还原原始机型 ===\n");
    if (!isRoot()) { printf("[!] 需要 root\n"); return 1; }

    g_resetprop = findResetprop();

    auto recs = loadBak(bakProps());
    if (recs.empty()) printf("[!] 没找到属性备份（%s）\n", bakProps().c_str());
    int ok = 0, fail = 0;
    for (auto& r : recs) {
        bool r2 = r.present ? propSet(r.k, r.v) : propDel(r.k);
        if (r2) ++ok; else ++fail;
    }
    printf("[*] 还原属性：成功 %d，失败 %d\n", ok, fail);

    auto dels = loadBak(bakDeleted());
    int back = 0;
    for (auto& r : dels) if (propSet(r.k, r.v)) ++back;
    if (!dels.empty()) printf("[*] 恢复被删除的痕迹属性：%d/%zu\n", back, dels.size());

    fakeProcRestore();
    restoreDevNodes();
    restorePropFiles();

    printf("\n[✓] 还原完成，建议重启虚拟机。\n");
    return 0;
}

// ---------------------------------------------------------------------------
// 自检
// ---------------------------------------------------------------------------
static void doVerify() {
    printf("\n=== 自检 ===\n");
    auto attrs = profileMate30();

    int ok = 0, bad = 0;
    for (auto& a : attrs) {
        if (a.v.empty()) continue;
        std::string cur = propGet(a.k);
        if (cur == a.v) ++ok;
        else {
            ++bad;
            printf("  [FAIL] %s\n         期望: %s\n         实际: %s\n",
                   a.k.c_str(), a.v.c_str(), cur.c_str());
        }
    }
    printf("\n属性核对：OK=%d FAIL=%d\n", ok, bad);

    printf("\n--- 残留 VM 痕迹 ---\n");
    bool any = false;
    for (auto& p : propList()) {
        if (keepKey(p.k)) continue;
        if (hitBlack(p.k) || hitBlack(p.v)) {
            printf("  [LEAK] %s = %s\n", p.k.c_str(), p.v.c_str());
            any = true;
        }
    }
    if (!any) printf("  未发现\n");

    printf("\n--- /proc ---\n");
    printf("  cpuinfo Hardware: %s\n", sh("grep -m1 Hardware /proc/cpuinfo 2>/dev/null").c_str());
    printf("  version: %s\n", sh("head -c 90 /proc/version 2>/dev/null").c_str());

    printf("\n--- 备份 ---\n");
    printf("  %s : %zu 条\n", bakProps().c_str(), loadBak(bakProps()).size());
    printf("  %s : %zu 条\n", bakDeleted().c_str(), loadBak(bakDeleted()).size());
}

// ---------------------------------------------------------------------------
// 菜单
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// 隐藏 Root / 反检测加固
//   能做的：root/证明态属性、SELinux 强制、/proc 内核信息遮蔽、日志清理
//   做不了的：TEE/attestation、GPU 字符串、Netlink 策略、KernelSU 侧信道
// ---------------------------------------------------------------------------
static std::string fakeStat() {
    std::string real = readFile("/proc/stat");
    double up = 0;
    std::string us = readFile("/proc/uptime");
    if (!us.empty()) up = atof(us.c_str());
    if (up <= 0.5) {
        struct sysinfo si;
        if (::sysinfo(&si) == 0) up = (double)si.uptime;
    }
    long now = (long)::time(nullptr);
    long btime = now - (long)up;
    if (btime < 0) btime = now;

    std::istringstream ss(real);
    std::ostringstream out;
    std::string line;
    bool done = false;
    while (std::getline(ss, line)) {
        if (startsWith(line, "btime ")) {
            out << "btime " << btime << "\n";
            done = true;
        } else {
            out << line << "\n";
        }
    }
    if (!done) out << "btime " << btime << "\n";
    return out.str();
}

static int doHideRoot() {
    printf("\n=== 隐藏 Root / 反检测加固 ===\n");
    if (!isRoot()) { printf("[!] 需要 root\n"); return 1; }

    mkdirs(g_state);
    ::chmod(g_state.c_str(), 0700);
    g_resetprop = findResetprop();

    // 1) root / 证明态属性
    std::vector<PropEntry> p = {
        {"ro.debuggable",              "0"},
        {"ro.secure",                  "1"},
        {"ro.adb.secure",              "1"},
        {"service.adb.root",           "0"},
        {"ro.build.type",              "user"},
        {"ro.build.tags",              "release-keys"},
        {"ro.boot.verifiedbootstate",  "green"},
        {"ro.boot.flash.locked",       "1"},
        {"ro.boot.warranty_bit",       "0"},
        {"ro.boot.vbmeta.device_state","locked"},
        {"ro.boot.veritymode",         "enforcing"},
        {"persist.sys.usb.config",     "mtp"},
    };
    std::vector<std::string> keys;
    for (auto& a : p) keys.push_back(a.k);
    backupKeys(keys, bakProps());
    int ok = 0;
    for (auto& a : p) if (propSet(a.k, a.v)) ++ok;
    printf("[*] root/证明态属性：%d/%zu\n", ok, p.size());

    // 2) SELinux
    std::string before = sh("getenforce 2>/dev/null");
    if (before != "Enforcing") shCode("setenforce 1");
    std::string after = sh("getenforce 2>/dev/null");
    printf("[*] SELinux: %s -> %s\n", before.c_str(), after.c_str());

    // 2.5) 进程可见性：VM 内核常没开 hidepid，普通应用能 ps 到 magiskd/zygiskd/su
    {
        std::string pm = sh("grep -m1 ' /proc ' /proc/mounts 2>/dev/null");
        if (pm.find("hidepid=2") == std::string::npos) {
            shCode("mount -o remount,hidepid=2,gid=3009 /proc");
            std::string pm2 = sh("grep -m1 ' /proc ' /proc/mounts 2>/dev/null");
            if (pm2.find("hidepid=2") != std::string::npos)
                printf("[*] /proc 已重挂为 hidepid=2（其他进程不可见）\n");
            else
                printf("[!] hidepid 重挂失败（内核不支持），进程级检测无法消除\n");
        } else {
            printf("[*] /proc 已是 hidepid=2\n");
        }
    }
    // 3) 遮蔽内核信息（截图里的 /proc/config.gz 暴露、btime 一致性）
    writeFile(g_state + "/config.gz", "");
    writeFile(g_state + "/kallsyms", "");
    writeFile(g_state + "/modules", "");
    writeFile(g_state + "/stat", fakeStat());
    int m = fakeProcApply();
    printf("[*] /proc 遮蔽：本次挂载成功 %d 项（含基础伪装）\n", m);

    // 4) 日志痕迹
    shCode("logcat -c");
    for (const char* d : {"/data/log", "/data/tombstones", "/data/anr", "/data/system/dropbox"})
        shCode(std::string("rm -rf ") + d + "/*");
    printf("[*] 已清空 logcat / log / tombstones / anr / dropbox\n");

    // 5) 结果
    printf("\n[✓] 已处理：\n");
    printf("    · 属性：debuggable/adb.secure/verifiedbootstate/flash.locked/warranty_bit\n");
    printf("    · SELinux：%s\n", after.c_str());
    printf("    · /proc：cpuinfo、version、cmdline、config.gz、kallsyms、modules、stat(btime 自洽)\n");
    printf("    · 日志：已清\n");
    printf("\n[!] 本工具处理不了、需要别的层：\n");
    printf("    · Attestation 证书链 / TEE 密钥 / AOSP key / Tampered key\n");
    printf("      → 只能上 TrickyStore + 有效 keybox，本工具不碰 keystore\n");
    printf("    · GPU 识别（Adreno via …）\n");
    printf("      → 需改 GPU 库字符串或 Zygisk hook，属进程内行为\n");
    printf("    · Netlink sock_diag 策略、KernelSU 侧信道\n");
    printf("      → 内核 / SELinux 策略层，用户态改不了\n");
    printf("    · 挂载 ID 一致性\n");
    printf("      → /proc 伪装必然新增 mount ID，深度检测可发现（无挂载就无此项）\n");
    return 0;
}
static void banner() {
    printf("\n\033[36m==============================================\033[0m\n");
    printf("\033[36m  华为 Mate30 全维伪装  v%s\033[0m\n", TOOL_VER);
    printf("\033[36m  目标: HUAWEI TAS-AN00 / HarmonyOS 3.0\033[0m\n");
    printf("\033[36m        Android 12 / SDK 31\033[0m\n");
    printf("\033[36m==============================================\033[0m\n");
    printf("  1) 开启伪装\n");
    printf("  2) 还原原始机型\n");
    printf("  3) 自检\n");
    printf("  4) 隐藏 Root / 反检测加固\n");
    printf("  0) 退出\n");
    printf("\033[33m请选择: \033[0m");
}

static void initState() {
    if (fileExists("/data/adb") || mkdirs("/data/adb"))
        g_state = "/data/adb/hwspoof";
    else
        g_state = "/data/local/hwspoof";
    mkdirs(g_state);
    ::chmod(g_state.c_str(), 0700);
}

#include "weiyan/Util.h"//导入微验库(每次注入的库不通用，请使用对应注入的库)
int main(int argc, char** argv) {
    // 微验接口域名
	const string n906a213bfa7d55c81b77901c5ea3f415 = "wy.llua.cn";
	// 当前版本，用于检查更新
	const string currentVersion = "1.0";
	// 卡密存储路径
	const string kmPath = "/sdcard/.km";
	
	// 获取公告
	string notice_data = httppost(n906a213bfa7d55c81b77901c5ea3f415,"v2/828c0f73f32dd63af2e9750e90b41b59",x6f6d969f2633a60f8b977d5a0bfe1516(f22d7f04ed940a411a6daf7309817eb92(x6f6d969f2633a60f8b977d5a0bfe1516(pae77a364a36799dcff03d2fa713565b6(x6f6d969f2633a60f8b977d5a0bfe1516(x6f6d969f2633a60f8b977d5a0bfe1516(pae77a364a36799dcff03d2fa713565b6("id=FHfcShFrrHF","a06218eff951a17bb467f89ca"))),"qaaeee6211e8b41a280334131e676505bf6d1")),"qXriuPsncTS487dHlVveYtDAL1K09oZwygWCfGmOFNM2hpR3+6jbEz/kxQIJU5aB")));
	//try {
		json notice_e6aa08c36b9a1d5deed9627c3bf2c4ad5 = json::parse(pae77a364a36799dcff03d2fa713565b6(m3247129730bf928b7c9c499ea3bf998f(notice_data),"d70093df96ae865a25759f9914b79483c115ed8"));
		if (notice_e6aa08c36b9a1d5deed9627c3bf2c4ad5.contains("msg")) {
			std::string gg = notice_e6aa08c36b9a1d5deed9627c3bf2c4ad5["msg"]["app_gg"];
			if (!gg.empty()) {
				std::cout << "公告:\n" << gg << std::endl;
			} else {
				std::cerr << "公告解析失败[-1]" << std::endl;
			}
		} else {
			std::cerr << "公告解析失败[-2]" << std::endl;
		}
	//}
	//catch(const std::exception & e) {
		//std::cerr << "公告获取失败" << e.what() << std::endl;
	//}
	std::cout << std::endl;
	
	// 检查更新
	string ini_data = httppost(n906a213bfa7d55c81b77901c5ea3f415,"v2/828c0f73f32dd63af2e9750e90b41b59",x6f6d969f2633a60f8b977d5a0bfe1516(f22d7f04ed940a411a6daf7309817eb92(x6f6d969f2633a60f8b977d5a0bfe1516(pae77a364a36799dcff03d2fa713565b6(x6f6d969f2633a60f8b977d5a0bfe1516(x6f6d969f2633a60f8b977d5a0bfe1516(pae77a364a36799dcff03d2fa713565b6("id=00Pse5206m6","a06218eff951a17bb467f89ca"))),"qaaeee6211e8b41a280334131e676505bf6d1")),"qXriuPsncTS487dHlVveYtDAL1K09oZwygWCfGmOFNM2hpR3+6jbEz/kxQIJU5aB")));
	//try {
		json ini_e6aa08c36b9a1d5deed9627c3bf2c4ad5 = json::parse(pae77a364a36799dcff03d2fa713565b6(m3247129730bf928b7c9c499ea3bf998f(ini_data),"d70093df96ae865a25759f9914b79483c115ed8"));
		if (ini_e6aa08c36b9a1d5deed9627c3bf2c4ad5.contains("msg")) {
			std::string version = ini_e6aa08c36b9a1d5deed9627c3bf2c4ad5["msg"]["version"];
			std::string updateshow = ini_e6aa08c36b9a1d5deed9627c3bf2c4ad5["msg"]["updateshow"];
			std::string updateurl = ini_e6aa08c36b9a1d5deed9627c3bf2c4ad5["msg"]["updateurl"];
			std::string updatemust = ini_e6aa08c36b9a1d5deed9627c3bf2c4ad5["msg"]["updatemust"];
			if (version != currentVersion){
				std::cout << "有新版本:" << std::endl << 	
				             "当前版本:" << currentVersion << std::endl <<
				             "最新版本:" << version << std::endl <<
				             "更新内容:" << updateshow << std::endl <<
				             "更新地址:" << updateurl << std::endl;
				if (updatemust == "y"){
		    	    std::cout << "强制更新，请更新至最新版本后使用！" << std::endl;
		    	    exit(0);
		        }
		    }
		} else {
			std::cerr << "更新解析失败" << std::endl;
		}
	//}
	//catch(const std::exception & e) {
		//std::cerr << "检查更新失败" << e.what() << std::endl;
	//}
	std::cout << std::endl;
	
	// 单码登录
	while(true){
	string i0795eeb8eff19715a61fbb45cc6e5d39;
	string z7014253bd89e492bea680695b22870f2 = getIMEI();
	std::cout << "请输入卡密(输入y使用上次登录卡密): ";
    std::cin >> i0795eeb8eff19715a61fbb45cc6e5d39;
    
    if (i0795eeb8eff19715a61fbb45cc6e5d39 == "y"){
    	ifstream file(kmPath);
        if (!file.is_open()) {
        	std::cout << "没有获取到上次登录卡密" << std::endl;
            continue;
        }
        getline(file, i0795eeb8eff19715a61fbb45cc6e5d39);
        file.close();
        std::cout << "使用上次卡密:" << i0795eeb8eff19715a61fbb45cc6e5d39 << std::endl;
    }
    
    std::random_device rd;
    std::mt19937 gen(rd()); // 使用 Mersenne Twister 引擎
    std::uniform_int_distribution<> dist(100000, 999999);
    
    auto now = std::chrono::system_clock::now();
    auto epoch = now.time_since_epoch();
    auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(epoch).count();
    
	string x33bcb16682d44ea85ae26a070bd184a7 = std::to_string(timestamp);
	string n76f10f23f662f41475faee17eaef2328 = std::to_string(dist(gen));
	string qcec69dcde9ed3357f754e5323a12cd7d = yfdfadbb9bc041492e7e4ae5665b2d48b("kami=" + i0795eeb8eff19715a61fbb45cc6e5d39 + "&markcode=" + z7014253bd89e492bea680695b22870f2 + "&t=" + x33bcb16682d44ea85ae26a070bd184a7 + "&s4917a5fe7b82d264fcc14f59e0e2");
	string l07a31f5f7c95cac404acce529a5f725b = httppost(n906a213bfa7d55c81b77901c5ea3f415,"v2/828c0f73f32dd63af2e9750e90b41b59",x6f6d969f2633a60f8b977d5a0bfe1516(f22d7f04ed940a411a6daf7309817eb92(x6f6d969f2633a60f8b977d5a0bfe1516(pae77a364a36799dcff03d2fa713565b6(x6f6d969f2633a60f8b977d5a0bfe1516(x6f6d969f2633a60f8b977d5a0bfe1516(pae77a364a36799dcff03d2fa713565b6("id=9VW9UrE9V9I&kami=" + i0795eeb8eff19715a61fbb45cc6e5d39 + "&markcode=" + z7014253bd89e492bea680695b22870f2 + "&t=" + x33bcb16682d44ea85ae26a070bd184a7 + "&sign=" + qcec69dcde9ed3357f754e5323a12cd7d + "&value=" + n76f10f23f662f41475faee17eaef2328 +"","a06218eff951a17bb467f89ca"))),"qaaeee6211e8b41a280334131e676505bf6d1")),"qXriuPsncTS487dHlVveYtDAL1K09oZwygWCfGmOFNM2hpR3+6jbEz/kxQIJU5aB")));
	//try {
		json e6aa08c36b9a1d5deed9627c3bf2c4ad5 = json::parse(pae77a364a36799dcff03d2fa713565b6(m3247129730bf928b7c9c499ea3bf998f(q6461970cd071c3f52f7df2e9c39760fa(q838970f494117388584d8b41d00bdf34(q838970f494117388584d8b41d00bdf34(pae77a364a36799dcff03d2fa713565b6(m3247129730bf928b7c9c499ea3bf998f(l07a31f5f7c95cac404acce529a5f725b),"z8c65280c132cec5052cc1f8a41feff"))),"uc8X9a+VTN5O4GDgKdBW2/iyjRehv3H7PQEtmlsZwqJF6xbpoMkfSYC1A0nrzLUI")),"z6fca51aa4e384c115081e60917ba7e12e8"));
		if (e6aa08c36b9a1d5deed9627c3bf2c4ad5["bfec5c6e7ad8c2946bc61cb13c089beb4"] == 74979 && e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["w13cfa95ab53a765fa470d1fb9e6e3929"] == "b9da909e4e957cfc6d9b6897a344acf7"){
            long b0696fdc111c901157b0488be3ec1a12f = e6aa08c36b9a1d5deed9627c3bf2c4ad5["f63aa8b4c5ffb09c5dadcb85da797cc98"];
            if (b0696fdc111c901157b0488be3ec1a12f-std::stol(x33bcb16682d44ea85ae26a070bd184a7)>30 || b0696fdc111c901157b0488be3ec1a12f-std::stol(x33bcb16682d44ea85ae26a070bd184a7)<-30){
                std::cout << "设备时间不准\n" << std::endl;
            }else{
                std::string y1aa7a3ee228c55871f81801dcb0d9305 = std::to_string(b0696fdc111c901157b0488be3ec1a12f);
                long z2ac165225e7bc81dfc20b5e7df47cc0b = e6aa08c36b9a1d5deed9627c3bf2c4ad5["bfec5c6e7ad8c2946bc61cb13c089beb4"];
                std::string ja168c1f95eb85cffa7ad0eb0ed781716 = std::to_string(z2ac165225e7bc81dfc20b5e7df47cc0b);
                long n45cc8ab6692457f5792605f01c6a1162 = e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["ob49298faea8a5410cfee732c40ac108b"];
                std::string me370f1fb775c6e7148356bf1be982b68 = std::to_string(n45cc8ab6692457f5792605f01c6a1162);
                if (e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["z4aa3eec29f"] != qf4abdc3e531697eb74d9e36f433e8d18(yfdfadbb9bc041492e7e4ae5665b2d48b(ja168c1f95eb85cffa7ad0eb0ed781716+y1aa7a3ee228c55871f81801dcb0d9305+"s4917a5fe7b82d264fcc14f59e0e2"+ja168c1f95eb85cffa7ad0eb0ed781716+"")) || e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["eb8000fca"] != qf4abdc3e531697eb74d9e36f433e8d18(yfdfadbb9bc041492e7e4ae5665b2d48b(yfdfadbb9bc041492e7e4ae5665b2d48b(qcec69dcde9ed3357f754e5323a12cd7d+x33bcb16682d44ea85ae26a070bd184a7+me370f1fb775c6e7148356bf1be982b68+""))) || e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["j9945fac20618"] != yfdfadbb9bc041492e7e4ae5665b2d48b(pe487c389b5c7ada35fa3198dfd91d1c1(pe487c389b5c7ada35fa3198dfd91d1c1(qcec69dcde9ed3357f754e5323a12cd7d+ja168c1f95eb85cffa7ad0eb0ed781716+me370f1fb775c6e7148356bf1be982b68+me370f1fb775c6e7148356bf1be982b68+""))) || e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["a9046443e"] != yfdfadbb9bc041492e7e4ae5665b2d48b(yfdfadbb9bc041492e7e4ae5665b2d48b(yfdfadbb9bc041492e7e4ae5665b2d48b(n76f10f23f662f41475faee17eaef2328+ja168c1f95eb85cffa7ad0eb0ed781716+x33bcb16682d44ea85ae26a070bd184a7+""))) || e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["db0636fa06f2d"] != qf4abdc3e531697eb74d9e36f433e8d18(qf4abdc3e531697eb74d9e36f433e8d18(qf4abdc3e531697eb74d9e36f433e8d18(qcec69dcde9ed3357f754e5323a12cd7d+qcec69dcde9ed3357f754e5323a12cd7d+x33bcb16682d44ea85ae26a070bd184a7+"")))){
                    std::cout << "校验失败\n" << std::endl;
                }else{
                    if (e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["ze4bd51bba4386e47928f211a94102f11"] == "single"){
                        std::cout << "登录成功，剩余可登录次数：" << e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["pc18c6a90d14b1008b2ab6b35be45c215"] << std::endl;
                    }else{
                        long oabd4c7174fc31b2ec3b896e1fa56a651 = e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"]["td183e8254c41167c77920514c0953eea"];
                        std::tm tm = *std::localtime(&oabd4c7174fc31b2ec3b896e1fa56a651 );
                        std::stringstream ss;
                        ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
                        std::cout << "登录成功，到期时间：" << ss.str() << std::endl;
                        //到期自动退出
				        signal(SIGALRM, _exit); 
                        alarm(oabd4c7174fc31b2ec3b896e1fa56a651-timestamp);
                    }
                    ofstream file(kmPath);
                    if (file.is_open()) {
                        file << i0795eeb8eff19715a61fbb45cc6e5d39 << endl;
                        file.close();
                    } else {
                        cerr << "无法保存卡密到文件: " << kmPath << endl;
                    }
			        break;
                }
            }
		}else{
		    std::string msg = e6aa08c36b9a1d5deed9627c3bf2c4ad5["w643164dd83ef6144b470e934220811b4"];
			std::cout << msg << std::endl;
		}
	//}
	//catch(const std::exception & e) {
		//std::cerr << "登录失败" << e.what() << std::endl;
	//}
	std::cout << std::endl;
	}
	
	
    ::setvbuf(stdout, nullptr, _IONBF, 0);
    initState();

    std::string act = (argc > 1) ? argv[1] : "";
    if (act == "1") return doApply();
    if (act == "2") return doRestore();
    if (act == "3") { doVerify(); return 0; }
    if (act == "4") return doHideRoot();

    for (;;) {
        banner();
        std::string line;
        if (!std::getline(std::cin, line)) break;
        line = trim(line);
        if (line == "1") doApply();
        else if (line == "2") doRestore();
        else if (line == "3") doVerify();
        else if (line == "4") doHideRoot();
        else if (line == "0" || line == "q") break;
        else printf("无效输入\n");
        printf("\n按回车继续...");
        std::getline(std::cin, line);
    }
    printf("再见\n");
    return 0;
}
