你能在编译的二进制文件中看到#defined项吗?

时间:2010-02-25 03:19:02

标签: c objective-c

我想在我的代码中“隐藏”一些信息,但我不确定这是否能解决问题。我知道在编译的应用程序中很容易找到和查看字符串文字,但整数呢?假设我定义了一个数字#define kHiddenNumber 1234567然后在我的代码中使用kHiddenNumber作为整数引用它。这会在编译的代码中可见,还是会有效隐藏数字?

谢谢!

7 个答案:

答案 0 :(得分:5)

#define由预处理器处理,而预处理器只是暴力替换。它没有试图“隐藏”任何东西。

答案 1 :(得分:3)

这不会隐藏任何东西。预编译器只用1234567替换“kHiddenNumber”的每个实例,编译后的代码没有引用kHiddenNumber。

kHiddenNumber只会让您的代码更具可读性和可维护性。 C编译器只看到1234567。

答案 2 :(得分:3)

考虑一下简单的程序:

#define kHiddenNumber 1234567

int main(void)
{
    int i = kHiddenNumber;
    return(i & 0xFF);
}

编译:

gcc -o xx xx.c

注意1234567 10 = 0x12D687

现在以十六进制打印程序并搜索D6:

$ od -x xx | grep d6
0002700      6d65    422e    642e    6c79    6269    0000    0000    0000
0007460      45c7    87fc    12d6    0f00    45b6    c9fc    00c3    25ff
0020140      7265    4700    705f    6f72    6e67    6d61    0065    026c
$

你可以在输出的中间行看到0x12D687。它是一种有趣的格式,但仍然存在于代码中。请注意,编译未进行优化。当程序被优化时,证据就会丢失 - 可能是因为常量被用在这样一个简单的上下文中,'i'可以被优化掉,返回表达式减少到值0x87。字节0x87确实出现在优化代码中优化版本中大约相同的位置 - 您需要做一个正确的反汇编工作来证明这绝对是值的最后一个字节,尽管我认为这很可能。

$ od -x xx | grep -i d6
0002320      e500    60d6    fdf5    ee77    10b8    e3d5    5834    7377
0002700      6d65    422e    642e    6c79    6269    0000    0000    0000
0020140      7265    4700    705f    6f72    6e67    6d61    0065    026c
$ od -x xx | grep -i 87
0007460      0000    f400    4855    e589    87b8    0000    c900    00c3
$

在更复杂的程序中 - 'i'传递给函数(可能是'printf()'),无法完成优化。

因此,您不能依赖编译器来隐藏值。最有可能的是,该值的名称将不存在。但是这个价值可能存在于要找到的程序中。

顺便提一下,您有时可以找到类似的加密密钥 - 虽然更复杂。数据太随意而不自然 - 所以它在程序中就像一个痛苦的拇指一样突出。

答案 3 :(得分:1)

极不可能在编译的目标代码中出现字符串“1234567”。但是,它可能以二进制形式出现 - 作为一个字节序列,很可能是0x00 0x12 0xD6 0x870x87 0xD6 0x12 0x00

这些字节可以位于代码使用的其他常量中的单独部分中,也可以在指令流本身内进行编码。

有一些方法可以混淆这些常数,但正如其他人所指出的那样,你真的在​​试图玩这种游戏时一无所有。经验丰富的逆向工程师以前见过这一切。

答案 4 :(得分:0)

我认为在编译的二进制文件中不会显示,因为数字被编译为二进制格式,但可以通过使用黑客工具来解决。

答案 5 :(得分:0)

How to hide a string in binary code?
可能对你有帮助

答案 6 :(得分:-2)

取决于你如何使用它。如果编译器无法优化它,它将是可见的。如果你做一些事情,比如将用户的序列号与内置号码进行比较,就很容易跟踪。