本文前言

Source Insight 4 是一款非常强大的源代码编辑器和代码分析工具,而对于其授权过程的逆向分析网上已经有许多文章了,本文不再赘述,这里仅分享一个更方便的补丁,用于自动通过其授权而无需修改任何文件。

使用方式

相关项目及文件链接贴在了文章末尾,可以直接下载使用。

  1. 从官网下载并安装 Source Insight 4。
  2. msimg32.dll 复制到 Source Insight 4 的安装目录中。
  3. 运行 Source Insight 4 即可正常使用。

实现原理

通过在 Source Insight 4 的程序目录中伪造并代理其导入的系统库 msimg32.dll 来注入其进程,并使用微软的 Detours 库劫持其哈希校验和联网校验功能后自动生成授权文件以本地激活。

劫持校验功能

  • 劫持哈希校验功能部分

    BOOL Patch::CryptVerifySignatureW(HCRYPTHASH hHash, const BYTE* pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR szDescription, DWORD dwFlags) {
        // 跳过签名验证
        return TRUE;
    }
  • 劫持联网校验功能部分

    HINTERNET Patch::InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags) {
        // 阻止检查授权,防止序列号被加入在线黑名单
        // 检查授权的 UA 是 Source Insight,检查更新的 UA 是 SourceInsight/4.0
        if (std::wcscmp(lpszAgent, L"Source Insight") == 0) {
            SetLastError(ERROR_ACCESS_DENIED);
            return NULL;
        }
        return internetOpenW(lpszAgent, dwAccessType, lpszProxy, lpszProxyBypass, dwFlags);
    }

授权文件生成

  • 生成序列号部分

    wchar_t LicenseSerial::GenerateRandomLetterOrDigit() {
        std::uniform_int_distribution<uint16_t> distribution(0, 35);
        uint16_t randomValue = distribution(randomEngine);
        if (randomValue < 10) {
            return L'0' + randomValue;
        } else {
            return L'A' + randomValue - 10;
        }
    }
    
    wchar_t LicenseSerial::GenerateRandomRGDF() {
        std::uniform_int_distribution<uint16_t> distribution(0, 3);
        switch (distribution(randomEngine)) {
            case 0:
                return L'R';
            case 1:
                return L'G';
            case 2:
                return L'D';
            default:
                return L'F';
        }
    }
    
    std::wstring LicenseSerial::Generate() {
        std::wstring serial(19, L'-');
        wchar_t* serialData = serial.data();
        serialData[0] = L'S';
        serialData[1] = L'4';
        serialData[2] = L'S';
        serialData[3] = L'G';
        serialData[5] = GenerateRandomLetterOrDigit();
        serialData[6] = GenerateRandomRGDF();
        serialData[7] = GenerateRandomLetterOrDigit();
        serialData[8] = GenerateRandomLetterOrDigit();
        for (size_t i = 0; i < 4; i++) {
            serialData[i + 10] = GenerateRandomLetterOrDigit();
        }
        for (size_t i = 0; i < 4; i++) {
            uint8_t hash = substitutionTable[serialData[0] + i];
            for (size_t j = 1; j < 15; j++) {
                hash = substitutionTable[serialData[j] ^ hash];
            }
            serialData[i + 15] = alphabetTable[hash % 26];
        }
        return serial;
    }
  • 生成授权文件部分

    void License::EnsureAvailability() {
        // 获取 %ProgramData%\Source Insight\4.0\si4.lic 文件路径,如果父目录不存在则创建
        std::array<wchar_t, MAX_PATH> commonAppDataPath;
        if (SHGetFolderPathW(nullptr, CSIDL_COMMON_APPDATA, nullptr, 0, commonAppDataPath.data()) != S_OK) {
            throw std::runtime_error("Failed to get CSIDL_COMMON_APPDATA path, error code: " + std::to_string(GetLastError()));
        }
        std::filesystem::path licenseFilePath = std::filesystem::path(commonAppDataPath.data()) / L"Source Insight" / L"4.0" / L"si4.lic";
        std::filesystem::create_directories(licenseFilePath.parent_path());
    
        // 如果 License 文件不存在或不包含 SourceInsight4Patch 字符串,则生成一个新的
        std::wfstream licenseFile;
        licenseFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
        if (std::filesystem::exists(licenseFilePath)) {
            licenseFile.open(licenseFilePath, std::ios::in);
            std::span<const wchar_t> magic(L"SourceInsight4Patch", 19);
            std::istreambuf_iterator<wchar_t> end;
            if (std::search(std::istreambuf_iterator<wchar_t>(licenseFile), end, magic.begin(), magic.end()) != end) {
                licenseFile.close();
                return;
            }
            licenseFile.close();
        }
        licenseFile.open(licenseFilePath, std::ios::out | std::ios::trunc);
        LicenseSerial licenseSerial;
        std::chrono::time_point now = std::chrono::system_clock::now();
        licenseFile << std::format(L"<SourceInsightLicense>\n" \
                                   L"    <LicenseProperties ActId=\"\"\n" \
                                   L"                       HWID=\"\"\n" \
                                   L"                       Serial=\"{:s}\"\n" \
                                   L"                       LicensedUser=\"SourceInsight4Patch\"\n" \
                                   L"                       Organization=\"Fox\"\n" \
                                   L"                       Email=\"\"\n" \
                                   L"                       Type=\"Standard\"\n" \
                                   L"                       Version=\"4\"\n" \
                                   L"                       MinorVersion=\"0\"\n" \
                                   L"                       Date=\"{:%Y-%m-%d}\" />\n" \
                                   L"    <Signature Value=\"SourceInsight4Patch\" />\n" \
                                   L"</SourceInsightLicense>", licenseSerial.Generate(), now);
        licenseFile.close();
    }

代理库代码生成

使用 ProxyPESourceGenerator 生成用于代理 msimg32.dll 的源代码。

免责声明

本项目仅用于学习和研究目的,不得用于商业或非法用途,如果您喜欢该程序,请购买注册以支持正版软件。

下载链接