如果我的代码中的几个地方都有这样的整数......
int my_secret = 42;
...是否有可能使编译程序中的整数更难找到?我已经看到这是用字符串完成的,例如通过将每个字母移动x个字符然后在运行时取消它们,但我怀疑这种技术是否适用于数字。
答案 0 :(得分:14)
这永远不会奏效。密钥永远不应该在代码中。在运行时创建它们。混淆肯定是诱惑性的。
答案 1 :(得分:3)
您可以通过编译器无法优化的某些函数在运行时计算它,使用数字的平方,然后通过数学库函数取平方根。
当然问题是这类东西都不能阻止一个坚定的人。
也可以说你真的不需要打扰。混淆字符串很有意义,因为有很多易于使用的工具可以从exe转储字符串。然而,你的42只会被编码为二进制数。整个exe只是一个很长的二进制数序列,并没有一个简单的工具来搜索42.你必须反汇编exe并理解汇编。无论你做什么,任何想要经历这么多麻烦的人都可能弄清楚这个数字。
所以简短的回答是不要打扰它,以便随意使用它。
答案 2 :(得分:2)
您可以通过在两个变量之间拆分此值来实现此目的。例如:
volatile int my_secret_1 = 20;
volatile int my_secret_2 = 22;
然后使用my_secret_1 + my_secret_2而不是my_secret。
需要使用volatile关键字,因为大多数(如果不是全部)c编译器都会优化它。无论如何,最好看看编译器生成的汇编代码。
答案 3 :(得分:2)
哈桑评论中的最初问题是关键问题。这取决于你保守秘密的内容,以及为什么有多少工作是值得的。一般来说,隐藏某些使用该程序的人(在某些时候)将这些值放在一起是不可能永远做到的。但是,你可以让攻击者更难。
然后问题就变成了你想要做多少工作才能使攻击者更难。然后你可以做任何代码混淆(不是非常安全,但可能会阻止一个非常随意的攻击者并且相对容易做,特别是因为原始来源可以评论正在发生的事情)到完全加密和一些“黑色box“已经用于复制保护的类型方法(尽管这些方法最终可以破解),如果这足够关键的话,可以将其作为Web服务的效果,而不是最终用户。即使这并不总是安全的。
那么,你想要你的秘密有多秘密,你愿意投入多少工作来保持这种秘密?
答案 4 :(得分:2)
没有办法完全隐藏确定的攻击者的这些秘密,但有办法提高标准(这有时可能既是一种威慑,也是一种临时措施。)
最简单的方法是使用XOR等一次性打击垫。
int pad = 322;
int secret = 360;
int value = pad ^ secret; // This is 42
您可以添加此类一次性填充的组合以及混淆的加密函数,以使攻击者更难找到该值。
请注意,虽然这使攻击者更难以通过查看已编译的代码来获取密钥,但是他们仍然可以将调试器附加到正在运行的进程并将计算出的密钥从内存中拉出来。实际上,有一些调试器(例如IDA pro)可以使这样的东西变得非常简单。
您还必须担心操作系统在计算完密钥后将其分页到磁盘,这可以非常简单地提取。 (使用mlock()之类的东西将页面锁定到内存可以帮助你。)
无论如何,这是一个非常棘手的问题,许多软件作者正在努力实施非侵入式(例如,没有通过网络验证密钥)的许可方案。
答案 5 :(得分:2)
我听说有人使用自修改代码进行混淆。正如其他人所说的那样,有足够坚定的人仍然可以破解它,但如果他们甚至看不到最终的代码被拆解或在其中设置断点,它会使一个潜在的攻击者生活更加艰难。 (设置断点相当于用INT 3
指令替换内存字节;如果该内存作为自修改代码操作的一部分被修改,断点将消失,可能破坏那里的指令并导致更多乐趣。)
仍然可以在调试器中单步执行代码。为了部分抵消这种情况,您可以偶尔测试IsDebuggerPresent()并带领攻击者进行疯狂的追逐。当然,这也可以反作用,例如,通过DLL填充甚至在必要时创建低级设备驱动程序。
答案 6 :(得分:1)
如何使用补充
int secret = ~42;
printf("%0X %0x" , secret , ~secret );
打印
FFFFFFD5 42
编辑:或使用宏
#define OBFUSCATE(X) (~(X)^0xdeadbeef)
int secret = OBFUSCATE( 42 );
printf("%0X %d" , secret ,OBFUSCATE( secret ));
2152413A 42
答案 7 :(得分:1)
隐藏在另一个数字基础中表示其值。请参阅base conversion和base 64
上的示例答案 8 :(得分:1)
您可以尝试antispy C/C++ Obfuscation Library for all platforms,它们提供了一种在编译时隐藏值类型的方法。
答案 9 :(得分:0)
实际上没有办法在程序中隐藏一个整数,因为有人可以通过调试器来确定它的最终值。
最好的办法是使用一些自动混淆器来混淆整个例程/程序。