Я взял известный пример запуска исполняемого файла pe из памяти. Но когда я пытаюсь запустить его, я получаю нарушение доступа к памяти в функции WriteProcessMemory ().
Я использую последнюю версию Visual Studio 2019 и Windows 10 x64 OS. В настройках Visual Studio я выбираю отладку и сборку x86. Приложение, которое я пытаюсь запустить (simpleMessageBox.exe), совпадает с отладкой x86. Вот моя полная программа:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <Windows.h> // WinAPI header
#include <TlHelp32.h> // WinAPI Process API
std::vector<uint8_t> getFileContents(const char* filePath)
{
std::vector<uint8_t> rawData;
std::ifstream stream(filePath, std::ios::in);
rawData = std::vector<uint8_t>(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
return rawData;
}
int RunPortableExecutable(void* Image)
{
IMAGE_DOS_HEADER* DOSHeader; // For NT DOS Header symbols
IMAGE_NT_HEADERS* NtHeader; // For Nt Header objects & symbols
IMAGE_SECTION_HEADER* SectionHeader;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
CONTEXT* CTX;
DWORD* ImageBase; // Base address of the image
void* pImageBase; // Point to the image base
int count;
char CurrentFilePath[1024];
DOSHeader = PIMAGE_DOS_HEADER(Image); // Initialize variable
NtHeader = (PIMAGE_NT_HEADERS)((char*)DOSHeader + DOSHeader->e_lfanew);
GetModuleFileNameA(0, CurrentFilePath, 1024); // Path to current executable
if (DOSHeader->e_magic == IMAGE_DOS_SIGNATURE) // Check if image is a PE file
{
ZeroMemory(&PI, sizeof(PI)); // Null the memory
ZeroMemory(&SI, sizeof(SI)); // Null the memory
if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) // Create a new instance of current
//process in suspended state, for the new image.
{
// Allocate memory for the context.
CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL; // Context is allocated
if (GetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread
{
// Read instructions
ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0);
pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase),
NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
// Write the image to the process
WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL);
for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
{
SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40));
WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress),
LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0);
}
WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0);
// Move address of entry point to the eax register
CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(PI.hThread, LPCONTEXT(CTX)); // Set the context
ResumeThread(PI.hThread); //´Start the process/call main()
return 0; // Operation was successful.
}
}
}
}
int main()
{
auto rawPEData = getFileContents("C:\\Users\\..\\simpleMessageBox.exe");
auto runError = RunPortableExecutable(&rawPEData[0]);
return runError;
}
Благодарю за любую помощь. Заранее спасибо.