Assembler in C als string



  • ok, hab jetzt nur ret drin, und immer noch das gleiche...
    So siehts jetzt aus:

    "\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"
    


  • Sicher, dass das ganze als NEAR call aufgerufen wird?
    Probiers doch mal mit retf (CB).



  • nee, auch nicht.. das programm ansich ist immer noch das gleiche wie am Anfang, nur das im string hat sich geändert



  • Soviel ich weiss, muss man Assembler-Subroutinen importieren.

    Meiner Meinung nach, schreibt der C Compiler noch irgendwelche Markierungen in den Code, so dass da keine funktionierende Assembler subroutine steht, sondern nur die Zeichen. Wenn da überhaupt einer wäre ist nicht garantiert dass er auch funktioniert. Hast du ihn denn schon getestet? Ausserdem muss der Code an einer geraden Speicherstelle beginnen. Oder muss es sogar eine doubleword Grenze sein?



  • Code darf auf Intel beginnen wo er will. Das Problem wird sien, dass die Sieten in dem der "Code" steht, nicht ausführbar sind, d.h. es ist nicht erlaubt von den Seiten im Speicher Code auszuführen. Das müsste man mit nem Syscall ändern, aber ich kann dir leider net sagen wie unter Linux



  • Aber wieso funktioniert der Code dann bis zum Ende und gibt dann erst nen Fehler 😕 😕



  • bei mir geht der Code gar nicht (also vorher wird Hello, World! ausgegeben, durch das printf).

    @Tri
    warum gehen dann bufferoverflow exploits?

    [ Dieser Beitrag wurde am 10.11.2002 um 18:01 Uhr von kingruedi editiert. ]



  • Original erstellt von kingruedi:
    **bei mir geht der Code gar nicht (also vorher wird Hello, World! ausgegeben, durch das printf).
    **

    Was hast du für Compiler/System?

    Es sollte erst die Adresse kommen (von dem String mit asm-code)
    dann sollte
    Hello World und
    Hello world! kommen...

    Hello world! wird von dem asm-code ausgegeben..

    Bevor das ganze läuft musst du einmal compilieren, dann die Adresse ankucken und in den Code eintragen, wo
    /* B9: ecx - mov ecx addresse d string */
    steht..
    dh wenn als adresse 0x8049415 da steht musst du in zweierschritten rückwärts in den Code eintragen, also als erstes 15 dann 94 dann 04 als letztes 08

    "\xB9\x15\x94\x04\x08" /* B9: ecx - mov ecx addresse d string */
    hier->  |   |   |   |
    

    und dann nochmal compilieren

    [ Dieser Beitrag wurde am 10.11.2002 um 18:21 Uhr von Chickenman editiert. ]

    [ Dieser Beitrag wurde am 10.11.2002 um 18:23 Uhr von Chickenman editiert. ]



  • 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 😞


Anmelden zum Antworten