• 汇编语言基础之九 关于栈指针的规律性的总结


    栈底指针可以被用来判断传递的参数的值,还有函数的局部变量的值。

    让我们继续用上一个例子来说明一下吧。

    ChildEBP RetAddr 
    0012ff34 00401121 Simple!Foo2+0x64 [C:\Labfiles\Module04\Simple\Simple.cpp @ 82]
    0012ff4c 004010da Simple!Foo1+0x31 [C:\Labfiles\Module04\Simple\Simple.cpp @ 65]
    0012ff64 00401096 Simple!Foo+0x2d [C:\Labfiles\Module04\Simple\Simple.cpp @ 49]
    0012ff80 00404739 Simple!main+0x36 [C:\Labfiles\Module04\Simple\Simple.cpp @ 33]
    0012ffc0 7c817077 Simple!mainCRTStartup+0xe9 [crt0.c @ 206]

    栈中的内容如下:

    dd esp

    0012ff14  cccccccc cccccccc cccccccc cccccccc
    0012ff24  cccccccc cccccccc cccccccc cccccccc
    0012ff34  0012ff4c 00401121 00000001 00000002
    0012ff44  00000002 00000001 0012ff64 004010da
    0012ff54  0012ff60 0012ff5c 00000002 00000001
    0012ff64  0012ff80 00401096 00000001 00000002
    0012ff74  00000002 00000001 cccccccc 0012ffc0
    0012ff84  00404739 00000001 00420e90 00420de0

    dd

    0012ff94  43010000 00000000 7ffde000 00000001
    0012ffa4  00000006 0012ff94 80621a58 0012ffe0
    0012ffb4  00408084 00417218 00000000 0012fff0
    0012ffc4  7c817077 43010000 00000000 7ffde000
    0012ffd4  8054c6ed 0012ffc8 8918f3e8 ffffffff
    0012ffe4  7c839ad8 7c817080 00000000 00000000
    0012fff4  00000000 00404650 00000000 78746341
    00130004  00000020 00000001 000024b8 000000c4

    利用EBP确定参数

    ==============

    函数Foo2的栈底位置为0012ff34 ,而函数返回值的位置就在栈底的下方,即ebp+4. 在这里为00401121。

    第一个参数在参数表的最左边,是最后一个压栈的参数,所以第一个参数的起始地址为ebp+8,根据前面我们的程序Simple.cpp,可以看出第一个参数的值为1, 第二个参数的值为2.

    运行如下的命令来验证。可以看到ebp+8所指向的内存中,值为1。第二个参数的位置为ebp+12,在下面的内存dump中,可以看到该位置的值确实为2.

    dd ebp+8

    0012ff3c  00000001 00000002 00000002 00000001
    0012ff4c  0012ff64 004010da 0012ff60 0012ff5c
    0012ff5c  00000002 00000001 0012ff80 00401096
    0012ff6c  00000001 00000002 00000002 00000001
    0012ff7c  cccccccc 0012ffc0 00404739 00000001
    0012ff8c  00420e90 00420de0 43010000 00000000
    0012ff9c  7ffde000 00000001 00000006 0012ff94
    0012ffac  80621a58 0012ffe0 00408084 00417218

    Windbg有个查看函数ebp,返回值和前三个参数的命令,很方便。

    ChildEBP RetAddr  Args to Child             
    0012ff34 00401121 00000001 00000002 00000002 Simple!Foo2+0x64 [C:\Labfiles\Module04\Simple\Simple.cpp @ 82]
    0012ff4c 004010da 0012ff60 0012ff5c 00000002 Simple!Foo1+0x31 [C:\Labfiles\Module04\Simple\Simple.cpp @ 65]
    0012ff64 00401096 00000001 00000002 00000002 Simple!Foo+0x2d [C:\Labfiles\Module04\Simple\Simple.cpp @ 49]
    0012ff80 00404739 00000001 00420e90 00420de0 Simple!main+0x36 [C:\Labfiles\Module04\Simple\Simple.cpp @ 33]
    0012ffc0 7c817077 43010000 00000000 7ffde000 Simple!mainCRTStartup+0xe9 [crt0.c @ 206]
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0012fff0 00000000 00404650 00000000 78746341 kernel32!RegisterWaitForInputIdle+0x49

    利用EBP确定局部变量

    ==============

    局部变量的地址是按照与EBP的距离由近到远,从第一个往后分配地址的。

    所以,第一个局部变量的位置是ebp-4,第二个是ebp-8.

    由于有些局部变量在函数中非常的常用,所以有时局部变量不一定会被压入栈中,而在寄存器中。所以,确定局部变量有可能需要去查看汇编代码,来看变量时从哪里来的,如何移动的,以及如何改变的。

    总结一下

    项目 根据EBP的计算公式
    当前函数栈底的位置 EBP
    上一个函数栈底位置 [EBP]
    当前函数的返回地址 EBP+4
    第一个局部变量 EBP-4
    第二个局部变量 EBP-0x8
    第三个局部变量 EBP-0xc
    第一个参数 EBP+8
    第二个参数 EBP+0xc
  • 相关阅读:
    学习python第二天
    学习python第一天
    SQL操作
    JAR规范 JAR File Specification
    IDEA快捷键
    Fibonacci数列
    AnyHandler
    测试UDP
    Eclipse卡顿设置
    服务器初始化操作
  • 原文地址:https://www.cnblogs.com/awpatp/p/1597269.html
Copyright © 2020-2023  润新知