Я просто играл со стеком вызовов, пытался изменить адрес возврата функции и т. Д. И закончил писать эту программу на C:
#include<stdio.h>
void trace(int);
void func3(int);
void func2(int);
void func1(int);
int main(){
int a = 0xAAAA1111;
func1(0xFCFCFC01);
return 0;
}
void func1(int a){
int loc = 0xBBBB1111;
func2(0xFCFCFC02);
}
void func2(int a){
int loc1 = 0xCCCC1111;
int loc2 = 0xCCCC2222;
func3(0xFCFCFC03);
}
void func3(int a){
int loc1 = 0xDDDD1111;
int loc2 = 0xDDDD2222;
int loc3 = 0xDDDD3333;
trace(0xFCFCFC04);
}
void trace(int a){
int loc = 0xEEEE1111;
int *ptr = &loc;
do {
printf("0x%08X : %08X\n", ptr, *ptr, *ptr);
} while(*(ptr++) != 0xAAAA1111);
}
(извините за длину)
Это привело к следующему выводу (с добавленными мной комментариями):
0xBF8144D4 : EEEE1111 //local int in trace
0xBF8144D8 : BF8144F8 //beginning of trace stack frame
0xBF8144DC : 0804845A //return address for trace to func3
0xBF8144E0 : FCFCFC04 //int passed to trace
0xBF8144E4 : 08048230 //(possibly) uninitialized padding
0xBF8144E8 : 00000000 //padding
0xBF8144EC : DDDD3333 //local int in func3
0xBF8144F0 : DDDD2222 //local int in func3
0xBF8144F4 : DDDD1111 //local int in func3
0xBF8144F8 : BF814518 //beginning of func3 stack frame
0xBF8144FC : 08048431 //return address for func3 to func2
0xBF814500 : FCFCFC03 //parameter passed to func3
0xBF814504 : 00000000 //padding
0xBF814508 : 00000000 //padding
0xBF81450C : 00000000 //padding
0xBF814510 : CCCC2222 //local int in func2
0xBF814514 : CCCC1111 //local int in func2
0xBF814518 : BF814538 //beginning of func2 stack frame
0xBF81451C : 0804840F //return address for func2 to func1
0xBF814520 : FCFCFC02 //parameter passed to func2
0xBF814524 : 00000000 //padding
0xBF814528 : BF816728 //uninitialized padding
0xBF81452C : B7DF3F4E //uninitialized padding
0xBF814530 : B7EA61D9 //uninitialized padding
0xBF814534 : BBBB1111 //local int in func1
0xBF814538 : BF814558 //beginning of func1 stack frame
0xBF81453C : 080483E8 //return address for func1 to main
0xBF814540 : FCFCFC01 //parameter passed to func1
0xBF814544 : 08049FF4 //(maybe) padding
0xBF814548 : BF814568 //(maybe) padding
0xBF81454C : 080484D9 //(maybe) padding
0xBF814550 : AAAA1111 //local int in main
Мне было интересно, если кто-нибудь мог бы заполнить меня здесь на пустых местах ... Я использую Ubuntu Linux, компилирующуюся с gcc 4.3.3 (на x86 - AMD Turion 64)
Что такое 0804 ... числа? Какой третий адрес снизу вверх? Это обратный адрес для основного? Если так, то почему он не в порядке по сравнению с остальной частью стека?
Числа 0x0804 являются адресами возврата или указателями на код / данные или что-то еще, а числа 0xBF814 являются указателями стека
Что это:
0xBF814524 : 00000000 //padding?
0xBF814528 : BF816728 //I have no idea
0xBF81452C : B7DF3F4E //????
0xBF814530 : B7EA61D9 //????
видели сразу после локального int в func1?
Хорошо, мой дамп стека почти полностью заполнен.
Похоже, что компилятор хочет поместить параметры в стек, начиная с адреса 0x ....... 0, и все, что находится между локальными переменными из предыдущей функции и первым параметром функции, являющейся Кажется, что он вызывается как заполнение (0x00000000 или какое-то неинициализированное значение). В некоторых из них я не уверен, потому что они выглядят как указатели на сегменты кода / данных, но я не вижу, чтобы они использовались в коде: они просто там, когда указатель стека уменьшается.
и я знаю это ОГРОМНЫЙ ноно, касающийся стека вызовов в любом проекте, но это нормально. Это весело, правда?
также
Грег хочет увидеть сборку,
вот оно
.file "stack.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $20, %esp
movl $-1431695087, -8(%ebp)
movl $-50529279, (%esp)
call func1
movl $0, %eax
addl $20, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.globl func1
.type func1, @function
func1:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $-1145368303, -4(%ebp)
movl $-50529278, (%esp)
call func2
leave
ret
.size func1, .-func1
.globl func2
.type func2, @function
func2:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $-859041519, -4(%ebp)
movl $-859037150, -8(%ebp)
movl $-50529277, (%esp)
call func3
leave
ret
.size func2, .-func2
.globl func3
.type func3, @function
func3:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $-572714735, -4(%ebp)
movl $-572710366, -8(%ebp)
movl $-572705997, -12(%ebp)
movl $-50529276, (%esp)
call trace
leave
ret
.size func3, .-func3
.section .rodata
.LC0:
.string "0x%08X : %08X\n"
.text
.globl trace
.type trace, @function
trace:
pushl %ebp
movl %esp, %ebp
subl $40, %esp
movl $-286387951, -4(%ebp)
leal -4(%ebp), %eax
movl %eax, -8(%ebp)
.L10:
movl -8(%ebp), %eax
movl (%eax), %edx
movl -8(%ebp), %eax
movl (%eax), %eax
movl %edx, 12(%esp)
movl %eax, 8(%esp)
movl -8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl -8(%ebp), %eax
movl (%eax), %eax
cmpl $-1431695087, %eax
setne %al
addl $4, -8(%ebp)
testb %al, %al
jne .L10
leave
ret
.size trace, .-trace
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits