Tag: gcc

gcc是否在编译时重新排序局部变量?

我现在正在阅读(第二次)“黑客:剥削的艺术”并且偶然发现了一些事情。 本书提出了两种不同的方法来利用这两个类似的程序: auth_overflow和auth_overflow2 在第一个中,有一个像这样的密码检查function int check_authentication(char *password) { int auth_flag = 0; char password_buffer[16]; strcpy(password_buffer, password); … } 输入超过16个ASCII字符会将auth_flag的值更改为大于0的值,从而绕过检查,如此gdb输出所示: gdb$ x/12x $esp 0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141 0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001 0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556 password_buffer @ 0xbffff40c auth_flag @ 0xbffff41c 第二个程序反转了两个变量: int check_authentication(char *password) { char password_buffer[16]; int auth_flag = 0; strcpy(password_buffer, […]

如何在现代系统上测试缓冲区溢出?

我目前对学习如何进行缓冲区溢出感兴趣。 我已经完成了很多程序集,并了解了堆栈是如何工作的以及如何在C中实现缓冲区溢出。但是,我遇到了很多麻烦,试图让GCC 4.9.1允许我溢出缓冲得当。 我正在运行Debian Jessie。 这是我试图遵循的教程,在2.2节中。 我复制/粘贴了他提供的C程序,我使用的是相同的Perl脚本,所以一切都与他的情况完全相同(当然除了系统)。 这些是我一贯得到的结果: ~/projects/buffer-overflow$ ls run.pl test.c ~/projects/buffer-overflow$ sudo su root@wash# echo “0” > /proc/sys/kernel/randomize_va_space root@wash# exit exit ~/projects/buffer-overflow$ gcc -m32 -fno-stack-protector -zexecstack test.c ~/projects/buffer-overflow$ ./run.pl Address of foo = 0x804845b Address of bar = 0x80484a4 My stack looks like: (nil) 0xffffd4a8 0xf7e58b2f 0xf7fb3ac0 0x8048657 0xffffd494 ABCDEFGHIJKLMNOPP @ Now the […]

C / C ++编译器反馈优化

有没有人看过任何使用C / C ++编译器提供的反馈优化来支持分支预测,缓存预加载等function的程序的真实世界数字。 我搜索了它,令人惊讶的是,甚至流行的翻译开发小组似乎都没有检查过这种效果。 并且将ruby,python,php等性能提高10%左右应该被认为是有用的。 真的没有任何好处,或整个开发者社区只是懒得使用它?

GCC错误“导致节类型冲突”

为什么在尝试将两个(RAM)变量(只是它们的初始化值不同)放入同一部分时会出现编译器错误? 问题 C源: int __attribute__((section(“.in_my_data”))) _foo = 1; int __attribute__((section(“.in_my_data”))) _bar = 0; (相关)GCC编译器输出: mcve/main.c:75:45: error: _bar causes a section type conflict 链接描述文件在SECTIONS定义中包含以下行,但(致命)错误来自编译器,而不是链接器。 .my_data : { *(.in_my_data) } > data 更多的信息 更改C源以允许编译器使用两个部分允许编译通过,但是如果两个输入节被映射到相同的输出节,则链接器会生成错误。 C源: int __attribute__((section(“.in_my_data_nonzero”))) _foo = 1; int __attribute__((section(“.in_my_data_zero”))) _bar = 0; 链接器脚本: .my_data : { *(.in_my_data*) } > data (相关)链接器输出: Link Error: attributes […]

为什么GCC在这个例子中没有发出警告

启用-Wsequence-point ,GCC应在发现未定义的行为代码时警告用户。 例如 b = a + ++a; 应该被GCC注意到并且应该被报告为“未定义的行为”代码(因为ISO C没有指定评估操作数的顺序)。 但是,我玩了语法,我尝试了这个: int *a = malloc(sizeof(int) * 2); a[0] = 1; printf(“%d\n”, *(a + (*a)++ – *a)); 当然,我收到了警告 警告:’* a’上的操作可能未定义[-Wsequence-point] 这是我所期望的,因为*a (其为a[0] )的值可以在处理第三个操作数时递增或者可以不递增。 但是,我尝试了以下一个: int *a = malloc(sizeof(int) * 2); a[0] = 1; printf(“%d\n”, *(a + (*a)++ – 1)); 我很惊讶,因为我没有收到任何警告。 这不应该是UB吗? 我的意思是,根据ISO C99,可以在表达式评估期间的任何点评估后增量操作(逗号运算符和三元运算符除外)。 在我的后一个例子中,我没有递增指针,而是指向它指向的整数。 因此,根据标准,它可以在任何点递增(这意味着它可以在评估整个表达式后递增),因此程序可以打印1或2 ,对吧? […]

避免重复Cerror handling

我经常编写代码,这些代码最终都是长序列 int error; error = do_something(); if (error) { return error; } error = do_something_else(with, some, args); if (error) { return error; } error = do_something_yet_again(); if (error) { return error; } return 0; 我正在寻找一种更清晰的方式来写这个,这在某种程度上避免了重复相同的检查。 到目前为止,我已经编写了一个ERROR_OR宏,它的工作方式类似于 #define ERROR_OR(origerr, newerr) \ ({ \ int __error_or_origerr = (origerr); \ (__error_or_origerr != 0) \ ? __error_or_origerr \ : […]

C程序链接共享库而不设置LD_LIBRARY_PATH

我正在阅读GCC简介,它说如果一个软件包同时包含.a和.so。 gcc更喜欢共享库。 默认情况下,加载程序仅在预定义的一组系统目录中搜索共享库,例如/usr/local/lib和/usr/lib 。 如果库不在其中一个目录中,则必须将其添加到加载路径,或者您需要使用-static选项强制它使用.a库。 但是,我尝试了以下方法: vim hello.c: #include #include int main() { mpz_t x; mpz_init(x); return 0; } gcc hello.c -I/opt/include -L/opt/lib -lgmp (my gmp library is in opt) ./a.out 它运行。 该书说它应该有以下错误: ./a.out: error while loading shared libraries: libgdbm.so.3: cannot open shared object file: No such file or directory (好吧,这本书使用GDBM作为例子,但我使用了GMP,但这没关系吗?) 但是,我没有设置LD_LIBRARY_PATH=/opt/lib ,你可以看到我也没有使用-static选项,但a.out仍然运行。 你能告诉我为什么,并告诉我如何得到书中描述的错误? 是的,我想要错误,所以我会理解我误解的内容。

在VC ++中进入MACRO

我正在调试一个源代码,它有很多大的#define MACRO例程。 我很有兴趣进入它们,但我想,VC ++不允许步入function…所以, 我正在将它们转换为函数,但这对我来说变得很难 有没有办法进入MACRO例程? 特别是在VC ++中? PS:如果gcc编译器支持步入MACRO,我可以将整个代码移植到gcc中

错误:未知类型名称’FILE’

我正在创建一个函数,它只是将“hello”写入文件。 我把它放在一个不同的文件中并将其标题包含在程序中。但是gcc给出了一个错误:错误:未知类型名称’FILE’。 代码如下 app.c: #include #include #include”write_hello.h” int main(){ FILE* fp; fp = fopen(“new_file.txt”,”w”); write_hello(fp); return 0; } write_hello.h: void write_hello(FILE*); write_hello.c: void write_hello(FILE* fp){ fprintf(fp,”hello”); printf(“Done\n”); } 当通过gcc编译时,会发生以下情况: harsh@harsh-Inspiron-3558:~/c/bank_management/include/test$ sudo gcc app.c write_hello.c -o app write_hello.c:3:18: error: unknown type name ‘FILE’ void write_hello(FILE* fp){ ^ 对不起任何错误。我是初学者。

为什么GCC的-Wconversion对char和unsigned char的行为不同?

考虑 U8 foo(U8 x, U8 y) { return x % y; } 如果U8(x和y的类型是char或unsigned char),GCC的-Wconversion表现不同: gcc -Wconversion -c test.c -DU8=’unsigned char’ (没有警告) gcc -Wconversion -c test.c -DU8=char test.c: In function ‘foo’: test.c:2:14: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion] return x % y; ~~^~~ 但是根据我的理解,在两种情况下,x经过整数提升(到int或unsigned int),因此在两种情况下它都将从int转换为返回类型(char或unsigned char)。 为什么会有区别? 额外问题:如果你启用了ubsan(-fsanitize = undefined),那么GCC会在两种情况下都发出-Wconversion。 编辑 […]