反汇编c程序时神秘的printf参数
Mysterious printf argument when disassembling c program
所以我有这个 C 代码:
#include <stdio.h>
int main(void)
{
int a;
int b;
int c;
a=b=c=5;
printf("Hi%d%d%dHi",a,b,c);
}
我在 ubuntu 上编译了它:
gcc program.c -o program -ggdb -m32 -O2
然后反汇编为:
objdump -M intel program -d
并且在主 printf() 中被这样调用:
mov DWORD PTR [esp+0x10],0x5
mov DWORD PTR [esp+0xc],0x5
mov DWORD PTR [esp+0x8],0x5
mov DWORD PTR [esp+0x4],0x8048500
mov DWORD PTR [esp],0x1
call 8048330 <__printf_chk@plt>
我现在想知道的是这意味着什么:
mov DWORD PTR [esp],0x1
我知道前 4 条 mov 指令的用途,但我就是想不通为什么将“1”压入堆栈。此外,此移动仅在打开优化时发生。有什么想法吗?
如果您(或编译器)定义了 _FORTIFY_SOURCE
并启用了优化,GNU C 库 (glibc) 将使用 __printf_chk
而不是 printf
。该函数的 _chk
版本的行为就像它替换的函数一样,除了它应该 check for stack overflow 并且可能验证参数。额外的第一个参数表示应该进行多少检查和验证。
查看 actual glibc implmenation 似乎没有对编译器自动提供的内容进行任何额外的堆栈检查(因此没有必要),并且参数验证非常少。它将检查 %n
是否只出现在只读格式字符串中,并检查特殊的 %<i>m</i>$
参数说明符是否是使用它们用于所有参数而没有任何间隙。
所以我有这个 C 代码:
#include <stdio.h>
int main(void)
{
int a;
int b;
int c;
a=b=c=5;
printf("Hi%d%d%dHi",a,b,c);
}
我在 ubuntu 上编译了它:
gcc program.c -o program -ggdb -m32 -O2
然后反汇编为:
objdump -M intel program -d
并且在主 printf() 中被这样调用:
mov DWORD PTR [esp+0x10],0x5
mov DWORD PTR [esp+0xc],0x5
mov DWORD PTR [esp+0x8],0x5
mov DWORD PTR [esp+0x4],0x8048500
mov DWORD PTR [esp],0x1
call 8048330 <__printf_chk@plt>
我现在想知道的是这意味着什么:
mov DWORD PTR [esp],0x1
我知道前 4 条 mov 指令的用途,但我就是想不通为什么将“1”压入堆栈。此外,此移动仅在打开优化时发生。有什么想法吗?
如果您(或编译器)定义了 _FORTIFY_SOURCE
并启用了优化,GNU C 库 (glibc) 将使用 __printf_chk
而不是 printf
。该函数的 _chk
版本的行为就像它替换的函数一样,除了它应该 check for stack overflow 并且可能验证参数。额外的第一个参数表示应该进行多少检查和验证。
查看 actual glibc implmenation 似乎没有对编译器自动提供的内容进行任何额外的堆栈检查(因此没有必要),并且参数验证非常少。它将检查 %n
是否只出现在只读格式字符串中,并检查特殊的 %<i>m</i>$
参数说明符是否是使用它们用于所有参数而没有任何间隙。