Ergebnis 1 bis 2 von 2
  1. #1
    NoClose Wurm Avatar von Zer0Flag
    Registriert seit
    27.06.2009
    Beiträge
    198

    Standard [C++] Example_Loader

    Hey,

    Ich habe hier einen kleinen Loader für ein reverseMe von Lena151 gemacht. Bei diesem Target wäre ein Patch wohl einfacher gewesen aber ich dachte mir Übung schadet nie . Hoffe iwer anderst kann mit dem Source auch noch etwas anfangen. Im Anhang befindet sich der Loader sowie das reverseME.

    Code:
    #include <Windows.h>
    
    #define WIN32_LEAN_AND_MEAN
    #define VC_EXTRALEAN
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    
    /*
    CPU Disasm
    Address   Hex dump          Command                                  Comments
    0040107B    EB 1D           JMP SHORT reverseMe.0040109A
    0040107D  . 6A 00           PUSH 0                                   ; Type = MB_OK|MB_DEFBUTTON1|MB_APPLMODAL
    0040107F  . 68 00204000     PUSH OFFSET reverseMe.00402000           ; Caption = " Key File ReverseMe"
    00401084  . 68 17204000     PUSH OFFSET reverseMe.00402017           ; Text = "Evaluation period out of date. Purchase new license"
    00401089  . 6A 00           PUSH 0                                   ; hOwner = NULL
    0040108B  . E8 D7020000     CALL <JMP.&USER32.MessageBoxA>           ; Jump to USER32.MessageBoxA
    00401090  . E8 24020000     CALL <JMP.&KERNEL32.ExitProcess>         ; KERNEL32.ExitProcess
    00401095  . E9 83010000     JMP reverseMe.0040121D
    0040109A  > 6A 00           PUSH 0                                   ; pOverlapped = NULL
    0040109C  . 68 73214000     PUSH OFFSET reverseMe.00402173           ; pBytesRead = reverseMe.402173 -> 0
    004010A1  . 6A 46           PUSH 46                                  ; Size = 70.
    004010A3  . 68 1A214000     PUSH OFFSET reverseMe.0040211A           ; Buffer = reverseMe.40211A -> 00
    004010A8  . 50              PUSH EAX                                 ; hFile
    004010A9  . E8 2F020000     CALL <JMP.&KERNEL32.ReadFile>            ; KERNEL32.ReadFile
    004010AE  . 85C0            TEST EAX,EAX
    004010B0    EB 02           JMP SHORT reverseMe.004010B4
    004010B2  . EB 43           JMP SHORT reverseMe.004010F7
    004010B4  > 33DB            XOR EBX,EBX
    004010B6  . 33F6            XOR ESI,ESI
    004010B8  . 833D 73214000 1 CMP DWORD PTR DS:[reverseMe.402173],10
    004010BF     90             NOP
    004010C0     90             NOP
    004010C1  > 8A83 1A214000   MOV AL,BYTE PTR DS:[EBX+reverseMe.40211A
    004010C7  . 3C 00           CMP AL,0
    004010C9    EB 08           JMP SHORT reverseMe.004010D3
    004010CB  . 3C 47           CMP AL,47
    004010CD  . 75 01           JNE SHORT reverseMe.004010D0
    004010CF  . 46              INC ESI
    004010D0  > 43              INC EBX
    004010D1  . EB EE           JMP SHORT reverseMe.004010C1
    004010D3  > 83FE 08         CMP ESI,8
    004010D6     90             NOP
    004010D7     90             NOP
    */
        CONTEXT*              tCONTEXT = 0;
        STARTUPINFO*          tSTARTUPINFO = 0;
        PROCESS_INFORMATION*  tPROCESS_INFORMATION = 0;
    
        DWORD Patch1 = 0x40107B;
        DWORD Patch2 = 0x4010B0;
        DWORD Patch3 = 0x4010BF;
        DWORD Patch4 = 0x4010C9;
        DWORD Patch5 = 0x4010D6;
    
        UCHAR PatchVal1[] = "\xEB\x1D";
        UCHAR PatchVal2[] = "\xEB\x02";
        UCHAR PatchVal3[] = "\x90\x90";
        UCHAR PatchVal4[] = "\xEB\x08";
        UCHAR PatchVal5[] = "\x90\x90";
    
        char* cCommandLine = GetCommandLine();
    
        tCONTEXT = (CONTEXT*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CONTEXT));
        tSTARTUPINFO = (STARTUPINFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STARTUPINFO));
        tPROCESS_INFORMATION = (PROCESS_INFORMATION*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PROCESS_INFORMATION));
    
        tCONTEXT->ContextFlags = CONTEXT_FULL;
        tSTARTUPINFO->cb = sizeof(STARTUPINFO);
    
    
        if(CreateProcessA("reverseMe.exe", cCommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, tSTARTUPINFO, tPROCESS_INFORMATION)){
    
            WriteProcessMemory(tPROCESS_INFORMATION->hProcess, (LPVOID)Patch1, &PatchVal1, sizeof(PatchVal1)-1, NULL);
            WriteProcessMemory(tPROCESS_INFORMATION->hProcess, (LPVOID)Patch2, &PatchVal2, sizeof(PatchVal2)-1, NULL);
            WriteProcessMemory(tPROCESS_INFORMATION->hProcess, (LPVOID)Patch3, &PatchVal3, sizeof(PatchVal3)-1, NULL);
            WriteProcessMemory(tPROCESS_INFORMATION->hProcess, (LPVOID)Patch4, &PatchVal4, sizeof(PatchVal4)-1, NULL);
            WriteProcessMemory(tPROCESS_INFORMATION->hProcess, (LPVOID)Patch5, &PatchVal5, sizeof(PatchVal5)-1, NULL);
    
    
            ResumeThread(tPROCESS_INFORMATION->hThread);
        }
    
        return 0;
    }


    Download:
    Code:
    http://www.multiupload.com/YKCNJU4Y38
    ~Zer0Flag

  2. Folgende Benutzer haben sich für diesen Beitrag bedankt:

    GregorSamsa (15.09.2010)

  3. #2
    I'm in ur VM. Avatar von l0dsb
    Registriert seit
    23.07.2007
    Beiträge
    1.038

    Standard

    Erst einmal Danke für das Posten (auch wenn ich den Post vorher schon auf drei anderen (RCE-)Boards sah ). Ich hoffe, die konstruktive Kritik hilft dir weiter:

    Wieso allokierst du CONTEXT-, STARTUP- und PROCESS_INFORMATION-Strukturen auf dem Heap? Wie Op schon sagte, wäre da new (und ein passendes delete, bei dir vermisse ich HeapFree) angebracht.

    Selbst dann ist es doch viel einfacher, das ganze auf dem Stack zu allokieren - die Strukturen sind nicht wirklich groß und die Stackvariante ist wesentlich einfacher zu schreiben und letzten Endes vermutlich noch performanter (kein Memory-Leak ).

    Du solltest dir noch im Klaren darüber sein, dass GetCommandLine auch den Pfad der eigenen Anwendung beinhaltet, diesen müsstest du also zuerst "rausschneiden" - oder einfach den passenden Parameter von WinMain verwenden.

    VC_EXTRALEAN und WIN32_LEAN_AND_MEAN sind bei so einem Projekt unnötig, selbst bei größeren konnte ich nie einen wirklichen Unterschied in der Build-Geschwindigkeit feststellen. Die würde ich weglassen, zusätzliche Schreibarbeit.

    Zuletzt wären noch Fehlerabfragen bei WriteProcessMemory sinnvoll und natürlich die Überprüfung per ReadProcessMemory, ob die zu patchende Location auch den richtigen Wert beinhaltet (bzw. für ganz paranoide noch eine Checksum über die ganze Binary).

    Die Patches selbst (Adressen, alte und neue Werte) kann man prima in ein Array verlagern, somit spart man sich das Kopieren des WriteProcessMemory-Aufrufs und muss lediglich einen neuen Datensatz einfügen.
    I can haz RCE?

  4. Folgende Benutzer haben sich für diesen Beitrag bedankt:

    blackberry (15.09.2010), ocz (15.09.2010), Zer0Flag (15.09.2010)

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •