2012-04-11 17 views
5

Yığın taşmasına ve Segmentation fault numarasına sahip olmanın bariz bir yolu, yığın çerçevelerini birbiri üstüne gelecek şekilde üst üste itmek olacaktır. Yeni yığma çerçevelerini bile zorlamadan yığın taşmasının gerçekleşip gerçekleşmeyeceğini merak ediyorum.Yığın yeni yığın çerçevelerini itmeden nasıl taşar?

Yeterince büyük bir dizi oluşturmak bunu deneyimden değil, diğer olası senaryolardan da yapabilir mi?

+0

Bu, Linux/UNIX ortamında olur. –

+1

'alloca' ve VLA’lar. – Mat

cevap

3

C99, yeniden boyutlandırabileceğiniz ve daha büyük bir boyuta yeniden boyutlandırabileceğiniz bir dizi kullanır. Ancak bu yeniden boyutlandırılabilir dizi, alloca kullanılarak uygulanır. İşte UNIX env bir örnek kod var:

#include <stdio.h> 
#include <alloca.h> 
#include <stdlib.h> 
#include <stdbool.h> 

int 
main() 
{ 
    while (true) 
    { 
     void *p = alloca(32UL); 
     printf("new memory allocated at %p \n", p); 
    } 
    exit(EXIT_SUCCESS); 
} 

Ve çıkış o ayarlayarak yığının üzerinde bellek tahsis dışında bu

new memory allocated at 0xbf800a60 
new memory allocated at 0xbf800a30 
new memory allocated at 0xbf800a00 
new memory allocated at 0xbf8009d0 
new memory allocated at 0xbf8009a0 
[1] 3977 segmentation fault ./a.out 

alloca gibi fonksiyonların malloc ailede olduğu bakacağız yığın işaretçisi.

1

Kötüye alloca() veya _alloca() Windows SDK/VS gelişmekte eğer:

alloca() fonksiyonu arayanın yığın çerçevede alanın boyutu bayt ayırır.

Not _alloca() Not lehine kabul edilmemektedir.

1

Temel olarak "yığın" ifadesi sadece bir bellek ve ESP/EBP bu belleğin sınırlarının dışına çıktığında bir yığın taşmasıdır. int x[10000000];

  • ESP doğrudan Set: __asm mov esp, 0x0
    1. kalan yığın alanı boyutundan daha büyük olan dev bir yığın-tahsis dizi oluşturun:

      yollarla bir dizi gerçekleştirebilirsiniz geçerli fonksiyon unwinds zaman Bozuk yığın yüzden, ESP/EBP çöp ayarlanır: int x; memset(&x, 0, 10000000);

    Ve coun ilan ve yığın boyutundan daha bir dizi daha büyük kullanarak

  • 1

    tless başka yollar ...:

    $ ulimit -s 
    8192 
    $ 
    

    sonra

    int main(void) 
    { 
        volatile char bla[8192 * 1024 + 16] = {0}; 
    } 
    

    çalıştırıldığında segfault muhtemeldir.

    +0

    neden uçucu? Örneğimde, programın başka bir yerinde kullanılmadığı için optimize etmesini önlemek için benim örneğimde –

    +0

    . Eğer 'printf' kullanarak tüm öğeleri basmak için' for' döngüsünü yaparsanız, derleyici onu optimize edemediğinden 'volatile' qualifer'e ihtiyacınız olmaz. – ouah