如果我在代码中的多个地方都有这样的整数...
int my_secret = 42;
...是否可能使在编译程序中找到该整数更加困难?我已经看到使用字符串完成此操作,例如,通过将每个字母移动x个字符,然后在运行时取消移动它们,但是我怀疑这种技术是否可以很好地用于数字。
您可以通过在两个变量之间分割该值来实现。例如这样:
volatile int my_secret_1 = 20;
volatile int my_secret_2 = 22;
然后使用my_secret_1 + my_secret_2代替my_secret。
需要volatile关键字,因为大多数(如果不是全部)c编译器都会对其进行优化。无论如何,最好查看编译器生成的汇编代码。
您可以尝试antispy C/C++ Obfuscation Library for all platforms,它们提供了一种在编译时隐藏值类型的方法。
这永远行不通。秘密密钥永远不应该在代码中。在运行时创建它们是可行的。混淆无疑会吸引人的天意。
您可以在运行时通过一些编译器无法优化的函数来计算它,例如使用数字的平方,然后通过数学库函数求平方根。
当然,问题是,这类东西都不会阻止一个确定的人。
也可能会说您真的不需要打扰。对字符串进行混淆很有意义,因为有大量易于使用的工具将从exe转储字符串。但是,您的42只会被编码为二进制数。整个exe只是一长串二进制数,没有一个简单的工具可以搜索42。您必须拆卸exe并了解其装配。无论您做什么,都要经历那么多麻烦的任何人都可能会弄清楚这个数字。
因此,简短的答案是不要打扰它,以至于可以随意使用。
[哈桑评论中的第一个问题是关键性问题。这取决于您要保密的内容,以及为什么要进行多少工作才值得。通常来说,对正在使用该程序的人隐藏某些东西(在某些时候将这些值放在一起)是不可能永远做到的。但是,您可以使攻击者更难。
然后,问题就变成了您想要进行多少工作才能使该攻击者更难。然后,您可以执行任何操作,从代码混淆(不是很安全,但可能会阻止非常偶然的攻击者并且相对容易做到,尤其是因为原始源可以用正在发生的事情进行注释)到完全加密和某些“黑色”框”类型的方法已经用于复制保护(即使最终还是很容易破解的),如果这很关键的话,可以将其作为某种Web服务的效果提供,而代码不会传递给最终用户。即使那也不总是故障安全。
所以,您想要多少秘密,您愿意为保持这种秘密付出多少工作?
我听说有人使用自我修改的代码进行混淆。正如其他人所说,有足够决心的人仍然可以破解它,但是如果他们甚至看不到最终代码被分解或在其中设置断点,那么对于潜在的攻击者来说,生活将变得更加艰难。 (设置断点等于用INT 3
指令替换内存的一个字节;如果该内存作为自修改代码操作的一部分被修改,则断点将消失,可能破坏那里的指令并带来更多的乐趣。 )
仍然可以在调试器中单步执行代码。要部分抵消它,您可以偶尔测试IsDebuggerPresent(),如果是,则引导攻击者进行大雁追捕。当然这也可以被抵消,例如。通过DLL填充或什至在需要时创建低级设备驱动程序。
没有办法完全向坚定的攻击者隐藏这样的秘密,但是有很多方法可以提高标准(有时可能既起到威慑作用,又是临时措施。)
最简单的方法是应用一次性的XOR之类的工具。
int pad = 322;
int secret = 360;
int value = pad ^ secret; // This is 42
您可以添加此类一次性密码的组合以及模糊的加密功能,以使攻击者更难找到价值。
请注意,尽管这使攻击者更难通过查看已编译的代码来获取密钥,但他们仍然可以将调试器附加到正在运行的进程中,并将计算出的密钥直接从内存中拉出。实际上,有些调试器(例如IDA pro)使这种事情变得微不足道。
您还需要担心操作系统在计算密钥后将其分页到磁盘,可以很轻松地将其提取出来。 (使用mlock()之类的东西将页面锁定到内存可以帮助您。)
无论如何,这是一个非常棘手的问题,许多软件作者都在努力实现非侵入式(例如,网络上没有验证密钥)许可方案。
如何使用那些补语
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
隐藏以另一个数字表示的值。参见示例base conversion和base 64
实际上没有办法只在程序中隐藏一个整数,因为有人可能只是通过调试器来确定其最终值。
您最好的选择是使用一些自动混淆器来混淆整个例程/程序。