Jor*_*dan 2 x86 assembly stack eip
我是全新的大会,并希望确认在以下陈述中我有哪些误解,需要纠正.
堆栈指针(ESP)指的是堆栈的顶部(最低内存地址).
基指针(EBP)用于在构建堆栈帧时临时存储各种存储器地址.它通常保存当前堆栈帧的最高内存地址.
指令指针(EIP)指的是存储器的文本(代码)段中的一行代码的存储器地址
一旦某些东西被推入堆栈,它就不能就地更改.即.如果我们PUSH EBP到堆栈,我们正在推送当前值EBP,而不是某种引用或指针.然后我们不能就地改变这个价值.
传递给函数的参数通常被移动到地址空间中,该地址空间是堆栈指针的偏移量.即.[ESP-12].
调用函数(使用CALL)时,会发生以下情况:
EIP因此我们知道在被调用函数完成后返回的位置谢谢.我正试着绕过这些东西.
传递给函数的参数通常被移动到地址空间中,该地址空间是堆栈指针的偏移量.即.[ESP-12].
在调用之前,通常会在堆栈上推送参数.
push paramA ; ( some 32bit value, register, whatever )
push paramB
call myFunct
Run Code Online (Sandbox Code Playgroud)
这导致以下堆栈内容:
---------------
| paramA |
---------------
| paramB |
---------------
| return addr | <-- ESP
---------------
Run Code Online (Sandbox Code Playgroud)
由于返回地址(由其推call)是4个字节,因此该函数的参数为[ESP+4]和[ESP+8].
如果你的函数添加了一个堆栈框架,通常你会这样做
myFunct: push EBP
mov EBP, ESP
Run Code Online (Sandbox Code Playgroud)
现在堆栈看起来像这样:
---------------
| paramA |
---------------
| paramB |
---------------
| return addr |
---------------
| saved EBP | <-- EBP, ESP
---------------
Run Code Online (Sandbox Code Playgroud)
并且参数是[EBP+8]和[EBP+12],即使你推更多的值(或为局部变量添加一些位置),因为EBP不再改变:
myFunct: push EBP
mov EBP, ESP
sub ESP, 12 ; make room for 3 32bit local variables
mov eax, [EBP+8] ; access one of the parameters
mov [EBP-4], eax ; save it in local variable #1
rel | rel |
to | to |
ESP | EBP |
----|------|--------------
+24 | +12 | paramA |
| |--------------
+20 | +8 | paramB |
| |--------------
+16 | +4 | return addr |
| |--------------
+12 | | saved EBP | <-- EBP (is fixed here for now)
| |---------------
+8 | -4 | local#1 |
| |---------------
+4 | -8 | local#2 |
| | ---------------
0 | -12 | local#3 | <--- ESP (keeps growing, by pushing, calling etc)
---------------
Run Code Online (Sandbox Code Playgroud)
局部变量是在[EBP-4],[EBP-8],[EBP-12]等
返回地址是[EBP+4]
注意:正如您所看到的,这是可能的
ESP(那么你就不会需要一个帧指针,但你需要跟踪的多少数据推动,"发现"的参数和变量)EBP(通过增加一些开销).在许多函数中,根本不需要帧指针,并且由编译器优化掉.