1

我只是在学习 ASM/x86,所以请多多包涵。

问题

我在正在检查的程序中注意到以下内容,并且我认为它正在将参数传递给被调用的函数:

mov   [ebp-04],00000005
call  <some function call here>

据我所知,这似乎是将堆栈顶部的第二个字节设置为 value 5

这是否有效地将参数 5 传递给函数?

它会类似于以下内容C

void someFunction(int num); //function declaration

someFunction(5); //In some context

如果将单个参数 5 传递给函数,为什么将其设置为第二个字节(-04),而不是堆栈顶部?栈顶是什么?我解释这一切都错了吗?

编辑 函数的顶部是ebp设置的位置:

push  ebp
mov   ebp,esp
push  -01
push  184
mov   eax,fs:[00000000]
...   //bunch more pushes and movs with eax and ecx into [ebp-offset]
...   //a couple of jump if equals
...   //some more push and movs
lea   ecx,[ebp-1C]
mov   [ebp-04],00000005
call  <some function>

这是被调用的函数:

 mov   edx,[ecx]
 mov   eax,[ecx+08]
 sub   eax,edx
 test  edx,edx
 je    <label1>
 cmp   eax,00000080
 jna   <label2>
 push  edx
 call  <another function>
 add   esp,04
 ret
label2:
 push  eax
 push  edx
 call  <yet another function>
 add   esp,08
label1:
 ret
4

3 回答 3

2

您展示的示例不是将值传递给函数。至少这不会是一个典型的电话。

寄存器的使用fs通常是 try/catch 设置。

如果这确实是函数的整个序列(尤其是被调用函数),那么

...在这里它可能只是设置了一些局部变量。

mov   [ebp-04],00000005

...这里似乎有一个要在 ECX 寄存器中传递的参数

lea   ecx,[ebp-1C]

大多数编译程序使用ebp寄存器作为指向堆栈上局部变量的基指针。然后使用[ebp-X]其中 X 是每个变量的偏移量来寻址各个变量。例如,如果您有两个局部 int 变量,那么您将看到[ebp-4][ebp-8]何时处理这两个变量。

于 2013-10-16T16:17:13.773 回答
1

ebp不是堆栈指针,那是esp. ebp通常用作帧指针,因此根据它的设置方式,它可能确实将其5作为参数传递。或者它可能只是将其存储在局部变量中。

此外,在不知道函数本身的情况下,可能无法判断它是本地参数还是函数参数:

int x = 5;
foo();

可能会生成与foo(5);

帧指针用于指向当前函数的堆栈区域的开头,并且必须由函数本身在序言中设置。参数在它上面(正偏移量)局部变量在它下面(负偏移量)。请注意,在 32 位和 64 位模式下(在 x86 上)您并不需要它,因为您可以esp直接相对于堆栈指针进行寻址。尽管如此,在某些情况下它可能还是有用的,例如用于调试目的。

于 2013-10-15T17:43:36.367 回答
1

通常参数是通过将它们放入寄存器或将它们压入堆栈,然后调用目标子程序来传递的。

EBP 通常包含指向堆栈帧的指针,而不是堆栈顶部。所以你的例子看起来很奇怪,至少它看起来不太可能是一个参数传递操作。它可能是与进行调用的函数相关的一些其他操作。

是编译器生成的代码吗?如果是这样,编译器可能知道 ESP 和 EBP 之间的关系(通常在输入函数时 ESP 被复制到 ESP 中)并且可能正在利用该知识。您需要更早地弄清楚正在使用的 EBP 值的设置位置;显示该代码会很有帮助。

于 2013-10-15T17:44:36.543 回答