因此,在本书中编写的以下程序intlen()中,当我读取与此程序对应的汇编语言时,intlen()提供了受保护的Canary值,以及ALL放置到堆栈中的几个值。
我的问题在于,本书清楚地表明你有六个寄存器可以放入六个变量,一旦你把这些变量放到寄存器中,一旦你经过6个寄存器,那么一切都进入堆栈。
我需要知道的是为什么程序intlen()将其所有值放入堆栈并理解为什么将canary值放在它所在的位置。
我已经尝试谷歌搜索答案以及计算以前程序中的变量和参数,因为“调用”仍然是一件事,对吧?事实上,以前程序中的这些变量最多只能达到四个。
编辑:我还想知道当受Canary值保护时,len在堆栈指针上分配了多少。以下是我认为len的工作原理。参数* s值8位,堆栈保护器是另一个8位,因为我们在64位系统上,返回的堆栈帧是8位,所以它需要总共24位,对吗?
/* C Code */
int len(char *s){
return strlen(s);
}
void iptoa(char *s, long *p){
long val = *p;
sprintf(s, "%ld", val);
}
int intlen(long x){
long v;
char buf[12];
v = x;
iptoa(buf, &v);
return len(buf);
}
=====装配对应=======
没有堆栈保护器
1. intlen:
2. subq $40, %rsp
3. movq %rdi, 24(rsp)
4. leaq 24(%rsp), %rsi
5. movq %rsp, %rdi
6. call iptoa
有保护者
0. intlen:
1. subq $56, %rsp
2. movq %fs:40, %rax < Canary Value
3. movq %rax, 40(%rsp) < Where the Canary goes (Why does this go here?)
4. xorl %eax, %eax
5. movq %rdi, 8(%rsp)
6. leaq 8(%rsp), %rsi
7. leaq 16(%rsp), %rdi
8. call iptoa
我希望大多数变量都在寄存器中,但是如你所见,所有内容都被放到了堆栈指针上,我真的不明白为什么。感谢您的时间。