RunPE内存故障



每当执行我的可执行文件时,它80%的时间都能工作。另外20%的时间,我收到来自Windows的0xc00000005错误。我相信这可能是内存问题,但我不确定如何解决。我花了太多时间想办法解决这个问题,所以我现在来这里。我正在使用Visual Studio。

我调试了这个程序,它在名为"写入进程内存步骤1:失败"的调试脚本中失败了

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

RunPE功能:

/*             PE Execution Function               */
int RunPortableExecutable(void* Image)
{
IMAGE_DOS_HEADER* DOSHeader;
IMAGE_NT_HEADERS* NtHeader;
IMAGE_SECTION_HEADER* SectionHeader;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
DWORD* ImageBase;
void* pImageBase;
int count;
char CurrentFilePath[1024];
DOSHeader = PIMAGE_DOS_HEADER(Image);
NtHeader = PIMAGE_NT_HEADERS(DWORD(Image) + DOSHeader->e_lfanew);
GetModuleFileNameA(0, CurrentFilePath, 1024);
if (NtHeader->Signature == IMAGE_NT_SIGNATURE)
{
ZeroMemory(&PI, sizeof(PI));
ZeroMemory(&SI, sizeof(SI));
if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
{
LPCONTEXT CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL;
if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
{
if (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);
if (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));
if (WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress),
LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0))
{
cout << "Write process memory in FOR statement. Success";
}
else cout << "Write process memory in FOR statement. Failed";
}
if (WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8),
LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0))
{
CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
if (SetThreadContext(PI.hThread, LPCONTEXT(CTX)))
{
if (ResumeThread(PI.hThread))
{
cout << "Resume thread: Success";
}
else cout << "Resume thread: Failed";
}
else cout << "Set thread context: Failed";
}
else cout << "Write process memory step 2: Failed";
}
else cout << "Write process memory step 1: Failed";
}
else cout << "Read process memory: Failed";
}
else cout << "Get thread context: Failed";
}
else cout << "Create process: Failed";
}
else cout << "Get module file name: Failed";
return 0;
}

警告信息:

严重性代码描述项目文件行抑制状态
警告C6011取消引用NULL指针'CTX'
39号线

严重性代码描述项目文件行禁止显示状态
警告C6387"CTX"可能为"0":这不符合函数"GetThreadContext"的规范。请参阅第39行,了解可能发生这种情况的较早位置
第41行

严重性代码描述项目文件行禁止显示状态
警告C6387"pImageBase"可能为"0":这不符合函数"WriteProcessMemory"的规范
48号线

严重性代码描述项目文件行禁止显示状态
警告C6387"CTX"可能为"0":这不符合函数"SetThreadContext"的规范。请参阅第39行,了解可能发生这种情况的较早位置
第62行

您在计算NtHeader指针时出错,这会在尝试访问NtHeader->Signature时导致denied access。你的指针应该这样计算:

NtHeader = (PIMAGE_NT_HEADERS) ((u_char*)DOSHeader + DOSHeader->e_lfanew);

我通过在Linker/Advanced选项选项卡中将Randomized Base Address设置为No来解决问题。

然后我将NtUnmapViewofSection添加到我的代码中

*(DWORD_PTR*)&pNtUnmapViewOfSection = (DWORD_PTR)GetProcAddress(GetModuleHandleW(L"NTDLL.dll"), "NtUnmapViewOfSection");

最新更新