0
votes

I've have a PE exe as resource of another exe. If i extract and write to file the resource, it run fine. If i try to run with CreateProcess i get an error (impossible to run application)

this is my code for create process :

void BBStub::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);

  cout << peStartUpInformation.cb << endl;
  //      if (CreateProcess(NULL, pPath, &secAttrib, NULL, false, CREATE_SUSPENDED, NULL, NULL, &peStartUpInformation, &peProcessInformation))
  try
  {

      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);
          ResumeThread(peProcessInformation.hThread);
      }
      else {
          DWORD dw = GetLastError();
          cout << "Error" << endl;
          cout << dw << endl;
      }
  }
  catch (exception e)
  {
      cout << e.what();
  }
  free(pMemory);
}

any idea?

1
What is the error? i.e. is CreateProcess() returning an error (which), or just nothing happens, or? - Ale
The application was unable to start correctly (0xc000000c) - Valentino
Just to test, try adding a call to GetStartupInfo(&peStartUpInformation); before your call to CreateProcess(). I remember I had very weird behaviours with a badly initialized PROCESS_INFORMATION structure (although at a first glance yours look fine...) - Ale
At what part of the code above does the error arise? And how do you resolve references to other libraries? - David Heffernan
You can't run a program "from memory" with CreateProcess. Create process want a path to an executable. - Jabberwocky

1 Answers

0
votes

This is referred to as RunPE, you start a process suspended and then map your executable into it's memory, set the EIP to the entry point and resume the process.

The best code for doing this is from hasherezade and is available on her github