zoukankan      html  css  js  c++  java
  • 多次Printf()是否使用用同一栈帧的参数?

    如题,问题出自于格式化字符串漏洞,(教师展示的源码)显示printf函数,“调用第一次打印正常数字,第二次打印时不指定变量  (printf("%d%d")),会将上一次压入的值和栈中下一个值打印出”。其实我怀疑他是不是讲错了。

    引申:

    格式化字符串漏洞成因:程序将格式化字符串的输入权交给用户,printf函数并不知道参数个数,它的内部有个指针,用来索检格式化字符串。对于特定类型%,就去取相应参数的值,直到索检到格式化字符串结束。所以没有参数,代码也会将format string 后面的内存当做参数以16进制输出。这样就会造成内存泄露。

    1.先来看调用printf函数以后会不会清除参数

    如上程序,我用execl画到0040104B地址的堆栈(add esp 8处)

    可以看到如果执行add esp,8先前的参数也会被堆栈清除,第二次打印会使用同一函数栈帧,但是参数已经清除,格式化字符串漏洞的打印上一次的参数不成立

     

    2.矛盾

    自己编写程序,发现教师的结果没有讲错

    拿去OD反汇编,第一次打印函数的确平衡了堆栈,清除了参数

    Leave的作用相当==mov esp,ebp和pop ebp

    那么到这就可以下结论了:printf()函数被调用多次,它的栈在每次调用完后都会被清除,多次调用打印上一次变量的值应该与printf()函数自身有关。

    3.不一样的结果

    但是但是,在经过一个小时的测试后

    如图VC++中的结果,明确了函数调用完堆栈会清除参数,问题不在printf函数本身,而在于编译器怎样去编译执行这个程序

    由于2中是用codeblock编写的,两个编译器出现不同的结果,由结论知:call调用同一函数,结束后会清除参数,所以多次Printf()不会使用用同一栈帧的参数。

  • 相关阅读:
    杭电1058
    动态规划之背包模版
    按字典序依次打印只由1~n组成的n位数
    杭电1029
    杭电1257
    杭电2191
    杭电1114
    杭电2602
    南阳975
    杭电2138
  • 原文地址:https://www.cnblogs.com/echoDetected/p/13734547.html
Copyright © 2011-2022 走看看