2016-07-10 20 views
-1

Hier ist, wie ein Stapelrahmen aussehen sollte:Mein Stack-Frames unterscheiden sich von dem Erbe einer

(high memory addresses) 
    -function arguments 
    -return address 
    -saved frame pointer 
    -local variables 
(low memory addresses) 

Die Frage ist, warum mein Stack-Frames so aussehen:

(high memory addresses) 
    -return address 
    -saved frame pointer 
    -local variables 
    -function arguments 
(low memory addresses) 

ich es bemerkt beim Debuggen in gdb. Ich code in C und kompiliere mit gcc 5.4.0 auf Kali Linux x86_64 (Intel Core i7).

C-Code:

void test_function(int a, int b, int c, int d) { 
    int flag; 
    char buffer[10]; 
    flag = 31337; 
    buffer[0] = 'A'; 
} 

int main() { 
    test_function(1, 2, 3, 4); 
    return 0; 
} 

Wert von RBP in main:

0x7fffffffe260 

Montageanleitung nach test_functtion Rufadresse:

0x00000000004004e1 

Ergebnis von x Befehl auf RSP, während sie in der Rahmen test_function:

0x7fffffffe240: 0x00000004 0x00000003 0x00000002 0x00000001 
0x7fffffffe250: 0x00400441 0x00000000 0x004003b0 0x00007a69 
0x7fffffffe260: 0xffffe270 0x00007fff 0x004004e1 0x00000000 
0x7fffffffe270: 0x004004f0 0x00000000 0xf7a575f0 0x00007fff 
+0

Da der Stapel _downwards_ wächst. – tkausl

+0

Ich weiß, aber wenn Sie es umkehren, entspricht es nicht einmal. –

+1

"So sollte ein Stack-Frame aussehen:". Woher hast du das? – kaylum

Antwort

0

Offenbar hat sich die Spezifikation eines Stapelrahmens zwischen x86 und x86_64 erheblich geändert. Sie sind korrekt für einen x86-Stack-Frame (Intel386 Processor Supplement). Die x86_64-Spezifikation (AMD64 Architecture Support Supplement) übergibt jedoch ganzzahlige Argumente in Registern (Abschnitt 3.2.3). Artikel # 2 unten:

  1. Wenn die Klasse MEMORY ist, übergeben Sie das Argument auf den Stapel.

  2. Wenn die Klasse INTEGER ist, wird das nächste verfügbare Register der Sequenz rdi,% rsi,% rdx,% rcx,% r8 und% r9 verwendet 13.

  3. Wenn die Klasse SSE ist, wird das nächste verfügbare Vektorregister verwendet, die Register werden in der Reihenfolge von% xmm0 bis% xmm7 erstellt.

  4. Wenn die Klasse SSEUP ist, wird die Achtbyte in dem nächsten verfügbaren Achtbyte-Chunk des zuletzt verwendeten Vektorregisters übergeben.

  5. Wenn die Klasse X87, X87UP oder COMPLEX_X87 ist, wird sie im Speicher übergeben.

Der Stapelrahmen sieht nun wie folgt aus:

x86_64 stack frame

Wenn Sie an der Stapelrahmen aussehen, die Rücksprungadresse in Haupt-8 [% rbp] oder 0x004005be und die Argumente sind in den richtigen Registern:

(gdb) x/32 $rbp 
0x7fffffffe040: 0xffffe050 0x00007fff 0x004005be 0x00000000 
0x7fffffffe050: 0x00000000 0x00000000 0xf7a36f45 0x00007fff 
0x7fffffffe060: 0x00000000 0x00000000 0xffffe138 0x00007fff 
0x7fffffffe070: 0x00000000 0x00000001 0x004005a1 0x00000000 
0x7fffffffe080: 0x00000000 0x00000000 0xdf5e7534 0x8acdbc8c 
0x7fffffffe090: 0x00400470 0x00000000 0xffffe130 0x00007fff 
0x7fffffffe0a0: 0x00000000 0x00000000 0x00000000 0x00000000 
0x7fffffffe0b0: 0x1f9e7534 0x75324373 0x02a47534 0x753253ca 
(gdb) info registers 
rax   0x4005a1 4195745 
rbx   0x0 0 
rcx   0x4 4 
rdx   0x3 3 
rsi   0x2 2 
rdi   0x1 1 
.... 
+0

Vielen Dank für die Antwort –