- UID
- 5524
注册时间2005-12-20
阅读权限95
最后登录1970-1-1
超级版主
   
TA的每日心情 | 开心 2019-2-27 15:18 |
|---|
签到天数: 205 天 [LV.7]常住居民III
|
关于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的对比图
.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也是比较常见的,把生成的劫持文件编译通过,函数没问题就行。这个应该更容易。
|
|