飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 119|回复: 4

[C/C++] 关于PPHijack工程文件的一些技术题外话

[复制链接]
  • TA的每日心情
    开心
    2019-2-27 15:18
  • 签到天数: 205 天

    [LV.7]常住居民III

    发表于 3 小时前 | 显示全部楼层 |阅读模式
    关于PPHijack工程文件的一些技术题外话

    起因:
    我们专注于用VS2026进行PPHijack功能完善与修复,考虑到工具应该生成最新的VS工程文件,但不是所有人都安装了VS2026,VS2022已经发布有好多年了,于是就想着生成VS2022 的工程,需要一个VS2022的sln文件,当时没有安装VS2022,一时半会儿也不想为了一个工程模板去下载这VS2022,更不想重复造轮子,本想着AI生成的,但是出于严谨考虑还是没采用。恰巧在网上发现了一个名为A***LibEx的工具,它能够生成VS2022的工程文件。于是,我们随手生成了一个DLL测试用例,在保留作者信息的前提下,原封不动地将其工程文件放入模板中进行适配,以便大家使用。为了功能开发,不想造轮子不得已为之,我们只想早点为大伙带来稳定的产品功能及体验

    在2025年12月1日发布PPHijackV1.0.0.1工具后,QQ群有人说是用了他的代码进行replace a to b,说是他的原创。
    VS的工程文件,如*.sln和*.vcxproj,本质上是微软的工程模板,随意生成一个即可,何谈原创?暂且不论这一点,我们已保留作者信息以表谢意,并在软件界面添加了滚动栏致谢。
    然而这人喋喋不休纠缠不放,还@我方管理人员,一天之内必须给他一个答复(解释),并拿 GPL3.0说事(遵循GPL得用了你的代码才行啊!我拿自己电脑上的一个sln文件也得给你GPL吗?)。
    不就是一个sln模板吗? 行,我自己生成总可以了吧,不再用你所谓的原创。下面就给你源码(附后面),让你看看什么是原创。

    科普一下:GPL协议主要约束的是源代码及其衍生作品的分发和修改,确保这些作品也以GPL许可方式发布,而非程序的输出。例如,sln文件作为项目文件,属于程序的输出部分,通常不被视为软件的“发布”,因此在大多数情况下,它不受GPL协议的约束。
    换句话说,类似于Hijack这种劫持生成工具或劫持代码本身以及其衍生品,本质上是不合法范畴,仅供学习和技术研究使用,不得用于非法用途,更不受法律保护。


    这东西又不是什么高科技玩意,不存在技术上的壁垒,随意新建一个工程复制一下就行了,根本用不着a to b这种做法!


    sln.jpg
    .sln的对比图

    vcxproj.jpg
    .vcxproj的对比图

    为什么有人会拿着微软生成的工程模板来当原创,这个原创到底在哪?

    现在我编写一段C++代码,可生成任意版本(vcxproj文件同理可推),后续更新将不再依赖所谓的原创内容,仅致谢关键代码发布者测试人员

    下面代码由 yosen2001 编写,版权归微软,随意复制,不需要遵循什么GPL3.0原则。

    GeneralSln.zip (2.11 KB, 下载次数: 10)


    以下代码仅供学习研究技术交流使用,产生的一切后果与本人无关。所有模板版权归归微软所有。
    [C++] 纯文本查看 复制代码
    // GeneralSln.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //;版权归微软所有,虽为yosen2001所写,你可以随意复制修改,不需要留有yosen2001的名字,也不需要感谢留名,不追究任何责任。
    
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <random>
    #include <ctime>
    
    // 生成 GUID 的函数(符合 GUID 格式)
    std::string generateGUID()
    {
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, 15);
        std::uniform_int_distribution<> dis2(8, 11); // 版本位
    
        const char* hex = "0123456789ABCDEF";
        std::string guid;
    
        // 第一部分: 8个字符
        for (int i = 0; i < 8; i++)
        {
            guid += hex[dis(gen)];
        }
        guid += '-';
    
        // 第二部分: 4个字符
        for (int i = 0; i < 4; i++)
        {
            guid += hex[dis(gen)];
        }
        guid += '-';
    
        // 第三部分: 4个字符(版本位设置)
        guid += '4'; // 版本4
        for (int i = 0; i < 3; i++)
        {
            guid += hex[dis(gen)];
        }
        guid += '-';
    
        // 第四部分: 4个字符(变体位设置)
        guid += hex[dis2(gen)]; // 变体位
        for (int i = 0; i < 3; i++)
        {
            guid += hex[dis(gen)];
        }
        guid += '-';
    
        // 第五部分: 12个字符
        for (int i = 0; i < 12; i++)
        {
            guid += hex[dis(gen)];
        }
    
        return guid;
    }
    
    std::string generateSolutionTemplate(const std::string& projectName,
        const std::string& projectGuid,
        const std::string& solutionGuid,
        const std::string& vsVersion)
    {
        return R"(
    # 这里随你加什么版本,yosen2001不追究
    # [url=http://www.chinapyg.com]www.chinapyg.com[/url]
    Microsoft Visual Studio Solution File, Format Version 12.00
    # Visual Studio Version 17
    VisualStudioVersion = <VS_VERSION>
    MinimumVisualStudioVersion = 10.0.40219.1
    Project("{<PROJECT_TYPE_GUID>}") = "<PROJECT_NAME>", "<PROJECT_NAME>\<PROJECT_NAME>.vcxproj", "{<PROJECT_GUID>}"
    EndProject
    Global
            GlobalSection(SolutionConfigurationPlatforms) = preSolution
                    Debug|x64 = Debug|x64
                    Debug|x86 = Debug|x86
                    Release|x64 = Release|x64
                    Release|x86 = Release|x86
            EndGlobalSection
            GlobalSection(ProjectConfigurationPlatforms) = postSolution
                    {<PROJECT_GUID>}.Debug|x64.ActiveCfg = Debug|x64
                    {<PROJECT_GUID>}.Debug|x64.Build.0 = Debug|x64
                    {<PROJECT_GUID>}.Debug|x86.ActiveCfg = Debug|Win32
                    {<PROJECT_GUID>}.Debug|x86.Build.0 = Debug|Win32
                    {<PROJECT_GUID>}.Release|x64.ActiveCfg = Release|x64
                    {<PROJECT_GUID>}.Release|x64.Build.0 = Release|x64
                    {<PROJECT_GUID>}.Release|x86.ActiveCfg = Release|Win32
                    {<PROJECT_GUID>}.Release|x86.Build.0 = Release|Win32
            EndGlobalSection
            GlobalSection(SolutionProperties) = preSolution
                    HideSolutionNode = FALSE
            EndGlobalSection
            GlobalSection(ExtensibilityGlobals) = postSolution
                    SolutionGuid = {<SOLUTION_GUID>}
            EndGlobalSection
    EndGlobal
    )";
    }
    
    // 替换模板中的占位符
    void replaceAll(std::string& str, const std::string& from, const std::string& to)
    {
        size_t start_pos = 0;
        while ((start_pos = str.find(from, start_pos)) != std::string::npos)
        {
            str.replace(start_pos, from.length(), to);
            start_pos += to.length();
        }
    }
    
    // 生成解决方案文件
    bool generateSolutionFile(const std::string& filename,
        const std::string& projectName = "MyProject",
        const std::string& vsVersion = "17.0.00000.000")
    {
        // 生成所有必要的GUID
        std::string projectTypeGuid = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; // VC++ 项目类型GUID
        std::string projectGuid = generateGUID();
        std::string solutionGuid = generateGUID();
    
        std::cout << "生成解决方案文件: " << filename << std::endl;
        std::cout << "项目名称: " << projectName << std::endl;
        std::cout << "项目类型GUID: " << projectTypeGuid << std::endl;
        std::cout << "项目GUID: " << projectGuid << std::endl;
        std::cout << "解决方案GUID: " << solutionGuid << std::endl;
        std::cout << "Visual Studio版本: " << vsVersion << std::endl;
    
        // 生成模板
        std::string solutionContent = generateSolutionTemplate(projectName, projectGuid, solutionGuid, vsVersion);
    
        // 替换占位符
        replaceAll(solutionContent, "<PROJECT_NAME>", projectName);
        replaceAll(solutionContent, "<PROJECT_TYPE_GUID>", projectTypeGuid);
        replaceAll(solutionContent, "<PROJECT_GUID>", projectGuid);
        replaceAll(solutionContent, "<SOLUTION_GUID>", solutionGuid);
        replaceAll(solutionContent, "<VS_VERSION>", vsVersion);
    
        // 写入文件
        std::ofstream file(filename);
        if (!file.is_open())
        {
            std::cerr << "错误: 无法创建文件 " << filename << std::endl;
            return false;
        }
    
        file << solutionContent;
        file.close();
    
        std::cout << "解决方案文件已成功生成!" << std::endl;
        return true;
    }
    
    int main()
    {
        // 从用户获取输入
        std::string projectName;
        std::string filename;
        std::string vsVersion = "17.0.00000.000";
    
        std::cout << "=== Visual Studio 解决方案生成器 ===" << std::endl;
        std::cout << "请输入项目名称: ";
        std::getline(std::cin, projectName);
    
        if (projectName.empty())
        {
            projectName = "MyProject";
        }
    
        std::cout << "请输入输出文件名 (默认: " << projectName << ".sln): ";
        std::getline(std::cin, filename);
    
        if (filename.empty())
        {
            filename = projectName + ".sln";
        }
    
        // 确保文件扩展名是 .sln
        if (filename.find(".sln") == std::string::npos)
        {
            filename += ".sln";
        }
    
        std::cout << "请输入Visual Studio版本 (默认: " << vsVersion << "): ";
        std::string inputVersion;
        std::getline(std::cin, inputVersion);
    
        if (!inputVersion.empty())
        {
            vsVersion = inputVersion;
        }
    
        // 生成解决方案文件
        if (generateSolutionFile(filename, projectName, vsVersion))
        {
            std::cout << "生成完成!文件: " << filename << std::endl;
        }
        else
        {
            std::cerr << "生成失败!" << std::endl;
            return 1;
        }
    
        return 0;
    }






    同时这里提供三个常见的dll,如果一个拿微软SLN工程模板就能当原创的,说明技术上也是可以的,可以自己【原创】写代码来把这三个dll生成工程和代码,编译通过应该不是什么问题。

    wbtrv32.zip (15.35 KB, 下载次数: 5)

    1.wbtrv32.dll,此为一网友提供的dll,感谢这位网友(虽然我不知道名字)及Nisy
    说明:这个dll生成劫持导出时有四个函数指向同一地址,怎么实现我想应该不难吧。

    dmdskmgr.zip (91.3 KB, 下载次数: 5)
    2.dmdskmgr.dll,此为微软自带的dll,可以在系统目录下找到,X64和X86都有。我这只提供了X86版本。
    说明:这个Dll也是比较普通,把导出函数生成之后编译通过就行。我想对于原创的人应该也很容易吧。

    SSCProt.zip (1.13 MB, 下载次数: 6)
    3.SSCProt.dll,此为某软件的COM组件,自己分析。
    说明:这个dll也是比较常见的,把生成的劫持文件编译通过,函数没问题就行。这个应该更容易。

    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2025-1-14 07:49
  • 签到天数: 1587 天

    [LV.Master]伴坛终老

    发表于 2 小时前 | 显示全部楼层
    友情帮顶 hoho
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-3-25 15:21
  • 签到天数: 487 天

    [LV.9]以坛为家II

    发表于 1 小时前 | 显示全部楼层
    药神妖僧出品必属精品,非盈利性的娱乐工具,普度众生,代码来源于网络,应用于网络,合理
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-1-11 18:37
  • 签到天数: 725 天

    [LV.9]以坛为家II

    发表于 半小时前 | 显示全部楼层
    然而这人喋喋不休纠缠不放,还@我方管理人员,一天之内必须给他一个答复(解释),并拿 GPL3.0说事

    这么事逼么
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表