Programm im Speicher erzeugen und ausführen



  • ^^man könnte 'createprocess' nachbauen bzw. abändern. für die exe wird ja ein 'section objekt' (auch als filemapping bekannt) angelegt. da könnte man vielleicht ansetzen und eine dateilose section (CreateFileMapping() ohne gültiges file-handle aufrufen) erzeugen, die man dann mit den daten der exe füttert. hört sich nach viel bastelei an, wär aber sicherlich interessant, sich 'ne CreateMemoryProcess()-funktion zu bauen.
    🙂



  • @AntonWert: Das geht ungefähr in drei-vier Schritten, Speicher allokieren (1), Deine Daten, die ja ausführbaren Code darstellen, rüberkopieren (2), den Speicherbereich als ausführbar "einstellen" und Funktionspointer darauf (3) setzen:

    {
        void (*my_func)(void) = NULL;
        void *pMem = NULL;
        void *pDeineDaten = NULL;
        DWORD ManyBytes = 4096;
        DWORD OldProtect = 0;
    
        ... /* pDeineDaten mit Daten füllen */
    
        pMem = VirtualAlloc(NULL, ManyBytes, MEM_COMMIT, PAGE_READWRITE);
        memcpy(pMem, pDeineDaten, ManyBytes);
        VirtualProtect(pMem, ManyBytes, PAGE_EXECUTE, &OldProtect);
        my_func = (void (*)(void))pMem;
        my_func();
    }
    

    Viel Glück beim Debuggen! 🙂



  • abc.w schrieb:

    @AntonWert: Das geht ungefähr in drei-vier Schritten, Speicher allokieren (1), Deine Daten, die ja ausführbaren Code darstellen, rüberkopieren (2), den Speicherbereich als ausführbar "einstellen" und Funktionspointer darauf (3) setzen:

    {
        void (*my_func)(void) = NULL;
        void *pMem = NULL;
        void *pDeineDaten = NULL;
        DWORD ManyBytes = 4096;
        DWORD OldProtect = 0;
    
        ... /* pDeineDaten mit Daten füllen */
    
        pMem = VirtualAlloc(NULL, ManyBytes, MEM_COMMIT, PAGE_READWRITE);
        memcpy(pMem, pDeineDaten, ManyBytes);
        VirtualProtect(pMem, ManyBytes, PAGE_EXECUTE, &OldProtect);
        my_func = (void (*)(void))pMem;
        my_func();
    }
    

    Viel Glück beim Debuggen! 🙂

    ^^ so kannste aber keine 'richtige exe' ausführen.
    🙂



  • das klappt so nicht. zum einen, weil die relocaton fehlt und zum anderen weil die
    echse einen header hat, den du mitausführen willst. 😉



  • Ach so, eine richtige exe soll es sein, habe ich überlesen. Dann... keine Ahnung... 🙂



  • vielleicht schaust mal im ReactOS source code wie CreateProcess() funktioniert, da die exe ja sowieso zuerst in den speicher geladen wird damit sie überhaupt ausführbar ist. alles andere sollte sich dann ergeben, oder FreeDOS wie die exe laden... etc..



  • mittlerweile habe ich es geschafft, kernel32 funktionen erfolgreich
    umzubiegen. allerdings scheint weder CreateProcess noch LoadLibrary
    auf dateifunktionen wie CreateFile zurückzugreifen. 😞

    wie machen die das? ich versuche grade die ntdll funktionen zu hooken.
    vielleicht klappt das ja.



  • du musst dazu nicht zwingend createprocess umschreiben,es sind nur folgende schritte nötig:

    - .exe einlesen (optional)
    - entsprechend speicher allocieren für dos/ntheader
    - header in allocierten speicher kopieren,sections richtig erstellen
    - STARTUPINFO/PROCESS_INFORMATION/CONTEXT richtig setzen
    - CreateProcess aufrufen

    poc code dazu:

    //--------------------------------------------------------
    // Dynamic Process Forking of Portable Executable
    // Author : Vrillon / Venus
    // Date   : 07/14/2008
    //--------------------------------------------------------
    /*********************************************************/
    /* With this header, you can create and run a process    */
    /* from memory and not from a file.                      */
    /*********************************************************/
    
    #ifdef WIN32
        #include <windows.h>
    #else
        #error Process Forking Requires a Windows Operating System
    #endif
    
    #include <stdio.h>
    
    /////////////////////////////////////////////////////////////
    // NtUnmapViewOfSection (ZwUnmapViewOfSection)
    // Used to unmap a section from a process.
    typedef long int (__stdcall* NtUnmapViewOfSectionF)(HANDLE,PVOID);
    NtUnmapViewOfSectionF NtUnmapViewOfSection = (NtUnmapViewOfSectionF)GetProcAddress(LoadLibrary("ntdll.dll"),"NtUnmapViewOfSection");
    
    /////////////////////////////////////////////////////////////
    // Fork Process
    // Dynamically create a process based on the parameter 'lpImage'. The parameter should have the entire
    // image of a portable executable file from address 0 to the end.
    bool ForkProcess(LPVOID lpImage)
    {
        // Variables for Process Forking
        long int                lWritten;
        long int                lHeaderSize;
        long int                lImageSize;
        long int                lSectionCount;
        long int                lSectionSize;
        long int                lFirstSection;
        long int                lPreviousProtection;
        long int                lJumpSize;
    
        bool                    bReturnValue;
    
        LPVOID                    lpImageMemory;
        LPVOID                    lpImageMemoryDummy;
    
        IMAGE_DOS_HEADER        dsDosHeader;
        IMAGE_NT_HEADERS        ntNtHeader;
        IMAGE_SECTION_HEADER    shSections[512 * 2];
    
        PROCESS_INFORMATION        piProcessInformation;
        STARTUPINFO                suStartUpInformation;
    
        CONTEXT                    cContext;
    
        // Variables for Local Process
        FILE*                    fFile;
        char*                    pProcessName;
    
        long int                lFileSize;
        long int                lLocalImageBase;
        long int                lLocalImageSize;
    
        LPVOID                    lpLocalFile;
    
        IMAGE_DOS_HEADER        dsLocalDosHeader;
        IMAGE_NT_HEADERS        ntLocalNtHeader;
    
        /////////////////////////////////////////////////////////////////
        // End Variable Definition
    
        bReturnValue = false;
    
        pProcessName = new char[MAX_PATH];
        ZeroMemory(pProcessName,MAX_PATH);
    
        // Get the file name for the dummy process
        if(GetModuleFileName(NULL,pProcessName,MAX_PATH) == 0)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        // Open the dummy process in binary mode
        fFile = fopen(pProcessName,"rb");
        if(!fFile)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        fseek(fFile,0,SEEK_END);
    
        // Get file size
        lFileSize = ftell(fFile);
    
        rewind(fFile);
    
        // Allocate memory for dummy file
        lpLocalFile = new LPVOID[lFileSize];
        ZeroMemory(lpLocalFile,lFileSize);
    
        // Read memory of file
        fread(lpLocalFile,lFileSize,1,fFile);
    
        // Close file
        fclose(fFile);
    
        // Grab the DOS Headers
        memcpy(&dsLocalDosHeader,lpLocalFile,sizeof(dsLocalDosHeader));
    
        if(dsLocalDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
        {
            delete [] pProcessName;
            delete [] lpLocalFile;
            return bReturnValue;
        }
    
        // Grab NT Headers
        memcpy(&ntLocalNtHeader,(LPVOID)((long int)lpLocalFile+dsLocalDosHeader.e_lfanew),sizeof(dsLocalDosHeader));
    
        if(ntLocalNtHeader.Signature != IMAGE_NT_SIGNATURE)
        {
            delete [] pProcessName;
            delete [] lpLocalFile;
            return bReturnValue;
        }
    
        // Get Size and Image Base
        lLocalImageBase = ntLocalNtHeader.OptionalHeader.ImageBase;
        lLocalImageSize = ntLocalNtHeader.OptionalHeader.SizeOfImage;
    
        // Deallocate
        delete [] lpLocalFile;
    
        // Grab DOS Header for Forking Process
        memcpy(&dsDosHeader,lpImage,sizeof(dsDosHeader));
    
        if(dsDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        // Grab NT Header for Forking Process
        memcpy(&ntNtHeader,(LPVOID)((long int)lpImage+dsDosHeader.e_lfanew),sizeof(ntNtHeader));
    
        if(ntNtHeader.Signature != IMAGE_NT_SIGNATURE)
        {
            delete [] pProcessName;
            return bReturnValue;
        }
    
        // Get proper sizes
        lImageSize = ntNtHeader.OptionalHeader.SizeOfImage;
        lHeaderSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
    
        // Allocate memory for image
        lpImageMemory = new LPVOID[lImageSize];
        ZeroMemory(lpImageMemory,lImageSize);
    
        lpImageMemoryDummy = lpImageMemory;
    
        lFirstSection = (long int)(((long int)lpImage+dsDosHeader.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
    
        memcpy(shSections,(LPVOID)(lFirstSection),sizeof(IMAGE_SECTION_HEADER)*ntNtHeader.FileHeader.NumberOfSections);
        memcpy(lpImageMemoryDummy,lpImage,lHeaderSize);
    
        // Get Section Alignment
        if((ntNtHeader.OptionalHeader.SizeOfHeaders % ntNtHeader.OptionalHeader.SectionAlignment) == 0)
        {
            lJumpSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
        }
        else
        {
            lJumpSize  = (ntNtHeader.OptionalHeader.SizeOfHeaders/ntNtHeader.OptionalHeader.SectionAlignment);
            lJumpSize += 1;
            lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
        }
    
        lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
    
        // Copy Sections To Buffer
        for(lSectionCount = 0; lSectionCount < ntNtHeader.FileHeader.NumberOfSections; lSectionCount++)
        {
            lJumpSize = 0;
            lSectionSize = shSections[lSectionCount].SizeOfRawData;
    
            memcpy(lpImageMemoryDummy,(LPVOID)((long int)lpImage + shSections[lSectionCount].PointerToRawData),lSectionSize);
    
            if((shSections[lSectionCount].Misc.VirtualSize % ntNtHeader.OptionalHeader.SectionAlignment)==0)
            {
                lJumpSize = shSections[lSectionCount].Misc.VirtualSize;
            }
            else
            {
                lJumpSize  = (shSections[lSectionCount].Misc.VirtualSize/ntNtHeader.OptionalHeader.SectionAlignment);
                lJumpSize += 1;
                lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
            }
    
            lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
        }
    
        ZeroMemory(&suStartUpInformation,sizeof(STARTUPINFO));
        ZeroMemory(&piProcessInformation,sizeof(PROCESS_INFORMATION));
        ZeroMemory(&cContext,sizeof(CONTEXT));
    
        suStartUpInformation.cb = sizeof(suStartUpInformation);
    
        // Create Process
        if(CreateProcess(NULL,pProcessName,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&suStartUpInformation,&piProcessInformation))
        {
            cContext.ContextFlags = CONTEXT_FULL;
            GetThreadContext(piProcessInformation.hThread,&cContext);
    
            // Check image base and image size
            if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
            {
                VirtualProtectEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,PAGE_EXECUTE_READWRITE,(unsigned long*)&lPreviousProtection);
            }
            else
            {
                if(!NtUnmapViewOfSection(piProcessInformation.hProcess,(LPVOID)((DWORD)lLocalImageBase)))
                    VirtualAllocEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
            }
    
            // Write Image to Process
            if(WriteProcessMemory(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lpImageMemory,lImageSize,(unsigned long*)&lWritten))
            {
                bReturnValue = true;
            }
    
            // Set Image Base
            if(WriteProcessMemory(piProcessInformation.hProcess,(LPVOID)((long int)cContext.Ebx + 8),&ntNtHeader.OptionalHeader.ImageBase,4,(unsigned long*)&lWritten))
            {
                if(bReturnValue == true)
                    bReturnValue = true;
            }
    
            if(bReturnValue == false)
            {
                delete [] pProcessName;
                delete [] lpImageMemory;
                return bReturnValue;
            }
    
            // Set the new entry point
            cContext.Eax = ntNtHeader.OptionalHeader.ImageBase + ntNtHeader.OptionalHeader.AddressOfEntryPoint;
    
            SetThreadContext(piProcessInformation.hThread,&cContext);
    
            if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
                VirtualProtectEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,lPreviousProtection,0);
    
            // Resume the process
            ResumeThread(piProcessInformation.hThread);
        }
    
        delete [] pProcessName;
        delete [] lpImageMemory;
    
        return bReturnValue;    
    }
    
    /////////////////////////////////////////////////////////////
    // Fork Process From Resource
    // Dynamically create a process from a resource file.
    bool ForkProcessFromResource(int iResource,char* pResourceSection)
    {
        HGLOBAL        hResData;
        HRSRC        hResInfo;
    
        LPVOID        lpRes;
        LPVOID        lpMemory;
        long int    lSize;
    
        HMODULE        hModule;
    
        bool bReturn;
    
        hModule = GetModuleHandle(0);
        bReturn = false;
    
        if(!hModule)
            return bReturn;
    
        hResInfo = FindResource(hModule, MAKEINTRESOURCE(iResource), pResourceSection);
        if(!hResInfo)
        {
            return bReturn;
        }
    
        hResData = LoadResource(hModule, hResInfo);
        if(!hResData)
        {
            return bReturn;
        }
    
        lpRes = LockResource(hResData);
        if(!lpRes)
        {
            FreeResource(hResData);
            return bReturn;
        }
    
        lSize = SizeofResource(hModule, hResInfo);
    
        lpMemory = new LPVOID[lSize];
        ZeroMemory(lpMemory,lSize);
    
        memcpy (lpMemory, lpRes, lSize);
    
        bReturn = ForkProcess(lpMemory);
    
        FreeResource(hResData);
        delete [] lpMemory;
    
        return bReturn;
    }
    


  • puh ganz schön viel code. warum greift der den nicht auf die datei zu?
    schließlich übergibst du ihm ja einen (eigenen) dateipfad?



  • helferlein schrieb:

    warum greift der den nicht auf die datei zu? schließlich übergibst du ihm ja einen (eigenen) dateipfad?

    Grob gesagt erzeugt das Snippet "irgendeinen" Prozess und brezelt dann seine "RAM-EXE" rein.



  • wird bei diesem "irgenteinem" prozess nicht aber auf die platte zurückgegriffen?



  • Ja, wird auch. Ist gewissermaßen "Hijacking". Insofern ist es nicht grade im Sinne des OT.



  • wo wird da eine exe von der HD geladen ?
    oder hab ich da was nicht gesehen?



  • zweiter parameter von CreateProcess....



  • heutemalwasanderes schrieb:

    wo wird da eine exe von der HD geladen ?

    Er lädt sich selbst als "dummy process" ("irgendeiner" geht auch):

    if(GetModuleFileName(NULL,pProcessName,MAX_PATH) == 0) ...
    
    (...)
    
    // Zugriff! -> verloren,verloren,hihihi :)
    if(CreateProcess(NULL,pProcessName,NULL,NULL,false,CREATE_SUSPENDED, ...
    


  • Da findet man wie man.bis win 10 rams in echtzeit lesen kann


Anmelden zum Antworten