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

问题描述 投票:0回答:7

我希望在代码中“隐藏”一些信息,但我不确定这是否能达到目的。我知道字符串文字很容易在编译的应用程序中找到和查看,但是整数呢?假设我定义了一个数字

#define kHiddenNumber 1234567
,然后在我的代码中使用
kHiddenNumber
作为整数来引用它。这会在编译后的代码中可见,还是会有效隐藏该数字?

c objective-c
7个回答
5
投票

#define
由预处理器处理,预处理器只是强力替换东西。它不会试图“隐藏”任何东西。


4
投票

考虑简单的程序:

#define kHiddenNumber 1234567

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

编译:

gcc -o xx xx.c

请注意 123456710 = 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
投票

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

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


1
投票

在编译后的目标代码中出现字符串“1234567”的可能性极小。 然而,它可能以二进制形式出现 - 作为字节序列,很可能是

0x00 0x12 0xD6 0x87
0x87 0xD6 0x12 0x00

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

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


0
投票

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


0
投票

-2
投票

取决于你如何使用它。如果编译器无法优化它,它将是可见的。 如果您执行诸如将用户的序列号与内置编号进行比较之类的操作,就很容易跟踪。

© www.soinside.com 2019 - 2024. All rights reserved.