C 强制优化器不对字符数组的内容进行任何假设
我如何才能强制gcc的优化器不对代码中的字符数组的内容进行任何假设?据我所知,这应该可以用C 强制优化器不对字符数组的内容进行任何假设,c,gcc,C,Gcc,我如何才能强制gcc的优化器不对代码中的字符数组的内容进行任何假设?据我所知,这应该可以用volatile关键字实现,但它似乎不起作用 请看下面的代码: #include <stdio.h> int main(int argc, char *argv[]) { volatile unsigned char magickey[] = "\xDE\xAD\xC0\xDE\xC0\xDE\xCA\xFE\xC0\xCA\xC0\x1A"; volatile un
volatile
关键字实现,但它似乎不起作用
请看下面的代码:
#include <stdio.h>
int main(int argc, char *argv[])
{
volatile unsigned char magickey[] = "\xDE\xAD\xC0\xDE\xC0\xDE\xCA\xFE\xC0\xCA\xC0\x1A";
volatile unsigned int val;
// printf("TEST: %p\n", magickey);
val = (magickey[0] << 24) | (magickey[1] << 16) | (magickey[2] << 8) | magickey[3];
printf("TEST2: %x\n", val);
return 0;
}
我希望能够在十六进制编辑器中打开可执行文件,并更改magickey
char数组的前4个字节,val
应包含通过修改可执行文件将其十六进制设置到char数组中的字节
只有在第一次调用printf
被停用时(如上所示的代码中),此功能才起作用。但是,只要我激活对printf
的第一个调用,无论我使用十六进制编辑器将哪些值写入可执行文件,程序都会打印TEST2:deadc0de
这让我很困惑。对printf
的第一次调用似乎完全无害,因为它只打印字符数组的地址。我不明白为什么激活这一行会以任何方式影响优化器
所以我一定是做错了什么。我该怎么做才能强制优化器不对
magickey
char数组的内容进行任何假设,这样我就可以在编译后通过使用十六进制编辑器对可执行文件进行黑客攻击来填充它,并且我使用十六进制编辑器写入其中的字节被正确复制到val
volatile
似乎并不真正起作用 当您使用gcc-O3
编译时,它可能被优化到打印语句被硬编码到应用程序后面的printdeadc0de
。查看使用-O2
或-O1
标志进行十六进制编辑是否会得到相同的结果。您是将magickey
声明为全局变量还是局部变量?当您正在修改二进制文件时,应将问题编辑为包含一个字符串,这样它就不再是有效的编译器生成的文件。所以你不能合法地要求任何东西。你可以想出一个解决方案,这个解决方案在此时此地就可以使用,但你不能保证将来也可以使用。好吧,问题是数组是一个局部变量。因此,gcc知道外部参与者(例如硬件、中断例程、其他线程)无法访问该阵列。因此,修改数组的唯一方法是将数组的地址传递给某个函数,例如printf
。尝试定义一个空函数voidfoo(char*unused){}
,将magickey
传递给该函数,然后查看gcc的功能。或者干脆将magickey
声明为全局变量(这样理论上硬件、中断和其他线程都可以访问它)。@user3386109:太好了,使用全局变量确实解决了问题。谢谢!
gcc -O3 test.c