is there a possibility to load an executable from RAM instead of from a
file? What I want to do is: the EXE is loaded into memory by my
application, the import table is patched, then the Windows loader
becomes active and creates a new process.
CU Christian
--
Christian Zietz - CHZ-Soft - czi...@gmx.net
WWW: http://chzsoft.home.pages.de/ - Fido: Christian Zietz@2:2437/80.14
PGP-Key auf Anfrage oder ueber http://wwwkeys.de.pgp.net (Port 11371)
This gets asked every so often. Many people believe
it is probably not too difficult, but admit they
haven't actually done it. I think it's probably
rather difficult, but I haven't tried it either.
Here's a link on Deja.com to the last thread I recall
on the subject. Note that in some of the discussions,
ideas were brought forward that don't apply to
executing exclusively from memory, with no
file on disk.
http://x39.deja.com/[ST_rn=ps]/viewthread.xp?AN=
570823732&search=thread&svcclass=dnyr&ST=
PS&CONTEXT=950977247.173277195&HIT_CONTEXT=
950977247.173277195&HIT_NUM=4&recnum=%3choqe4
.152$lz....@newsfeed.slurp.net%3e%231/1&group=
comp.os.ms-windows.programmer.win32&frpage=
getdoc.xp&back=clarinet
Long link, isn't it ;>
As Ron already explain, this is far more dificult hat it looks like, and
probably involves some pretty good knowledge of the undocumented loader
interfaces in ntdll.dll (starting with the Ldr*() prefix).
However, from your description of your problem, it seems you don´t actually
need all this. Wouldn´t it be enough to create the process directly from
disk, suspended, and then patch up the import table directly once the
process has been created before resuming it?
--
Tomas Restrepo
http://members.xoom.com/trestrep
> is there a possibility to load an executable from RAM instead of from a
> file? What I want to do is: the EXE is loaded into memory by my
> application, the import table is patched, then the Windows loader
> becomes active and creates a new process.
As Tomas pointed out, depending on exactly what you want to do, it might not
be necessary to create a new process from an in-memory image. If you really
do need to create a process from an in-memory image on NT then you might try
the following, which assumes that the in-memory image originates from a
binary resource bound to the executable.
Gary
#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
namespace NT {
extern "C" {
#pragma warning(disable: 4005) // macro redefinition
#include <ntddk.h>
#pragma warning(default: 4005)
}
}
using NT::NTSTATUS;
typedef struct _DEBUG_CONTROL {
ULONG L0 : 1;
ULONG G0 : 1;
ULONG L1 : 1;
ULONG G1 : 1;
ULONG L2 : 1;
ULONG G2 : 1;
ULONG L3 : 1;
ULONG G3 : 1;
ULONG LE : 1;
ULONG GE : 1;
ULONG : 3;
ULONG GD : 1;
ULONG : 2;
ULONG RWE0 : 2;
ULONG LEN0 : 2;
ULONG RWE1 : 2;
ULONG LEN1 : 2;
ULONG RWE2 : 2;
ULONG LEN2 : 2;
ULONG RWE3 : 2;
ULONG LEN3 : 2;
} DEBUG_CONTROL, *PDEBUG_CONTROL;
VOID preppatch()
{
CONTEXT context = {CONTEXT_DEBUG_REGISTERS};
PDEBUG_CONTROL dr7 = PDEBUG_CONTROL(&context.Dr7);
context.Dr0 = ULONG(GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwCreateThread"));
dr7->L0 = 1, dr7->RWE0 = 0, dr7->LEN0 = 0;
SetThreadContext(GetCurrentThread(), &context);
}
LONG patch(PEXCEPTION_POINTERS ep)
{
if (ep->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {
HANDLE hProcess = PHANDLE(ep->ContextRecord->Esp)[4];
PCONTEXT context = ((PCONTEXT*)(ep->ContextRecord->Esp))[6];
NT::PROCESS_BASIC_INFORMATION pbi;
NT::NtQueryInformationProcess(hProcess, NT::ProcessBasicInformation, &pbi, sizeof pbi, 0);
PVOID x; ReadProcessMemory(hProcess, PCHAR(pbi.PebBaseAddress) + 8, &x, sizeof x, 0);
NT::ZwUnmapViewOfSection(hProcess, x);
HRSRC hRsrc = FindResource(0, "Image", "EXE");
HGLOBAL hGlobal = LoadResource(0, hRsrc);
PVOID p = LockResource(hGlobal);
PIMAGE_NT_HEADERS nt = PIMAGE_NT_HEADERS(PCHAR(p) + PIMAGE_DOS_HEADER(p)->e_lfanew);
PVOID q = VirtualAllocEx(hProcess,
PVOID(nt->OptionalHeader.ImageBase),
nt->OptionalHeader.SizeOfImage,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, PCHAR(q), PCHAR(p), 0x1000, 0);
PIMAGE_SECTION_HEADER sect = IMAGE_FIRST_SECTION(nt);
for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++)
WriteProcessMemory(hProcess,
PCHAR(q) + sect[i].VirtualAddress,
PCHAR(p) + sect[i].PointerToRawData,
sect[i].SizeOfRawData, 0);
WriteProcessMemory(hProcess, PCHAR(pbi.PebBaseAddress) + 8, &q, sizeof q, 0);
context->Eax = ULONG(q) + nt->OptionalHeader.AddressOfEntryPoint;
ep->ContextRecord->Dr7 = 0;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
int main(int argc, char *argv[])
{
PROCESS_INFORMATION pi;
STARTUPINFO si = {sizeof si};
__try {
preppatch();
CreateProcess(0, "Explorer", 0, 0, FALSE, 0, 0, 0, &si, &pi);
}
__except (patch(GetExceptionInformation())) {}
return 0;
}
You´re always posting such useful and insightful code! Have you considered
putting it on a website altogether? It would sure be useful...
Tomas Restrepo schrieb:
> However, from your description of your problem, it seems you don´t actually
> need all this. Wouldn´t it be enough to create the process directly from
> disk, suspended, and then patch up the import table directly once the
> process has been created before resuming it?
Thank you for your answer.
As far as I know, the loader uses the import table when calling
createprocess (even suspended), so that I won't get an unchanged import
table to patch. But I'll try that.