问题描述
免责声明:我仅出于教育目的和在自己的计算机上使用RunPE。
首先:大家好! 我正在尝试使用具有.NET依赖关系(以C#语言编写)的文件来使用RunPE。
首先,使用本机c ++文件而不是.NET文件时,代码不会显示任何问题:
但是,每当我尝试使用以C#或.NET依赖性编码的文件时,就会发生这种情况:
我做了一些挖掘,然后在另一个StackOverflow线程上发现了这个(RunPE c++ only works with 32 console):
1.gui应用程序仅在其他GUI应用程序的内存上运行,而GUI应用程序仅在其他cui应用程序的内存上运行。 因为新窗口上的cui应用程序由conhost运行而不是直接运行。
2。要从C ++中的内存中运行.net应用程序,您必须修复导入表和其他内容。要从.net运行.net应用程序只需
答案本身不是很好,但是它可以说明问题所在:导入表需要重建,我们需要在另一个GUI应用程序中运行该应用程序,而不是像我正在使用的控制台。
我不知道如何在C ++中重建导入表,也不知道另一个“东西”是什么。
任何人都有一些有用的文档,或者知道如何在C ++中重建导入表?
在这里,我将代码留待进一步分析:
#include <fstream>
#include <Windows.h>
#define STUB_SIZE 114176
bool LoadDataIntoProcess(void* Image)
{
DWORD DataRead = 0;
DWORD DataWritten = 0;
PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)Image;
if (pIDH->e_magic != IMAGE_DOS_SIGNATURE)
{
std::cout << "Il file non è in un formato eseguibile.\n";
return 0;
}
PIMAGE_NT_HEADERS pINH = (PIMAGE_NT_HEADERS)((DWORD)Image + pIDH->e_lfanew);
if (pINH->Signature != IMAGE_NT_SIGNATURE)
{
std::cout << "Il file non è in un formato eseguibile.\n";
return 0;
}
PIMAGE_SECTION_HEADER pISH = IMAGE_FIRST_SECTION(pINH);
STARTUPINFOA si;
PROCESS_INFORMATION pi;
DWORD ImageBase;
void* pImageBase;
char CurrentPath[1024];
std::cout << "Prendo nome del modulo...\n";
GetModuleFileNameA(NULL,CurrentPath,1024);
ZeroMemory(&pi,sizeof(pi));
ZeroMemory(&si,sizeof(si));
std::cout << "Creo processo...\n";
if (CreateProcessA(CurrentPath,FALSE,CREATE_SUSPENDED,&si,&pi))
{
LPCONTEXT ctx = (LPCONTEXT)VirtualAlloc(NULL,sizeof(ctx),MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
ctx->ContextFlags = CONTEXT_FULL;
std::cout << "Prendo contesto del thread...\n";
if (GetThreadContext(pi.hThread,ctx))
{
std::cout << "Inizializzo puntatore alla base dell'eseguibile...\n";
bool Read = ReadProcessMemory(pi.hProcess,(LPCVOID)(ctx->Ebx + 8),(LPVOID)&ImageBase,4,&DataRead);
if (!Read)
{
std::cout << "Errore durante la lettura della memoria del processo.\n";
return 0;
}
else
{
std::cout << "Letti " << DataRead << " bytes dal processo.\n";
DataRead = 0;
}
pImageBase = VirtualAllocEx(pi.hProcess,(LPVOID)pINH->OptionalHeader.ImageBase,pINH->OptionalHeader.SizeOfImage,PAGE_EXECUTE_READWRITE);
bool Write = WriteProcessMemory(pi.hProcess,pImageBase,Image,pINH->OptionalHeader.SizeOfHeaders,&DataWritten);
if (!Write)
{
std::cout << "Errore: Impossibile scrivere all'interno del processo.\n";
return 0;
}
else
{
std::cout << "Scritti " << DataWritten << " all'interno del processo.\n";
DataWritten = 0;
}
std::cout << "SizeOfHeaders: " << pINH->OptionalHeader.SizeOfHeaders << ".\n";
for (int i = 0; i < pINH->FileHeader.NumberOfSections; i++)
{
std::cout << "Sezione " << i + 1 << " di " << pINH->FileHeader.NumberOfSections << ".\n";
Write = WriteProcessMemory(pi.hProcess,(LPVOID)((DWORD)pImageBase + pISH[i].VirtualAddress),(LPVOID)((DWORD)Image + pISH[i].PointerToRawData),pISH[i].SizeOfRawData,0);
if (!Write)
{
std::cout << "Errore: Impossibile scrivere all'interno del processo.\n";
return 0;
}
std::cout << "\tVA: 0x" << pISH[i].VirtualAddress << "\n\tPointerToRawData: 0x" << pISH[i].PointerToRawData << "\n\t SizeOfRawData: " << pISH[i].SizeOfRawData << ".\n";
}
std::cout << "Scrivo ImageBase dentro al processo...\n";
Write = WriteProcessMemory(pi.hProcess,(LPVOID)(ctx->Ebx + 8),(LPVOID)&pINH->OptionalHeader.ImageBase,0);
if (!Write)
{
std::cout << "Errore: Impossibile scrivere all'interno del processo.\n";
return 0;
}
std::cout << "Imposto entrypoint...\n";
ctx->Eax = (DWORD)pImageBase + pINH->OptionalHeader.AddressOfEntryPoint;
std::cout << "Riassumo il thread...\n";
bool STC = SetThreadContext(pi.hThread,ctx);
if (!STC)
{
std::cout << "Errore: Impossibile impostare il context del processo.\n";
return 0;
}
ResumeThread(pi.hThread);
std::cout << "Avvio completato.\n";
return 1;
}
else
{
std::cout << "Errore: Impossibile prendere contesto del thread.\n";
return 0;
}
}
else
{
std::cout << "Errore: Impossibile creare il processo.\n";
return 0;
}
}```
解决方法
编译器设置/ cls修复了所有问题,当使用.NET二进制文件尝试RunPE时,这一点很重要。