Note that there are some explanatory texts on larger screens.

plurals
  1. POC++ add PE file as resource and execute it from memory
    primarykey
    data
    text
    <p>I have the following program in C++ that adds an EXE file (PE) as resource and executes it from memory (no, is not malware related, I just use for a personal project a GPL exe file, so no license violation) but seems the PE file is not loaded as resource when I compile it from commandline as <code>cl /EHsc embed.cpp</code>. The full sourcecode is as follows:</p> <p>embed.cpp</p> <pre><code>#include &lt;windows.h&gt; #include &lt;iostream&gt; #include "resource.h" SECURITY_ATTRIBUTES secAttrib; using namespace std; void RunFromMemory(char*, char*); int main(int argc, char* argv[]) { HGLOBAL hResData; HRSRC hResInfo; void *pvRes; DWORD dwSize; char* lpMemory; HMODULE hModule = GetModuleHandle(NULL); if (((hResInfo = FindResource(hModule, MAKEINTRESOURCE(IDD_EXE1), RT_RCDATA)) != NULL) &amp;&amp; ((hResData = LoadResource(hModule, hResInfo)) != NULL) &amp;&amp; ((pvRes = LockResource(hResData)) != NULL)) { dwSize = SizeofResource(hModule, hResInfo); lpMemory = (char*)malloc (dwSize); memset(lpMemory,0,dwSize); memcpy (lpMemory, pvRes, dwSize); RunFromMemory(lpMemory,argv[0]); } } 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(&amp;IDH,pImage,sizeof(IDH)); memcpy(&amp;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 &lt; 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(&amp;peStartUpInformation,0,sizeof(STARTUPINFO)); memset(&amp;peProcessInformation,0,sizeof(PROCESS_INFORMATION)); memset(&amp;pContext,0,sizeof(CONTEXT)); peStartUpInformation.cb = sizeof(peStartUpInformation); if(CreateProcess(NULL,pPath,&amp;secAttrib,NULL,false,CREATE_SUSPENDED,NULL,NULL,&amp;peStartUpInformation,&amp;peProcessInformation)) { pContext.ContextFlags = CONTEXT_FULL; GetThreadContext(peProcessInformation.hThread,&amp;pContext); VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,PAGE_EXECUTE_READWRITE,&amp;previousProtection); WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),pMemory,dwImageSize,&amp;dwWritten); WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)pContext.Ebx + 8),&amp;INH.OptionalHeader.ImageBase,4,&amp;dwWritten); pContext.Eax = INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint; SetThreadContext(peProcessInformation.hThread,&amp;pContext); VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,previousProtection,0); ResumeThread(peProcessInformation.hThread); } free(pMemory); } </code></pre> <p>app.rc</p> <pre><code>IDD_EXE1 RCDATA "mm.txt" </code></pre> <p>resource.h</p> <pre><code>#define IDD_EXE1 1004 </code></pre> <p>the <code>mm.txt</code> is my EXE file.</p> <p>It compiles ok but I can't see the EXE added as resource. Any thoughts where I could be wrong?</p> <p>EDIT:</p> <p>As per Zevin Zenph Zambori's answer, "loaded" the exe as HEX and not resource, all works ok, the only problem my compiled console applications hangs at the end waiting for user input (carriage-return or smth...) any idea why doesn't terminate? Here is the code:</p> <pre><code>// compile under VC with: cl /EHsc embed.cpp #include &lt;windows.h&gt; #include &lt;iostream&gt; SECURITY_ATTRIBUTES secAttrib; using namespace std; void RunFromMemory(char*, char*); char _image_[] = { 0x4D,0x5A, .... ,0x00,0x00 }; int main(int argc, char* argv[]) { char current_file_path[1024]; GetModuleFileNameA(0, current_file_path, 1024); // Path to current executable. RunFromMemory(_image_, current_file_path); return 0; } 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(&amp;IDH,pImage,sizeof(IDH)); memcpy(&amp;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 &lt; 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(&amp;peStartUpInformation,0,sizeof(STARTUPINFO)); memset(&amp;peProcessInformation,0,sizeof(PROCESS_INFORMATION)); memset(&amp;pContext,0,sizeof(CONTEXT)); peStartUpInformation.cb = sizeof(peStartUpInformation); if(CreateProcess(NULL,pPath,&amp;secAttrib,NULL,false,CREATE_SUSPENDED,NULL,NULL,&amp;peStartUpInformation,&amp;peProcessInformation)) { pContext.ContextFlags = CONTEXT_FULL; GetThreadContext(peProcessInformation.hThread,&amp;pContext); VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,PAGE_EXECUTE_READWRITE,&amp;previousProtection); WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),pMemory,dwImageSize,&amp;dwWritten); WriteProcessMemory(peProcessInformation.hProcess,(void*)((DWORD)pContext.Ebx + 8),&amp;INH.OptionalHeader.ImageBase,4,&amp;dwWritten); pContext.Eax = INH.OptionalHeader.ImageBase + INH.OptionalHeader.AddressOfEntryPoint; SetThreadContext(peProcessInformation.hThread,&amp;pContext); VirtualProtectEx(peProcessInformation.hProcess,(void*)((DWORD)INH.OptionalHeader.ImageBase),dwImageSize,previousProtection,0); ResumeThread(peProcessInformation.hThread); } free(pMemory); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload