Beispielprogramm zu Codeinjection



  • Hallo,
    ich versuch zur Zeit ein Beispielprogramm zur Codeinjection zu schreiben. Babei orientiere ich mich an einem Programm, dass in Assembler vorliegt und ich in C++ übersetzen möchte. Hier erstmal der code von der Assemblerversion(gekürtzt aufs wesentliche, den kompletten code gibt es hier: http://www.governmentsecurity.org/forum/index.php?showtopic=16603):

    .code
    start:
        invoke GetModuleHandle,0
        mov [lpModule], eax
    
        mov edi,eax
        add edi,[	edi+3Ch]
        add edi,4
        add edi,14h
        mov eax,[edi+38h]
        mov [dwSize],eax
    
        invoke FindWindow,CTEXT ('IEFrame'),0                
        invoke GetWindowThreadProcessId, eax, addr ThePID    
        invoke OpenProcess,PROCESS_ALL_ACCESS, FALSE, ThePID 
        mov [lpProcess],eax
        invoke VirtualFreeEx, [lpProcess], [lpModule], 0, MEM_RELEASE
        invoke VirtualAllocEx, [lpProcess], [lpModule], dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE
        invoke WriteProcessMemory, [lpProcess], eax, [lpModule], [dwSize], addr nBytesWritten
        invoke CreateRemoteThread, [lpProcess], 0, 0, offset injected_thread, [lpModule], 0, ebx
      invoke ExitProcess,0
    
    injected_thread proc
      invoke LoadLibrary,CTEXT ('user32.dll')
      invoke MessageBox,0,CTEXT ('Success!!!'),CTEXT ('Hello From iexplorer'),0
        invoke ExitThread,0
        ret
    injected_thread endp
    

    So, und nun zu dem was ich bisher hab:

    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    void injectedThread();
    
    int main()
    {
        //get imagebase address
        HMODULE mHandle = GetModuleHandle(0);
    
        //PE headers stuff
        DWORD *mHandlePtr = reinterpret_cast<DWORD*>(&mHandle);
        mHandlePtr += 60;   // 3Ch = 60d
    
        DWORD mHandleEx = reinterpret_cast<DWORD>(mHandle) + *mHandlePtr;
        mHandleEx += 4;
        mHandleEx += 20;    //14h = 20d
    
        mHandlePtr = &mHandleEx;
        DWORD dwSize = *(mHandlePtr + 56);
    
        //Internet Explorer fenster finden:
        HWND hIExplorer = FindWindow("IEFrame", 0);
        if(hIExplorer == 0)
            cout << "Internet Explorer nicht gestartet." << endl;
        else
            cout << "Internet Explorer gefunden" << endl;
    
        DWORD dwPID;
        GetWindowThreadProcessId(hIExplorer, &dwPID);
        HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, false, dwPID);
        if(process == 0)
            cout << "Process konnte nicht geoeffnet werden" << endl;
        else
            cout << "Process geöffnet" << endl;
    
        bool bVFE = VirtualFreeEx(process, mHandle, 0, MEM_RELEASE);
        if( bVFE == 0)
            cout << "VirtualFreeEx hat ein Problem" << endl;
        else
            cout << "VirtualFreeEx hat speicher freigegeben" << endl;
    
        LPVOID baseAddrOfAllcRgn = VirtualAllocEx(process, mHandle, dwSize, MEM_COMMIT || MEM_RESERVE,PAGE_EXECUTE_READWRITE);
        if(baseAddrOfAllcRgn == NULL)
            cout << "VirtualAllocEx hat ein Problem" << endl;
        else
            cout << "VirtualAllocEx hat speicher reserviert" << endl;
    
        SIZE_T nBytesWritten;
        WriteProcessMemory(process, baseAddrOfAllcRgn, mHandle, dwSize, &nBytesWritten);
    
        LPDWORD lpNULL;
        CreateRemoteThread(process, 0, 0, (LPTHREAD_START_ROUTINE)injectedThread, mHandle, 0, lpNULL);
    
        ExitProcess(0);
    
        return 0;
    }
    
    void injectedThread()
    {
        LoadLibrary("user32.dll");
        MessageBox(0, "IExplorer", "Hello from iExplorer", 0);
    
        ExitThread(0);
    }
    

    Kompilieren lässt sich die C++ version auch, aber bei VirtualFreeEx bekomm ich als Rückgabewert immer 0. Woran kann das liegen?



  • Was sagt GetLastError () ?



  • 0, und danach stürtzt der Internet Explorer ab



  • Das der IE abstürzt, wird wohl eher an CreateRemoteThread liegen ..
    Und dass du 0 von GetLastError zurück bekommst, kann ich mir nicht vorstellen, zumindest nicht, wenn du die GetLastError direkt nach VirtualFreeEx aufrufst ..

    bool bVFE = VirtualFreeEx(process, mHandle, 0, MEM_RELEASE);
        if( bVFE == 0)
            cout << "VirtualFreeEx hat ein Problem: " << GetLastError () << endl;
        else
            cout << "VirtualFreeEx hat speicher freigegeben" << endl;
    

    Ich nehme einfach mal mit Hilfe meiner Kristallkugel an, dass du irgendwo falsche Parameter übergibst, wahrscheinlich direkt bei VirtualFreeEx ..



  • If the MEM_RELEASE flag is set in the dwFreeType parameter, lpAddress must be the base address returned by the VirtualAllocEx function when the region was reserved.
    

    ?



  • Ouh, verdammt, stimmt, ich bekomm nicht 0 zurück, sondern 87 (hatte mich auch schon gewundert). Respekt an deine Kristallkugel 🙂

    ERROR_INVALID_PARAMETER        The parameter is incorrect.
    87 (0x57)
    

    Fake oder Echt schrieb:

    If the MEM_RELEASE flag is set in the dwFreeType parameter, lpAddress must be the base address returned by the VirtualAllocEx function when the region was reserved.
    

    Heißt das, wenn ich MEM_RELEASE gesetzt hab, muss ich VirtualAllocEx() zuerst aufrufen?
    Ich hab das jetzt mal ausprobiert und zuerst VirtualAllocEx aufgerufen, bekomm für die Funktion aber auch den Fehler 87 zurück.

    Der Fehler scheint wohl am lpAdress parameter zu liegen, ich weiß allerdings nicht, wie ich das lösen kann



  • Ja gut, dann sollte ich meine Kristallkugel doch mal öfters auspacken 😛
    Bin drauf gekommen, weil du mHandle übergibst, und das ja das Handle von deinem eigenem Programm ist, du aber versuchst, dieses Handle im Prozess des IE zu allokieren bzw. freizugeben ..
    Ich hab mit diesen Funktionen leider keine Erfahrung, aber meine Vermutung ist, dass du nur Prozess-interne Handles allokieren kannst, wegen den Speicherbereichen ..
    Ob das richtig ist, weiß ich nicht, zumal damit ja eigentlich der Code injeziert werden soll ^^

    Also vllt. mit dem Handle des IEs probieren die Funktionen aufzurufen ..

    Und das du VirtualAllocEc vor VirtualFreeEx aurufen musst, war eben auch mein Gedanke wegen dieser Zeile in der Doku, deshalb hatte ich das gepostet ^^



  • Fake oder Echt schrieb:

    Bin drauf gekommen, weil du mHandle übergibst, und das ja das Handle von deinem eigenem Programm ist, du aber versuchst, dieses Handle im Prozess des IE zu allokieren bzw. freizugeben ..

    Als ich mir den Code von der Referenz angeguckt hab, ist mir das auch schon aufgefallen. Ich hab zwar auch keine Erfahrung mit diesen Funktionen, dafür aber ein wenig erfahrung mit Reverse Engineering.

    Ich werd das morgen mal mit GetModuleHandleEx() ausprobieren, vielleicht klappt das damit ja 😉



  • So, ich hab jetzt zuerst versucht statt GetModuleHandle die Funktion GetModuleHandleEx zu verwenden, allerdings versteh ich nicht, wie ich das andere Modul angeben muss (in diesem Fall den Internet Explorer).
    So wie ich das bisher verstanden hab, liefert GetModuleHandle die Imagebase Address, und die steht ja im PE Header im jeweiligen Programm. Ich hab dann den Internet Explorer mal in OllyDbg geöffnet um zu gucken, wo die Imagebase Address denn liegt und hab festgestellt, dass das Programm wahrscheinlich durch nen Packer oder ähnliches verändert wurde und ich die Imagebase address dadurch nicht bekomme. Deswegen hab ich ein anderes Programm genommen (OllyDbg) welches eine Imagebase address bei 400000 hat, wie mein Programm auch. Damit würde der Wert von GetModuleHandle für beide Programme der selbe sein. Doch sobald mein Programm bei den beiden Virtual...() Funktionen angekommen ist, bekomm ich wieder den Fehlercode 87.

    Ich weiß nicht weiter. Hat jemand eine Idee, was ich noch versuchen könnte?


Anmelden zum Antworten