Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Load Executable from Memory

733 views
Skip to first unread message

Christian Zietz

unread,
Feb 19, 2000, 3:00:00 AM2/19/00
to
Hello,

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)

a f f l e s 2@worldnet.att.net Ron Ruble

unread,
Feb 19, 2000, 3:00:00 AM2/19/00
to

Christian Zietz wrote in message <38AEAC16...@gmx.net>...

>Hello,
>
>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.


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 ;>

Tomas Restrepo

unread,
Feb 20, 2000, 3:00:00 AM2/20/00
to
Christian,

> 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 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

Gary Nebbett

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
"Christian Zietz" <czi...@gmx.net> wrote in message news:38AEAC16...@gmx.net...

> 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;
}


Tomas Restrepo

unread,
Feb 21, 2000, 3:00:00 AM2/21/00
to
Gary,

> 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.

You´re always posting such useful and insightful code! Have you considered
putting it on a website altogether? It would sure be useful...

Christian Zietz

unread,
Feb 23, 2000, 3:00:00 AM2/23/00
to
Tomas,

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.

bsad...@gmail.com

unread,
Mar 27, 2018, 11:29:21 AM3/27/18
to
On Monday, February 21, 2000 at 3:00:00 PM UTC+7, Gary Nebbett wrote:
> "Christian Zietz" <czi...@gmx.net> wrote in message news:38AEAC16...@gmx.net...
>
> > 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.
>
Could you help me explain the process of this stuff in a narrative way, perhaps?
and i dont know what is _try and _except

Thank you!

bob sadino

unread,
Mar 27, 2018, 11:49:37 PM3/27/18
to
Plese help

I got compile error

C2061: syntax error : identifier 'NT'|

i'm new to c++
0 new messages