使用CreateProcess运行资源

时间:2014-03-25 12:13:40

标签: c++ winapi createprocess

我有一个PE exe作为另一个exe的资源。 如果我提取并写入文件资源,它运行正常。 如果我尝试使用CreateProcess运行,我会收到错误(无法运行应用程序)

这是我的创建过程代码:

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);
}

任何想法?

1 个答案:

答案 0 :(得分:0)

这被称为RunPE,您将一个挂起的进程启动,然后将可执行文件映射到其内存中,将EIP设置为入口点,然后继续该进程。

执行此操作的最佳代码来自hasherezade,可在她的github上找到