我一直在考虑如何保护我的C/C++代码免于反汇编和逆向工程.通常我永远不会在我的代码中宽恕这种行为; 然而,为了各种人的安全,我一直在努力的现行协议绝不能被检查或理解.
现在这对我来说是一个新的主题,互联网并不是真正有效防范逆向工程,而是描绘了大量有关如何逆向工程的信息
到目前为止我想到的一些事情是:
编写我自己的启动例程(调试器更难绑定)
void startup();
int _start()
{
startup( );
exit (0)
}
void startup()
{
/* code here */
}
Run Code Online (Sandbox Code Playgroud)运行时检查调试器(如果检测到则强制退出)
功能蹦床
void trampoline(void (*fnptr)(), bool ping = false)
{
if(ping)
fnptr();
else
trampoline(fnptr, true);
}
Run Code Online (Sandbox Code Playgroud)无意义的分配和解除分配(堆栈变化很多)
我的意思是这些是我所想到的一些事情,但是在适当的时间范围内,它们都可以被代码分析师解决或者解决.我还有其他选择吗?
我正在尝试找到一个迭代包变量模板参数列表的方法.现在和所有迭代一样,您需要某种方法来了解打包列表中有多少参数,更重要的是如何从打包参数列表中单独获取数据.
一般的想法是迭代列表,将int类型的所有数据存储到向量中,将char*类型的所有数据存储到向量中,并将float类型的所有数据存储到向量中.在这个过程中,还需要一个单独的向量来存储参数进入顺序的各个字符.例如,当你push_back(a_float)时,你也在做一个push_back('f'),它只是存储一个单独的char来了解数据的顺序.我也可以在这里使用std :: string,只需使用+ =.该矢量仅用作示例.
现在,事物的设计方式是功能本身是使用宏构建的,尽管存在恶意,但它是必需的,因为这是一个实验.因此,使用递归调用几乎是不可能的,因为将包含所有这些的实际实现将在编译时扩展; 你不能招募一个宏.
尽管有各种可能的尝试,我仍然坚持要弄清楚如何实际做到这一点.所以相反,我使用了一个更复杂的方法,包括构造一个类型,并将该类型传递到varadic模板,在一个向量中扩展它,然后简单地迭代它.但是我不想像以下那样调用函数:
foo(arg(1), arg(2.0f), arg("three");
Run Code Online (Sandbox Code Playgroud)
所以真正的问题是如果没有这样的话我该怎么办?为了让你们更好地理解代码实际在做什么,我已经粘贴了我目前正在使用的乐观方法.
struct any {
void do_i(int e) { INT = e; }
void do_f(float e) { FLOAT = e; }
void do_s(char* e) { STRING = e; }
int INT;
float FLOAT;
char *STRING;
};
template<typename T> struct get { T operator()(const any& t) { return T(); } };
template<> struct get<int> { int operator()(const any& t) { return t.INT; } };
template<> struct get<float> { float operator()(const any& …Run Code Online (Sandbox Code Playgroud) 通过反复试验引起我的注意,有一些依赖于某种编译器魔术(TM)的certian C++ 11特性.我一直在搞乱实现我自己的标准符合标准的stdlib.我知道有很多可用的stdlib实现,但是这个更适合我个人版本的小应用程序.
昨晚我std::initializer_list根据规范实现了,我无法使其工作,我搜索高低的通道只留下声明它是不可能的,并且它需要修改编译器本身.好吧,我决定看看libstdc++它的当前实现,果然我的实现在设计上完全一样,边缘略有不同,我浪费了无数个小时搞清楚为什么实现不起作用,什么时候确切与设计相同的设计libstdc++.直到我意识到它必须在命名空间std之前六个小时.事实证明,实现是merley编译器的代理,这使得initializer_list可能,并且编译器本身搜索initializer_list该类namespace std.
我的问题是,我是否应该知道其他库函数需要某种特殊的编译器魔术才能工作,任何更隐藏的代理连接,或者为任何新的C++ 11库特性分离编译器内置?我想提前知道这些,所以当我实现依赖于编译器魔法的其他功能时,我可以做好准备,而不是浪费一整天通过反复试验来解决它; 这可能会变得单调乏味而且很烦人.
谢谢.
c++ compiler-construction initializer-list c++-standard-library c++11
我注意到很多boost和libc ++/libstdc ++在代码中明确地为SFINAE提供了一个默认值零
// libc++ http://llvm.org/svn/llvm-project/libcxx/trunk/include/memory
namespace __has_pointer_type_imp
{
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::pointer* = 0);
}
template <class _Tp>
struct __has_pointer_type
: public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1>
{
};
Run Code Online (Sandbox Code Playgroud)
然而,当我们明确地用0调用它时,为什么会出现这种情况让我感到困惑.我记得听到某个地方它是一个优化(在实例化模板时加速编译器)但我不完全理解它是如何工作的.我查看了标准,它有一个部分简要描述了与模板参数推导相关的default-arguments会发生什么.
14.8.2
在模板参数推导过程中的某些点,有必要采用一个使用模板参数的函数类型,并用相应的模板参数替换这些模板参数.当任何显式指定的模板参数被替换为函数类型时,这在模板参数推导的开始处完成,并且当替换从默认参数推导或获得的任何模板参数时,再次在模板参数推断的结尾处完成.
最后一点听起来与我的问题有关
并且在模板参数推断结束时再次替换从默认参数推导或获得的任何模板参数.
然而,如果必须做更多工作,这听起来与优化相反.有没有人有任何理由为什么0必须在那里,它没有它工作,但libc ++中的每个SFINAE例子至少似乎明确地把0放在那里,即使他们从不调用没有参数的函数.