简体   繁体   English

Windows 7上的内存缓冲区中的CreateProcess()无效

[英]CreateProcess() From Memory Buffer Doesn't Work On Windows 7

I was searching for awhile for how to read an exe into memory and execute it directly from memory. 我一直在寻找如何将exe读取到内存中并直接从内存中执行它。 Then I've passed by this answer which was very useful CreateProcess from memory buffer . 然后,我通过了这个答案,它对内存缓冲区非常有用。

Fortunately I've found some code implementing the mentioned idea. 幸运的是,我已经找到一些实现上述想法的代码。 After some tweaking I got it to work. 经过一些调整后,我开始工作了。

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

void RunFromMemory(unsigned char* pImage,char* pPath)
{
    DWORD dwWritten = 0;
    DWORD dwHeader = 0; 
    DWORD dwImageSize = 0;
    DWORD dwSectionCount = 0;
    DWORD dwSectionSize = 0;
    DWORD firstSection = 0;
    DWORD previousProtection = 0;
    DWORD jmpSize = 0;

    IMAGE_NT_HEADERS INH;
    IMAGE_DOS_HEADER IDH;
    IMAGE_SECTION_HEADER Sections[1000];

    PROCESS_INFORMATION peProcessInformation;
    STARTUPINFO peStartUpInformation;
    CONTEXT pContext;
    SECURITY_ATTRIBUTES secAttrib;

    char* pMemory;
    char* pFile;
    memcpy(&IDH,pImage,sizeof(IDH));
    memcpy(&INH,(void*)((DWORD)pImage+IDH.e_lfanew),sizeof(INH));

    dwImageSize = INH.OptionalHeader.SizeOfImage;
    pMemory = (char*)malloc(dwImageSize);
    memset(pMemory,0,dwImageSize);
    pFile = pMemory;

    dwHeader = INH.OptionalHeader.SizeOfHeaders;
    firstSection = (DWORD)(((DWORD)pImage+IDH.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
    memcpy(Sections,(char*)(firstSection),sizeof(IMAGE_SECTION_HEADER)*INH.FileHeader.NumberOfSections);

    memcpy(pFile,pImage,dwHeader);

    if((INH.OptionalHeader.SizeOfHeaders % INH.OptionalHeader.SectionAlignment)==0)
    {
        jmpSize = INH.OptionalHeader.SizeOfHeaders;
    }
    else
    {
        jmpSize = INH.OptionalHeader.SizeOfHeaders / INH.OptionalHeader.SectionAlignment;
        jmpSize += 1;
        jmpSize *= INH.OptionalHeader.SectionAlignment;
    }

    pFile = (char*)((DWORD)pFile + jmpSize);

    for(dwSectionCount = 0; dwSectionCount < INH.FileHeader.NumberOfSections; dwSectionCount++)
    {
        jmpSize = 0;
        dwSectionSize = Sections[dwSectionCount].SizeOfRawData;
        memcpy(pFile,(char*)(pImage + Sections[dwSectionCount].PointerToRawData),dwSectionSize);

        if((Sections[dwSectionCount].Misc.VirtualSize % INH.OptionalHeader.SectionAlignment)==0)
        {
            jmpSize = Sections[dwSectionCount].Misc.VirtualSize;
        }
        else
        {
            jmpSize = Sections[dwSectionCount].Misc.VirtualSize / INH.OptionalHeader.SectionAlignment;
            jmpSize += 1;
            jmpSize *= INH.OptionalHeader.SectionAlignment;
        }
        pFile = (char*)((DWORD)pFile + jmpSize);
    }


    memset(&peStartUpInformation,0,sizeof(STARTUPINFO));
    memset(&peProcessInformation,0,sizeof(PROCESS_INFORMATION));
    memset(&pContext,0,sizeof(CONTEXT));

    peStartUpInformation.cb = sizeof(peStartUpInformation);
    if(CreateProcess(NULL,pPath,NULL,NULL,false,CREATE_SUSPENDED, NULL,NULL,&peStartUpInformation,&peProcessInformation))
    {

        pContext.ContextFlags = CONTEXT_FULL;
        GetThreadContext(peProcessInformation.hThread,&pContext);
        VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,PAGE_EXECUTE_READWRITE,&previousProtection);
        WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),pMemory,dwImageSize,&dwWritten);
        WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)pContext.Ebx + 8),&INH.OptionalHeader.ImageBase,4,&dwWritten);
        pContext.Eax = INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint;
        SetThreadContext(peProcessInformation.hThread,&pContext);
        VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,previousProtection,0);
        ResumeThread(peProcessInformation.hThread);

    }
    else{
        // for debugging
        DWORD er = GetLastError();
        DWORD x = er;
    }
    free(pMemory);
}

int main()
{
    //*********** open file to encrypt ************
    char exe_path[] = "C:\\prog.exe";
    FILE *inFile = fopen(exe_path, "rb");
    fseek(inFile , 0 , SEEK_END);
    unsigned long dwSize = ftell(inFile);
    rewind(inFile);
    unsigned char *lpMemory = (unsigned char*) malloc (sizeof(unsigned char)*dwSize);
    fread(lpMemory,1,dwSize,inFile);
    fclose (inFile);
    //**********************************************


    //********* execute ***********
    RunFromMemory(lpMemory,exe_path);


    return 0;
}

I put a sample program called prog.exe into my C drive and this code reads it into memory and executes it. 我将一个名为prog.exe的示例程序放入我的C驱动器中,此代码将其读入内存并执行它。 This code works perfectly on Windows XP but I can't get it to work on Windows 7 as it launches this error message. 该代码在Windows XP上可以完美运行,但是由于启动此错误消息,因此我无法在Windows 7上运行。

The application was unable to start correctly (0xc000000c). Click OK to close the application.

I don't get what the reason may be for it to work correctly on Windows XP but not on Windows 7. Did Windows 7 apply some changes to PE format or headers or something ?? 我不知道是什么原因可能导致它无法在Windows XP上正常运行,但不能在Windows 7上正常运行。Windows 7是否对PE格式或标题应用了某些更改?

Thanks in advance. 提前致谢。 And If anyone would like to test it, don't forget to put your sample exe as C:\\prog.exe or change the path in the code as you like. 而且,如果有人想对其进行测试,请不要忘记将示例exe放在C:\\prog.exe或根据需要更改代码中的路径。

This is a major hack, and you should really avoid doing it. 这是一个主要的技巧,您应该避免这样做。 If you want to start a new process then the only guaranteed way to make it work without issue is to launch an executable that resides in the filesystem. 如果您要启动一个新进程,那么保证其正常运行的唯一保证方法是启动驻留在文件系统中的可执行文件。 Anything else is a hack and you can't rely on it working in the future. 其他任何事情都是骇客,您将来不能依靠它来工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM