Binary Reconstruction (einfacher puts) Frage



  • Guten Tag EDV Begeisterte xD,

    Ich habe ein kleines sinnloses Programm geschrieben, und habe es via gcc -o puts puts.c -fomit-frame-pointer assembliert. Anschliessend mit objdump -d ./puts und gdb begutachtet und analysiert, dabei sind mir diverse Fragen aufgetreten. Zuerst möchte ich das Werk zeigen und meine Dumps:

    (gdb) disas main
    Dump of assembler code for function main:
    0x08048354 <main+0>:    lea    0x4(%esp),%ecx
    0x08048358 <main+4>:    and    $0xfffffff0,%esp
    0x0804835b <main+7>:    pushl  0xfffffffc(%ecx)
    0x0804835e <main+10>:   push   %ecx
    0x0804835f <main+11>:   sub    $0x8,%esp
    0x08048362 <main+14>:   movl   $0x8048488,(%esp)
    0x08048369 <main+21>:   call   0x804827c <puts@plt>
    0x0804836e <main+26>:   mov    $0x9,%eax
    0x08048373 <main+31>:   add    $0x8,%esp
    0x08048376 <main+34>:   pop    %ecx
    0x08048377 <main+35>:   lea    0xfffffffc(%ecx),%esp
    0x0804837a <main+38>:   ret
    0x0804837b <main+39>:   nop
    0x0804837c <main+40>:   nop
    0x0804837d <main+41>:   nop
    0x0804837e <main+42>:   nop
    0x0804837f <main+43>:   nop
    End of assembler dump.
    (gdb) break *0x0804835e
    Breakpoint 1 at 0x804835e
    (gdb) run
    Starting program: /home/xxx/yy/puts
    
    Breakpoint 1, 0x0804835e in main ()
    (gdb) x/d 0xfffffffc+$ecx
    0xbffffa7c:     1073958568
    (gdb) x/s 0xfffffffc+$ecx
    0xbffffa7c:      "¨N\003@\001"
    (gdb) break *0x08048377
    Breakpoint 2 at 0x8048377
    

    Ich habe das folgendermassen Kommentiert, ist das korrekt?

    (gdb) disas main
    Dump of assembler code for function main:
    0x08048354 <main+0>:    lea    0x4(%esp),%ecx			; Speichert argc in reg ecx
    0x08048358 <main+4>:    and    $0xfffffff0,%esp			; alignment von esp (Wieso?)
    0x0804835b <main+7>:    pushl  0xfffffffc(%ecx)			; -4(ecx) ??
    0x0804835e <main+10>:   push   %ecx				; pusht argc auf den Stack
    0x0804835f <main+11>:   sub    $0x8,%esp			; reserviert 8-byte speicher aufm stack
    0x08048362 <main+14>:   movl   $0x8048488,(%esp)		; stellt die String-Adresse "Hey" in esp
    0x08048369 <main+21>:   call   0x804827c <puts@plt>		; ruft puts auf
    0x0804836e <main+26>:   mov    $0x9,%eax			; stellt 9 in eax für return
    0x08048373 <main+31>:   add    $0x8,%esp			; deallokiert/säubert den Stack um 8-byte
    0x08048376 <main+34>:   pop    %ecx				; holt argc vom stack
    0x08048377 <main+35>:   lea    0xfffffffc(%ecx),%esp		; 4(ecx) ??
    

    Meine Fragen sind:

    a) Bei main+4 geschieht ein Alignment von -15 Byte, was passiert genau? Was für Auswirkungen hat das für $esp und den zukünftigen Programmverlauf?

    b) Bei main+7, wird 0xfffffffc(%ecx) bzw. -4(ecx) auf den Stack gespeichert/gepusht. Was ist da drin genau? Was bringt das?
    Ich versuchte dies mit gdb:

    Breakpoint 1, 0x0804835e in main ()
    (gdb) x/d -4+$ecx
    0xbffffa7c:     1073958568
    (gdb) x/s -4+$ecx
    0xbffffa7c:      "¨N\003@\001"
    (gdb) x/s 0xfffffffc+$ecx
    0xbffffa7c:      "¨N\003@\001"
    

    Das 001 wird wahrsch. argc sein, korrekt? (Ich habe nur 'run' getippt, ohne argumente) Wieso wird argc für den weiteren Programmverlauf gespeichert?

    Und das führt zu meiner nächsten Frage
    c) Wieso wird argc verarbeitet und gespeichert, etc. und wieso argv[0] z.B. nicht? Ich kann nämlich nirgends den Programmnamen sehen, wenn ich in GDB erforsche.

    d) main+34, hier wird argc vom Stack in ecx wieder gespeichert. Was interessiert das Programm die Anzahl der Argumente am *Programmende*??

    und

    e) main+35, lea 0xfffffffc(%ecx),%esp ; -4(ecx) ?? Wieso wird das wieder auf den/in den Stack gepusht?

    Viele Fragen, ich hoffe auf viele gute Antworten. Hier ist mein C-Source:

    $ cat puts.c

    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
            puts("hey\n");
            return 9;
    }
    

    Merci beaucoup,

    ASM Newbie.



  • schalt mal die Optimierung aus

    ASM-Newbie schrieb:

    (gdb) disas main
    Dump of assembler code for function main:
    0x08048354 <main+0>:    lea    0x4(%esp),%ecx
    0x08048358 <main+4>:    and    $0xfffffff0,%esp
    0x0804835b <main+7>:    pushl  0xfffffffc(%ecx)
    
    0x08048377 <main+35>:   lea    0xfffffffc(%ecx),%esp
    

    Die Zeilen werden sicher durch den -O switch erzeugt, jedenfalls probier es mal ohne dann sollte da was anderes stehen was leichter verständlich ist. Am Anfang normalerweise die Sicherung des momentanen Stackframepointers und am Schluss ein Leave. Wie schon erwähnt schätze ich das es durch die Optimierungseinstellung kommt, kompilier mal ohne.

    bye

    tt



  • Hi

    Ich will nicht aus dem Weg gehen des Problems. Aber trotzdem Danke für deinen Beitrag. Hat jemand eine Ahnung, ohne dass er mir empfiehlt wie ich es compilieren soll? Danke


Anmelden zum Antworten