当我查看一些汇编代码时,我注意到一个函数具有以下结构:
My_Function:
; Function Prologue
push EBP
mov EBP, ESP
sub ESP, 0x28 ;40 Bytes local variable allocation
; Some code here
; Function epilogue
leave
ret
所以如果我们假设My_Function接受一个1字节的参数,那么从堆栈帧中删除的位置。据我所知,一个函数的堆栈包含以下结构(从低地址到高地址):
LOW ADDRESS > | Local Var
我正在学习一个基于语言的安全性类,我必须一步一步地知道在正确执行函数时堆栈中发生了什么,以便以后我可以学习如何防范攻击。到目前为止,我已经很好地理解了从堆栈中推送和弹出的内容,以及ESP、EBP是如何跟踪帧的。另外,我知道EIP保存在堆栈中。
我不知道的是函数中的代码实际上是在哪里执行才能得到结果的(我猜在内存中的其他地方是堆吗?)如果我给出一个简单函数的演练,是否有人会解释缺少的部分(我会用问题标记这些部分)。假定一个简单的功能:
int add(int x, int y)
{
int sum = x + y;
return sum;
}
它在main()中与add(3,4)一起
我在分配128位变量时遇到了问题,以便它在16字节的边界上对齐(在堆栈上,而不是堆上)。当调用我的函数时,我无法控制堆栈是否对齐,所以我只是直接假设它不是。
以下是我的函数的外观(简化):
; start of stackframe
push ebp
mov ebp, esp
; space for our variable
sub esp, 0x10
; the 128-bit variable would be at [ebp - 0x10]
...
; end of stackframe
mov esp, ebp
pop ebp
现在,我可以通过在and esp, 0xFFFF
有两个简单的C源文件。第一个是mainswap.c:
void swap(int *x, int *y);
int main()
{
int a, b;
a = 5;
b = 44;
swap(&a, &b);
return 0;
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
另一个是mainfoobar.c:
int bar(int x, int y)
{
int z = x + y;
例如让我们进入一个函数..。
push ebp ;Saving ebp
mov ebp, esp ;Saving esp into ebp
sub esp, 4 ;Saving four bytes onto the stack
退出功能..。
mov esp, ebp ;Restoring the saved value of esp
pop ebp ;Restoring the value of ebp from the stack
(是的,我知道我可以用回车和离开,但我更喜欢这样。)
我的问题是,当esp被恢复时,堆栈上的四个字节变量会弹出还是神奇地消失?我看不出pop ebp如何不会只
我正在尝试绘制一个堆栈,就像它出现在secondCall函数中的“return count”行之前一样。我正在尝试绘制它,以便它将显示三个活动功能的所有三个框架(或激活记录),main,firstCall和secondCall。
有人能帮我完成堆栈图吗?我正在尝试绘制基础(ebp)和栈(esp)指针的位置,就像它们在调用下一个函数之前在每个堆栈帧中一样。
C代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int secondCall(int a, int b) {
in
告诉我,编译器做不同的事情来处理ai,而一个是数组或指针。这里有一个来自c的例子:
char a[] = "hello";char *p = "world";
给定上面的声明,当编译器看到表达式a3时,它会发出代码,从a'', move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the locationp'‘的位置开始,在那里获取指针值,向指针中添加三个,最后获取指向的
_function:
push ebp ;store the old base pointer
mov ebp, esp ;make the base pointer point to the current
;stack location – at the top of the stack is the
;old ebp, followed by the return address and then
;the parameters.
为了了解这一点,我编写了这个简单的代码,其中我创建了不同类型的变量,并通过值、引用和指针将它们传递到函数中:
int i = 1;
char c = 'a';
int* p = &i;
float f = 1.1;
TestClass tc; // has 2 private data members: int i = 1 and int j = 2
函数体保留为空,因为我只是在查看参数是如何传入的。
passByValue(i, c, p, f, tc);
passByReference(i, c, p, f, tc);
passByPointer(&i,
虽然我只用长乘法,但不知道为什么是operand size is wrong
.type _square, @function
_square:
pushl %ebp
movl %esp, %ebp
subl $4, %esp #room for the local variable
movl 8(%ebp), %ecx #the first and only argument
movl $1, %eax
_finding_loop:
incl %eax
movl %eax, %ebx
imull %ebx, -4(%ebp) #storing the result in local va
这是一个节目:
#include <stdio.h>
void test_function(int a, int b, int c, int d){
int flag;
flag = 31337;
}
int main(){
test_function(1,2,3,4);
}
来自非洲开发银行:
Breakpoint 1, main () at stack_example.c:14
14 test_function(1,2,3,4);
(gdb) i r esp ebp eip
esp
下面的图片来自维基百科的 on call stack,其中有一些我不完全理解的东西:
我认为存储在ebp寄存器中的帧指针在序中是这样初始化的*
push ebp ; Preserve current frame pointer
mov ebp, esp ; Create new frame pointer pointing to current stack top
sub esp, 20 ; allocate 20 bytes worth of locals on stack.
如果是这样,那么图像中的帧指针不应该指向返回地址之后,它应该是前一个帧指针地址之前,返回地址之前吗
我知道这是一个非常基本的问题,但这里说的是:
我开始学习汇编程序,并试图了解堆栈是如何工作的。
首先,当我将一个值传递给一个汇编程序函数时,我会像这样访问它:
movl 4(%esp),%eax # first parameter
movl 8(%esp),%ebx # second parameter
但后来有人告诉我,最好这样做:
push %ebp
movl %esp,%ebp
# and then I'd access the values on %ebp:
movl 8(%ebp),%eax
movl 12(%ebp),%eax
pop %ebp
好的,这里有什么区别?当