Variablen auf Stack, Leerräume

#4722707
Lesenswert?

Hallo,
ich habe mir gerade mal angesehen, wie bei einem C-Programm die 
Variablen auf dem Stack abgelegt werden.

Testfunktion
1
void test()
2
{
3
    int var1;                   // -0c
4
    unsigned char var2[8];      // [0] = -1c, [1] = -1b, [7] = -15
5
    struct tt {
6
        unsigned int aa;        // -34
7
        unsigned int bb;        // -30
8
        unsigned int cc;        // -2c
9
        unsigned int dd;        // -28
10
    } stt;
11
    int var3;                   // -40
12
}

Im Kommentar ist der Adressoffset zu ebp angegeben.

Dabei ist mir aufgefallen, dass zwischen einzelnen Variablen auf dem 
Stack immer 8 Bytes freigelassen werden. Hat das einen bestimmten Grund?

Getestet habe ich mit VS2013 unter 32-Bit Windows (x86).
#4722741
Lesenswert?

Rufus Τ. F. schrieb:

> Je nach Compilereinstellung können das "stack guards" sein, mit denen
> die Runtime-Library Stackfehler und Variablenläufe erkennen kann.

Dieser "Security Cookie" liegt an offset -4, dazwischen auch wieder 4 
Bytes frei und dann kommt die erste Variable.

Ja, zur Zeit übersetze in mit den Debug-Einstellungen. Dieser freie 
Platz führt doch sogar eher dazu, dass ich eventuelle Fehler nicht 
entdecke, weil nicht eine andere Variable, sondern unbenutzer Bereich 
überschrieben wird.
Persönliche Seite #4722826
Lesenswert?

Thomas W. schrieb:
> Dieser freie Platz führt doch sogar eher dazu, dass ich eventuelle
> Fehler nicht entdecke, weil nicht eine andere Variable, sondern
> unbenutzer Bereich überschrieben wird.

Beim Verlassen eines Blocks wird vom Runtime-Code der freie Platz 
überprüft, ob er sich geändert hat.

D.h. beim Betreten eines Blocks wird der benutzte Bereich des Stacks mit 
einem definierten Bitmuster (0xCD, wenn ich mich recht erinnere) 
initialisiert, und beim Verlassen des Blocks das Vorhandensein dieses 
Bitmusters in den Lücken geprüft.
#4722855
Lesenswert?

Rufus Τ. F. schrieb:

> D.h. beim Betreten eines Blocks wird der benutzte Bereich des Stacks mit
> einem definierten Bitmuster (0xCD, wenn ich mich recht erinnere)
> initialisiert, und beim Verlassen des Blocks das Vorhandensein dieses
> Bitmusters in den Lücken geprüft.

Ah, ok.

Der Anfang der Funktion sieht bei mir so aus:
1
push    ebp
2
mov     ebp, esp
3
sub     esp, 104h
4
push    ebx
5
push    esi
6
push    edi
7
lea     edi, [ebp+var_104]
8
mov     ecx, 41h
9
mov     eax, 0CCCCCCCCh
10
rep stosd
11
mov     eax, __security_cookie
12
xor     eax, ebp
13
mov     [ebp+var_4], eax
14
mov     [ebp+var_C], 0AAAAh
Die letzte Anweisung ist die erste aus meinem C-Code (var1 = 0xaaaa;)

D.h. da werden zu Beginn 260 Bytes auf dem Stack mit 0xcc beschrieben

Wobei dann die Stack-Check Funktion wissen müsste, an welcher Stelle die 
Variablen auf dem Stack abgelegt werden, um auch die Lücken zu 
überprüfen. Dazu sieht mir diese Funktion aber zu kurz aus.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren