Assembler in C als string



  • gcc 3.0.4

    Debian GNU/Linux Kernel 2.4.18



  • Original erstellt von kingruedi:
    **gcc 3.0.4

    Debian GNU/Linux Kernel 2.4.18**

    Hmm.. dass müsste dann eigentlich gehen.. das mit der Adresse hast du gemacht, oder? Ich könnt mich ja mal per ssh bei dir einloggen und probieren, kanns aber verstehen wen du das nicht willst 🙂



  • sonst lass den gcc das nur in asm übersetzen und poste mal den Code, das wird dann zwar in AT&T Syntax sein, aber dass ist halb so wild.

    mfg
    -bg-



  • Original erstellt von -bg-:
    **sonst lass den gcc das nur in asm übersetzen und poste mal den Code, das wird dann zwar in AT&T Syntax sein, aber dass ist halb so wild.
    **

    Dann aber bitte per
    gcc -masm=intel -S bla.c

    weil das produziert schönen intel-syntax-code (ab gcc 3) 😃



  • Original erstellt von TriPhoenix:
    **Dann aber bitte per
    gcc -masm=intel -S bla.c

    weil das produziert schönen intel-syntax-code (ab gcc 3) :D**

    hab ich gemach. In dem file bla.c steht:

    #include <stdio.h>
    #include <stdlib.h>
    
    char Hello[]={'H','e','l','l','o',' ','W','o','r','l','d','\n','\0'};
    char Hello2[]={'H','e','l','l','o',' ','w','o','r','l','d','!','\n','\0'};
    
    char C[]={
      "\x55"
      "\x89\xE5"
      "\x83\xEC\x10"  
    
      "\xBA\x0D\x00\x00\x00"    /* BA: edx - mov edx str-länge*/
      "\xB9\x15\x94\x04\x08"    /* B9: ecx - mov ecx addresse d string */  
      "\xBB\x01\x00\x00\x00"    /* BB: ebx - mov ebx 1 - stdout*/
      "\xB8\x04\x00\x00\x00"    /* B8: eax - mov eax 4 - sys_write*/
      "\xCD\x80"                /* int 80 - kernelaufruf (linux)*/
    
      "\xC3"
      };
    
    void hello()
    {
      printf("%s",Hello);
    }
    
    int main(int argc, char *argv[])
    {
      printf("%p\n",&Hello2);
    
      hello(); 
    
      void (*Z)()=(void*)C;
    
      Z();
    
      return 0;
    }
    

    und in der entstandenen bla.s steht:

    .file   "main.c"
        .intel_syntax
    .globl Hello
        .data
        .type   Hello,@object
        .size   Hello,13
    Hello:
        .byte   72
        .byte   101
        .byte   108
        .byte   108
        .byte   111
        .byte   32
        .byte   87
        .byte   111
        .byte   114
        .byte   108
        .byte   100
        .byte   10
        .byte   0
    .globl Hello2
        .type   Hello2,@object
        .size   Hello2,14
    Hello2:
        .byte   72
        .byte   101
        .byte   108
        .byte   108
        .byte   111
        .byte   32
        .byte   119
        .byte   111
        .byte   114
        .byte   108
        .byte   100
        .byte   33
        .byte   10
        .byte   0
    .globl C
        .type   C,@object
        .size   C,30
    C:
        .string "U\211\345\203\354\020\272\r"
        .string ""
        .string ""
        .string "\271\025\224\004\b\273\001"
        .string ""
        .string ""
        .string "\270\004"
        .string ""
        .string ""
        .string "\315\200\303"
        .section    .rodata
    .LC0:
        .string "%s"
        .text
        .align 2
    .globl hello
        .type   hello,@function
    hello:
        push    %ebp
        mov %ebp, %esp
        sub %esp, 8
        sub %esp, 8
        push    OFFSET FLAT:Hello
        push    OFFSET FLAT:.LC0
        call    printf
        add %esp, 16
        leave
        ret
    .Lfe1:
        .size   hello,.Lfe1-hello
        .section    .rodata
    .LC1:
        .string "%p\n"
        .text
        .align 2
    .globl main
        .type   main,@function
    main:
        push    %ebp
        mov %ebp, %esp
        sub %esp, 8
        and %esp, -16
        mov %eax, 0
        sub %esp, %eax
        sub %esp, 8
        push    OFFSET FLAT:Hello2
        push    OFFSET FLAT:.LC1
        call    printf
        add %esp, 16
        call    hello
        mov DWORD PTR [%ebp-4], OFFSET FLAT:C
        mov %eax, DWORD PTR [%ebp-4]
        call    %eax
        mov %eax, 0
        leave
        ret
    .Lfe2:
        .size   main,.Lfe2-main
        .ident  "GCC: (GNU) 3.2"
    

    Ich vermute dass dann die adresse, wo der string steht nicht mehr stimmt, aber das macht ja nix. hab mir das da oben aber noch nich so genau angeschaut, werd wahrscheinlich nicht allzu viel blicken



  • kleine Zwischenfrage während ihr überlegt 😉

    Was genau hat der da aus dem String C gemacht? ich kann da irgendwie gar nix mehr rauslesen (ich mein die Stelle da)

    C:
    .string "U\211\345\203\354\020\272\r"
    .string ""
    .string ""
    .string "\271\025\224\004\b\273\001"
    .string ""
    .string ""
    .string "\270\004"
    .string ""
    .string ""
    .string "\315\200\303"
    .section    .rodata
    


  • Vielleicht muss man wie bei manchen Viren di Adressen alle relativ berechnen?
    call relativ
    relativ:
    ;jetzt addi vom stack holen und alles andere relativ dazu angeben.



  • ähh, ja.. kann mir jemand nen link sagen, wo das mit dem relativ erklärt ist (oder mir gleich erklären)? Bin (noch) nicht so gut in Assembler.



  • Na, ich denke mal der call wird schon stimmen...
    Ansonsten kann ich auch net mehr dazu sagen, da mir ebenfalls schleierhaft ist, was der Compiler aus dem String gemacht hat.



  • Mir ist nochetwas äußerst merkwürdiges aufgefallen: Der Speicherzugriffsfehler passiert garnicht in Z(), sondern ich kann das programm noch alles mögliche machen lassen, und erst ganz am Schluss beim Beenden kommt der Fehler (nach return glaub ich, da bin ich mir aber nicht sicher)
    Ich find das ziemlich 😕 😕 😕

    Nachtrag:
    DDD (gdb) sagt mir folgendes:

    Program received signal SIGSEGV, Segmentation Fault.
    0x40041e70 in _dl_pagesize () from /lib/libc.so.6

    das ist zwei steps nach der }-Klammer-Zu von main 😕

    Nachtrag 2:
    hab übrigens jetzt keinen char C[]=... string mehr, sondern mit malloc angelegt und dann mit C[x]=0xSoUndSo alles reingeschrieben,dann ausgeführt und dann ordentlich free... aber es passiert auch in der alten version genauso

    [ Dieser Beitrag wurde am 16.11.2002 um 21:50 Uhr von Chickenman editiert. ]



  • Der Code scheint mir verdammt konfus, z.B.:

    mov %eax, 0
      sub %esp, %eax
    ;oder
      sub %esp, 8 
      sub %esp, 8 ;also ich kann 8 und 8 zusammenzählen, und gcc?
    

    Optimiert soetwas echt???

    so, hab mal nachgeguckt, 0xC3 ist wirklich ret, aber da der compiler ein call %eax macht, liegt nahe, dass dies ein far call ist (schau mal nach, dass müsste dann ein FF D0 (musste das jez doch glatt ma durch nasm jagen :)).
    Daher solltest du es mal mit nem far ret (0xCB) versuchen. Das würde auch das Problem erklären. Das ist das bekannte Prob, dass das OS meckert wenn der Stack nacher anders ist als vorher.
    Und das wirkt sich natürlich dann erst nach dem beenden deines progs aus.

    mfg
    -bg-



  • Nee, das isses auch nicht, obwohl es so schön logisch klingt 😞
    Da wird das prog dann gar nicht erst beendet.. da geht er gleich in der funktion flöten 😞



  • Original erstellt von -bg-:
    so, hab mal nachgeguckt, 0xC3 ist wirklich ret, aber da der compiler ein call %eax macht, liegt nahe, dass dies ein far call ist (schau mal nach, dass müsste dann ein FF D0 (musste das jez doch glatt ma durch nasm jagen :)).

    Warum soll call %eax ein far-call sein? Ist doch kein Fremdes segment drin verwickelt, FF D0 ist auch n u ein near call, einen Far-call hast du erst, wenn ein anderes Segment involviert ist. So stüruzt das Programm natürlich beim far ret ab weil es ein illegales segment versucht zu erreichen 🙂



  • Original erstellt von Chickenman:
    **```
    char C[]={
    "\x55"
    "\x89\xE5"
    "\x83\xEC\x10"

    "\xBA\x0D\x00\x00\x00" /* BA: edx - mov edx str-länge*/
    "\xB9\x15\x94\x04\x08" /* B9: ecx - mov ecx addresse d string /
    "\xBB\x01\x00\x00\x00" /
    BB: ebx - mov ebx 1 - stdout*/
    "\xB8\x04\x00\x00\x00" /* B8: eax - mov eax 4 - sys_write*/
    "\xCD\x80" /* int 80 - kernelaufruf (linux)*/

    "\xC3"
    };

    Disassembliert:
    push ebp
    mov esp, ebp
    sub esp, 16
    mov edx, 0x0000000d
    mov ecx, 0x08049415
    mov ebx, 0x00000001
    mov eax, 0x00000004
    int 0x80
    ret

    Wolltest du nicht vielelihct den Stack wieder herrichten per
    mov esp, ebp
    ? 🙂

    [ Dieser Beitrag wurde am 17.11.2002 um 14:57 Uhr von TriPhoenix editiert. ]



  • @Tri: und das jetzt noch mal für noch nicht ganz so gut asm könner? 🙄
    Versteh nicht ganz was du mir damit sagen willst



  • Du musst den Stack am Ende der Funktion wieder so machen, wie er vorher war. Du lässt ihn aber einfach so wie er ist, und das geht garantiert schief.



  • Um CD9000s post mal zu verdeutlichen:

    Stack bevor die FUnktion aufgerufen wird:

    ...
    ------------------
    Rücksprungaddresse am Ende von main
    ------------------
    alter EBP vor main
    ------------------
    Variable Z
    ------------------

    Stack nachdem die Funktion aufgerufen wurde (in der Funktion):
    ...
    ------------------
    Rücksprungaddresse am Ende von main
    ------------------
    alter EBP vor main
    ------------------
    Variable Z
    ------------------
    Rücksprungaddresse von der asm-Funktion
    ------------------
    alter EBP vor der asm-Funktion
    ------------------

    Da beginnen die Probleme, der return springt dann nicht zurück an main, sondenr dahin, wo halt EBP drauf gezeigt hat und das geht shconmal schief.
    Korrekt wäre mov esp, EBP, damit der Stakc wieder in dem Zustand VOR dewm Aufruf der asm-Funktion ist


Anmelden zum Antworten