How to execute a Byte Array in C++

2020-07-28 11:31发布

Let's say I have a encrypted program, I open it with a decrypter, which loads the bytes into a array and decrypts it.

What I want to know is how it would be possible to execute those bytes without having to create another executable.

I read that it is possible using 'Forking', and that is the best way to do so. However I cannot successfully run my code, and it does not return any errors. Here's a sample of what I got :

    //<main>
    char* lpMemory;
    lpMemory = (char*)malloc (fileSize);
    memset(lpMemory,0,fileSize);
    memcpy (lpMemory, fileBuf, fileSize);
    RunFromMemory(lpMemory, /* What here? */);

    //</main>

void RunFromMemory(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;

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 /*&secAttrib*/, 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);
}
free(pMemory);
}

As you might have guessed, 'fileSize' is the size of the program and 'fileBuf' is the Byte array. I am sure that both of those values are correct.

Any links to resources that may help me is appreciated Thank you very much.

标签: c++
2条回答
2楼-- · 2020-07-28 11:40

Depending on what the bytes in the array actually represent, you might be able to just type-cast the array pointer into a function pointer and then call the "function" like any other. For that to work, the array would have to reside in executable memory (see VirtualProtect()) and contain just the byte representation of assembly instructions and nothing else.

查看更多
Animai°情兽
3楼-- · 2020-07-28 11:56

Yes it is possible: the easiest way to do it just to cast the pointer of your byte array to a function pointer and after call it. The second way is to use the inline assembler and perform a jmp to your byte array's address. Probably a heap or stack where your array is allocated will not be executable then you need to use the VirtualProtect and related api (for win32 ).

查看更多
登录 后发表回答