Createprocess from Memory Buffer

Does Windows supports running a program from memory?

Windows does not support running processes from memory, only from file. Running processes from memory is a hack that relies on undocumented implementation details which are subject to change. In other words, MS could perfectly well change the system design in a future OS release such that existing run from memory code stopped working.

CreateProcess and lpCommandLine lifetime

The buffer referred to by lpCommandLine needs be valid only for the duration of the call to CreateProcess. Once CreateProcess returns, it will not refer to that buffer again.

Imagine if you did have to keep that buffer alive. Were that the case, then all parent processes would have to outlive all of their children. That's clearly a ridiculous proposition and I'm sure you will know from experience that there is not such requirement.

There is a general principle here. By and large, API functions will not refer to their arguments after the function returns. If they do need to do so, then it will be explicitly called out in the documentation, or it will be blatantly obvious from the intent of the function. As an example of the latter I am thinking of passing a window procedure to RegisterClass. It is quite clear that the window procedure must remain valid for as long as there exists a window of that class.

Using FindResource with a memory buffer

I'm have a memory buffer which contains a valid file image

in which form ? i guess than in raw (as on disk). but you need 'mapped as image' memory for use FindResource. not hard map you raw image by self ( if you want only access resource, but not execute it from memory) example of code:

PVOID MapImage(PIMAGE_DOS_HEADER pvRawData, ULONG cbRawData)
{
if (cbRawData < sizeof(IMAGE_DOS_HEADER))
{
return 0;
}

if (pvRawData->e_magic != IMAGE_DOS_SIGNATURE)
{
return 0;
}

ULONG e_lfanew = pvRawData->e_lfanew, s = e_lfanew + sizeof(IMAGE_NT_HEADERS);

if (e_lfanew >= s || s > cbRawData)
{
return 0;
}

PIMAGE_NT_HEADERS pinth = (PIMAGE_NT_HEADERS)RtlOffsetToPointer(pvRawData, e_lfanew);

if (pinth->Signature != IMAGE_NT_SIGNATURE)
{
return 0;
}

ULONG SizeOfImage = pinth->OptionalHeader.SizeOfImage, SizeOfHeaders = pinth->OptionalHeader.SizeOfHeaders;

s = e_lfanew + SizeOfHeaders;

if (SizeOfHeaders > SizeOfImage || SizeOfHeaders >= s || s > cbRawData)
{
return 0;
}

s = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pinth->FileHeader.SizeOfOptionalHeader;

if (s > SizeOfHeaders)
{
return 0;
}

ULONG NumberOfSections = pinth->FileHeader.NumberOfSections;

PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)RtlOffsetToPointer(pinth, s);

ULONG Size;

if (NumberOfSections)
{
if (e_lfanew + s + NumberOfSections * sizeof(IMAGE_SECTION_HEADER) > SizeOfHeaders)
{
return 0;
}

do
{
if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData))
{
union {
ULONG VirtualAddress, PointerToRawData;
};

VirtualAddress = pish->VirtualAddress, s = VirtualAddress + Size;

if (VirtualAddress > s || s > SizeOfImage)
{
return 0;
}

PointerToRawData = pish->PointerToRawData, s = PointerToRawData + Size;

if (PointerToRawData > s || s > cbRawData)
{
return 0;
}
}

} while (pish++, --NumberOfSections);
}

PVOID ImageBase = VirtualAlloc(0, SizeOfImage, MEM_COMMIT, PAGE_READWRITE);

if (!ImageBase)
{
return 0;
}

memcpy(ImageBase, pvRawData, SizeOfHeaders);

if (NumberOfSections = pinth->FileHeader.NumberOfSections)
{
do
{
--pish;

if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData))
{
memcpy(RtlOffsetToPointer(ImageBase, pish->VirtualAddress),
RtlOffsetToPointer(pvRawData, pish->PointerToRawData), Size);
}

} while (--NumberOfSections);

}

return ImageBase;
}

void Test(PVOID pvRawData, ULONG cbRawData, PCWSTR lpType, PCWSTR lpName)
{
if (HMODULE ImageBase = (HMODULE)MapImage((PIMAGE_DOS_HEADER)pvRawData, cbRawData))
{
if (HRSRC hResInfo = FindResource(ImageBase, lpName, lpType))
{
if (HGLOBAL hg = LoadResource(ImageBase, hResInfo))
{
__nop();
}
}

VirtualFree(ImageBase, 0, MEM_RELEASE);
}
}

MapImage containing check for valid data sizes. however if you sure that (pvRawData, cbRawData) is 100% correct - you can skip this checks and simplify code

// i EDIT Test function based on @IInspectable comment - remove __try/__except - it not needed here



Related Topics



Leave a reply



Submit