C++:强制 class 的单独实例以进行代码保护
C++: Force separate instances of a class for code protection
这听起来可能很奇怪,但出于混淆的目的,我想知道是否有办法在我的应用程序中创建 class 的多个实例,而不是让它们都重用相同的底层代码,编译器会为 class 创建完全独立的代码块。 class.
的内联排序
这需要在 Xcode 和 Visual Studio 中工作。
这样做的原因,平心而论,这是我只是在玩的一个想法...我正在寻找另一个级别来减慢黑客修补我的许可证代码的速度。通常,无论您多么努力地防止代码被黑客入侵,最终都会有一个地方您的代码 returns 类似于 true/false...此许可证有效吗?如果黑客发现了那个地方,那只是一个简单的补丁。我的想法是尝试将许可证代码,特别是相同的许可证 class,放在我的整个应用程序中......其中很多......并随时检查其中任何一个。如果做得好,黑客可能不得不找到其中的 10 个……不知道我的应用程序中确实有 20 个这样的东西。所有这一切都取决于编写一个 class,但它不能是同一段重复使用的 class 代码......它们需要全部分开。
有什么想法吗?
这里是一个attempt/proof的概念。我起草了一份 class 其中有:
- 一些基于模板参数的垃圾数据,因此很难重用数据布局。
- 一种基于模板参数的有副作用的方法,因此很难重用代码
人们应该意识到这很棘手,因为允许编译器对保留可观察行为的代码进行任何转换。因此,仅使用带有参数的模板,将生成两种不同类型的语言,但生成的代码可以重复用于两者。
我不确定经验丰富的黑客是否会对代码得出任何结论,甚至许可证检查代码本身是否会被复制。这是可能的。下面的代码显示 method
有两次出现,其中一次是循环,另一次被展开,参见 godbolt 装配线 108-113 和 134-142。
也就是说,优化通常是一个很好的混淆器。也许有时甚至比手工处理更好。
这是一种开始方式。一般 constexpr
和模板是我们在这种情况下的朋友,因为它们是在编译时处理的,我们需要确保生成唯一的东西。人们可能会尝试一些 constexpr
散列等
代码:
#include <string>
#include <iostream>
using std::string;
using std::cout;
template<int N>
struct B {
constexpr B() : arr() {
for (auto i = 0; i != N; ++i)
arr[i] = i;
}
int arr[N];
};
template<int Randomizer = 42>
struct A{
string a{"data_a"}; // probably all member should be templated by Randomizer
B<Randomizer> padding;
string b{"data_b"};
void method() {
cout << a << "\n";
for(int i = 0; i<Randomizer; i++) {
cout << padding.arr[i]; // harmless side effect
}
cout << "\n" << b << "\n";
}
};
int main () {
A<> i1;
A<3> i2;
i1.method();
i2.method();
return 0;
}
这听起来可能很奇怪,但出于混淆的目的,我想知道是否有办法在我的应用程序中创建 class 的多个实例,而不是让它们都重用相同的底层代码,编译器会为 class 创建完全独立的代码块。 class.
的内联排序这需要在 Xcode 和 Visual Studio 中工作。
这样做的原因,平心而论,这是我只是在玩的一个想法...我正在寻找另一个级别来减慢黑客修补我的许可证代码的速度。通常,无论您多么努力地防止代码被黑客入侵,最终都会有一个地方您的代码 returns 类似于 true/false...此许可证有效吗?如果黑客发现了那个地方,那只是一个简单的补丁。我的想法是尝试将许可证代码,特别是相同的许可证 class,放在我的整个应用程序中......其中很多......并随时检查其中任何一个。如果做得好,黑客可能不得不找到其中的 10 个……不知道我的应用程序中确实有 20 个这样的东西。所有这一切都取决于编写一个 class,但它不能是同一段重复使用的 class 代码......它们需要全部分开。
有什么想法吗?
这里是一个attempt/proof的概念。我起草了一份 class 其中有:
- 一些基于模板参数的垃圾数据,因此很难重用数据布局。
- 一种基于模板参数的有副作用的方法,因此很难重用代码
人们应该意识到这很棘手,因为允许编译器对保留可观察行为的代码进行任何转换。因此,仅使用带有参数的模板,将生成两种不同类型的语言,但生成的代码可以重复用于两者。
我不确定经验丰富的黑客是否会对代码得出任何结论,甚至许可证检查代码本身是否会被复制。这是可能的。下面的代码显示 method
有两次出现,其中一次是循环,另一次被展开,参见 godbolt 装配线 108-113 和 134-142。
也就是说,优化通常是一个很好的混淆器。也许有时甚至比手工处理更好。
这是一种开始方式。一般 constexpr
和模板是我们在这种情况下的朋友,因为它们是在编译时处理的,我们需要确保生成唯一的东西。人们可能会尝试一些 constexpr
散列等
代码:
#include <string>
#include <iostream>
using std::string;
using std::cout;
template<int N>
struct B {
constexpr B() : arr() {
for (auto i = 0; i != N; ++i)
arr[i] = i;
}
int arr[N];
};
template<int Randomizer = 42>
struct A{
string a{"data_a"}; // probably all member should be templated by Randomizer
B<Randomizer> padding;
string b{"data_b"};
void method() {
cout << a << "\n";
for(int i = 0; i<Randomizer; i++) {
cout << padding.arr[i]; // harmless side effect
}
cout << "\n" << b << "\n";
}
};
int main () {
A<> i1;
A<3> i2;
i1.method();
i2.method();
return 0;
}