Yığın parçalama yoluyla dönüş adresini değiştirerek bir talimatı atlamaya çalışıyorum. Aşağıdaki kod bir ++ değerini ana olarak atlar ve "1 3" çıkışını yazdırır. Bu kodu 32 bitlik bir intel makinede çalıştırdım.Yığın parçalamayı kullanarak bir talimatın atlanması
#include<stdio.h>
void fun(int a,int b) {
// buffer
char buf[8];
char *p;
p = (char *)buf+24;
*p=*p+5;
return;
}
int main() {
int a=1,b=2;
fun(a,b);
a++;
b++;
printf("%d %d",a,b);
}
ben iade adresi buf adresini başlatılmasını 24 bayt yer değiştirme saklanır anlamak kuramıyorum. Aynı kodu farklı bir 32 bitlik bir intel makinesinde çalıştırmayı denedim ve 24 bayt yerine 20 bayt deplasman kullanmak zorunda kaldım. Anlayışımı aşağıdaki şekilde koymuştum. "?" Ile temsil edilen boşluğu doldurduğundan emin değilim. Şekilde. Gcc herhangi bir kanarya değerini koydu mu yoksa bir şey mi özlüyorum? rakama
Bağlantı:
Smashing the stack example3.c confusionhttp://www.cse.iitb.ac.in/~shashankr/stack.png aynı soruyu sordu ama genel olarak yer değiştirme nedenini açıklamak olabilir.
Aşağıdaki şekil, işlevde bir kesme noktası yerleştirerek elde edilen yığının bir görünümünü vermektedir. Cevabın bir şey değildir inanıyoruz
Dump of assembler (fun):
0x08048434 <+0>: push %ebp
0x08048435 <+1>: mov %esp,%ebp
0x08048437 <+3>: sub $0x18,%esp
0x0804843a <+6>: mov %gs:0x14,%eax
0x08048440 <+12>: mov %eax,-0xc(%ebp)
0x08048443 <+15>: xor %eax,%eax
0x08048445 <+17>: lea -0x14(%ebp),%eax
0x08048448 <+20>: add $0x18,%eax
0x0804844b <+23>: mov %eax,-0x18(%ebp)
0x0804844e <+26>: mov -0x18(%ebp),%eax
0x08048451 <+29>: movzbl (%eax),%eax
0x08048454 <+32>: add $0x5,%eax
0x08048457 <+35>: mov %eax,%edx
0x08048459 <+37>: mov -0x18(%ebp),%eax
0x0804845c <+40>: mov %dl,(%eax)
0x0804845e <+42>: mov -0xc(%ebp),%eax
0x08048461 <+45>: xor %gs:0x14,%eax
0x08048468 <+52>: je 0x804846f <fun+59>
0x0804846a <+54>: call 0x8048350 <[email protected]>
0x0804846f <+59>: leave
0x08048470 <+60>: ret
Dump of assembler (main)
0x08048471 <+0>: push %ebp
0x08048472 <+1>: mov %esp,%ebp
0x08048474 <+3>: and $0xfffffff0,%esp
0x08048477 <+6>: sub $0x20,%esp
0x0804847a <+9>: movl $0x1,0x18(%esp)
0x08048482 <+17>: movl $0x2,0x1c(%esp)
0x0804848a <+25>: mov 0x1c(%esp),%eax
0x0804848e <+29>: mov %eax,0x4(%esp)
0x08048492 <+33>: mov 0x18(%esp),%eax
0x08048496 <+37>: mov %eax,(%esp)
0x08048499 <+40>: call 0x8048434 <fun>
0x0804849e <+45>: addl $0x1,0x18(%esp)
0x080484a3 <+50>: addl $0x1,0x1c(%esp)
0x080484a8 <+55>: mov $0x80485a0,%eax
0x080484ad <+60>: mov 0x1c(%esp),%edx
0x080484b1 <+64>: mov %edx,0x8(%esp)
0x080484b5 <+68>: mov 0x18(%esp),%edx
0x080484b9 <+72>: mov %edx,0x4(%esp)
0x080484bd <+76>: mov %eax,(%esp)
0x080484c0 <+79>: call 0x8048340 <[email protected]>
0x080484c5 <+84>: leave
0x080484c6 <+85>: ret
Deneme ve hata ile değeri 24 anladım. Ayrıca, ana fonksiyonun 5 gdb demontajı ile değeri. – shashank
'p' değişkeni yığında da olmalı, böylece 4 bayt ekleyebilirsiniz, inanıyorum. Kalanın nereden geldiğinden emin değilim. –
Geriye doğru bakıldığında, 'a' ve 'b' argümanlarının hiçbir zaman verimlilik nedenleriyle yığından çıkarılmadığı, dolayısıyla hafızanın geri kalanını muhasebeleştirdiği de muhtemeldir. –