Dynamischer Code



  • Du musst die entsprechende Page Attribute für mem setzen: VirtualProtect
    Die relative call Adresse (E8!) berechnet sich nach: &foo - &mem[6]
    Außerdem musst du die Rücksprungadresse auf den Stack puschen und diesen nach der Rückkehr korrigieren (c-call).
    Es handelt sich um eine 32Bit Anwendung?

    BTW: FAR jumps werden nicht gebraucht.



  • upps: &mem[5]



  • masm schrieb:

    Du musst die entsprechende Page Attribute für mem setzen: VirtualProtect

    Muss ich das wirklich?
    Jetzt geht es zumindest so, aber das könnte auch Zufall sein.
    Allerdings kann man ja Speicher den man mittels malloc bekommen hat beschreiben und lesen, also würde ich vermuten, dass das nicht unbedingt nötig ist.

    masm schrieb:

    Die relative call Adresse (E8!) berechnet sich nach: &foo - &mem[6]

    Jo, so gehts 🙂 (Edit: +-1)

    masm schrieb:

    Außerdem musst du die Rücksprungadresse auf den Stack puschen und diesen nach der Rückkehr korrigieren (c-call).

    Gut, wird der nächste Schritt sein

    livinskull schrieb:

    Wenn du die Ziel-Offsets direkt reinschreiben willst solltest nicht relative Jumps/Calls sondern absolute Jumps/Calls nehmen[/url]

    Normalerweise sollten aber die Intel Manuals vorgezogen werden 🙂

    Absolute jmps sind bestimmt eine gute Alternative, dann muss ich nicht so viel rumrechnen.
    Probiere ich auch aus 🙂



  • EVIL_ENT schrieb:

    masm schrieb:

    Du musst die entsprechende Page Attribute für mem setzen: VirtualProtect

    Muss ich das wirklich?

    Ja, sollte man hinsichtlich DEP machen. Bei DLLs ist es zwingend, sofern diese von Prozessen geladen werden, die DEP unterstützen bzw. bei denen es aktiviert ist.



  • Falsches Forum,

    #define xy hex
    // und dann auch noch unvollständig
    

    ist mit Sicherheit kein Assembler 😉



  • nachtfeuer schrieb:

    Falsches Forum,

    #define xy hex
    // und dann auch noch unvollständig
    

    ist mit Sicherheit kein Assembler 😉

    Man kann sich auch anstellen...
    Der Code ist offensichtlich beides und es werden wohl mehr Leute die Assembler kennen auch C können als andersherum.
    Außerdem hätten mir Leute, die nur C/++ können bei meinem Problem wohl kaum weiter helfen können.

    Ist aber egal, ist alles gelöst.



  • EVIL_ENT schrieb:

    Ist aber egal, ist alles gelöst.

    Das ist aber nicht besonders wartbar. Du hast bisher nur zwei Opcodes verwendet, bei mehr wird es deutlich unübersichtlicher. Es gibt doch genug C/C++ Bibliotheken, die dir die Opcodes und Parameter generieren, mit denen kann man deutlich übersichtlicher arbeiten.



  • Falls es noch jemand interessiert, wie man es mit VirtualAlloc() macht, hier ein Beispiel:

    #define SIZE    (32u)
    unsigned char *p = NULL;
    DWORD old_protect = 0;
    
    p = VirtualAlloc(NULL, SIZE, MEM_COMMIT, PAGE_READWRITE);
    p[0] = 0x90u;
    p[1] = 0xC3u;
    
    VirtualProtect(p, SIZE, PAGE_EXECUTE, &old_protect);
    
    ((void (*)(void))p)();
    

    so müsste es gehen... wer Fehler findet - bekommt von mir nichts 🙂



  • abc.w schrieb:

    Falls es noch jemand interessiert, wie man es mit VirtualAlloc() macht, hier ein Beispiel

    Das Beispiel macht mehr als Nötig ;-D



  • Mechanics schrieb:

    Es gibt doch genug C/C++ Bibliotheken, die dir die Opcodes und Parameter generieren, mit denen kann man deutlich übersichtlicher arbeiten.

    Schön, war mir neu 😃
    Hab mal versucht danach zu suchen, aber kenn wohl nicht die richtigen Keywords.
    Das hier finde ich aber immer noch halbwegs lesbar.
    (Edit: Ok, mit instructions die mehr als 1 Byte brauchen ist es etwas unhandlich, ich überleg mir was.)
    Allerdings weiß ich nicht, ob ich einfach so ein globales array für meinen Code verwenden darf, oder ob ich das immer per VirtualAlloc machen sollte.

    #include <windows.h>
    
    #define NOP        0x90
    #define CALL       0xE8
    #define JMP        0xE9
    #define PUSH_EBP   0x55
    #define MOV        0x89
    #define ESP_TO_EBP 0xE5
    #define EBP_TO_ESP 0xEC
    #define POP_EBP    0x5D
    #define RET        0xC3
    
    void foo(){
        MessageBox(NULL, "Hello World!", "Success!", MB_OK);
    }
    
    BYTE code[12] = {
        //enter function
        PUSH_EBP,
        MOV, ESP_TO_EBP,//EDIT: this line is one instruction
        //call address
        CALL, 0, 0, 0, 0,
        //leave function
        MOV, EBP_TO_ESP,//EDIT: this line is one instruction
        POP_EBP,
        RET
    };
    
    int main(){
        DWORD dw = 0;
        VirtualProtect(code, sizeof(code), PAGE_EXECUTE_READWRITE, &dw);
         *(DWORD*)(code + 4) = (DWORD)foo  - (DWORD)code - 1 - 4 - 3;
        void(*test)() = (void(*)())code;
        test();
        return 0;
    }
    

Anmelden zum Antworten