|
|
sponsored advertisements
|
|
Dynamic Process Forking (Running a process from memory) |
29th December 2009, 06:28 PM
|
#1
|
Posting Well
Join Date: Dec 2009
Posts: 29
Reputation: 181
Rep Power: 349
|
Dynamic Process Forking (Running a process from memory)
Thought I'd share this old code with you guys. I originally posted it on GD, and now here.
It allows you to run a process from a resource or memory and not a file. This creates a separate process.
If you want to run a process from within the stub process instead of creating a new process, this can be achieved with something similar to this code. However, it takes a lot more work and a lot more things would need fixing for it to work 100%. But you could eventually use CreateThread() on the Entry point.
Code:
//--------------------------------------------------------
// Dynamic Process Forking of Portable Executable
//--------------------------------------------------------
/*********************************************************/
/* With this header, you can create and run a process */
/* from memory and not from a file. */
/*********************************************************/
#ifdef WIN32
#include <windows.h>
#else
#error Process Forking Requires a Windows Operating System
#endif
#include <stdio.h>
/////////////////////////////////////////////////////////////
// NtUnmapViewOfSection (ZwUnmapViewOfSection)
// Used to unmap a section from a process.
typedef long int (__stdcall* NtUnmapViewOfSectionF)(HANDLE,PVOID);
NtUnmapViewOfSectionF NtUnmapViewOfSection = (NtUnmapViewOfSectionF)GetProcAddress(LoadLibrary("ntdll.dll"),"NtUnmapViewOfSection");
/////////////////////////////////////////////////////////////
// Fork Process
// Dynamically create a process based on the parameter 'lpImage'. The parameter should have the entire
// image of a portable executable file from address 0 to the end.
bool ForkProcess(LPVOID lpImage)
{
// Variables for Process Forking
long int lWritten;
long int lHeaderSize;
long int lImageSize;
long int lSectionCount;
long int lSectionSize;
long int lFirstSection;
long int lPreviousProtection;
long int lJumpSize;
bool bReturnValue;
LPVOID lpImageMemory;
LPVOID lpImageMemoryDummy;
IMAGE_DOS_HEADER dsDosHeader;
IMAGE_NT_HEADERS ntNtHeader;
IMAGE_SECTION_HEADER shSections[512 * 2];
PROCESS_INFORMATION piProcessInformation;
STARTUPINFO suStartUpInformation;
CONTEXT cContext;
// Variables for Local Process
FILE* fFile;
char* pProcessName;
long int lFileSize;
long int lLocalImageBase;
long int lLocalImageSize;
LPVOID lpLocalFile;
IMAGE_DOS_HEADER dsLocalDosHeader;
IMAGE_NT_HEADERS ntLocalNtHeader;
/////////////////////////////////////////////////////////////////
// End Variable Definition
bReturnValue = false;
pProcessName = new char[MAX_PATH];
ZeroMemory(pProcessName,MAX_PATH);
// Get the file name for the dummy process
if(GetModuleFileName(NULL,pProcessName,MAX_PATH) == 0)
{
delete [] pProcessName;
return bReturnValue;
}
// Open the dummy process in binary mode
fFile = fopen(pProcessName,"rb");
if(!fFile)
{
delete [] pProcessName;
return bReturnValue;
}
fseek(fFile,0,SEEK_END);
// Get file size
lFileSize = ftell(fFile);
rewind(fFile);
// Allocate memory for dummy file
lpLocalFile = new LPVOID[lFileSize];
ZeroMemory(lpLocalFile,lFileSize);
// Read memory of file
fread(lpLocalFile,lFileSize,1,fFile);
// Close file
fclose(fFile);
// Grab the DOS Headers
memcpy(&dsLocalDosHeader,lpLocalFile,sizeof(dsLocalDosHeader));
if(dsLocalDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
{
delete [] pProcessName;
delete [] lpLocalFile;
return bReturnValue;
}
// Grab NT Headers
memcpy(&ntLocalNtHeader,(LPVOID)((long int)lpLocalFile+dsLocalDosHeader.e_lfanew),sizeof(dsLocalDosHeader));
if(ntLocalNtHeader.Signature != IMAGE_NT_SIGNATURE)
{
delete [] pProcessName;
delete [] lpLocalFile;
return bReturnValue;
}
// Get Size and Image Base
lLocalImageBase = ntLocalNtHeader.OptionalHeader.ImageBase;
lLocalImageSize = ntLocalNtHeader.OptionalHeader.SizeOfImage;
// Deallocate
delete [] lpLocalFile;
// Grab DOS Header for Forking Process
memcpy(&dsDosHeader,lpImage,sizeof(dsDosHeader));
if(dsDosHeader.e_magic != IMAGE_DOS_SIGNATURE)
{
delete [] pProcessName;
return bReturnValue;
}
// Grab NT Header for Forking Process
memcpy(&ntNtHeader,(LPVOID)((long int)lpImage+dsDosHeader.e_lfanew),sizeof(ntNtHeader));
if(ntNtHeader.Signature != IMAGE_NT_SIGNATURE)
{
delete [] pProcessName;
return bReturnValue;
}
// Get proper sizes
lImageSize = ntNtHeader.OptionalHeader.SizeOfImage;
lHeaderSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
// Allocate memory for image
lpImageMemory = new LPVOID[lImageSize];
ZeroMemory(lpImageMemory,lImageSize);
lpImageMemoryDummy = lpImageMemory;
lFirstSection = (long int)(((long int)lpImage+dsDosHeader.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
memcpy(shSections,(LPVOID)(lFirstSection),sizeof(IMAGE_SECTION_HEADER)*ntNtHeader.FileHeader.NumberOfSections);
memcpy(lpImageMemoryDummy,lpImage,lHeaderSize);
// Get Section Alignment
if((ntNtHeader.OptionalHeader.SizeOfHeaders % ntNtHeader.OptionalHeader.SectionAlignment) == 0)
{
lJumpSize = ntNtHeader.OptionalHeader.SizeOfHeaders;
}
else
{
lJumpSize = (ntNtHeader.OptionalHeader.SizeOfHeaders/ntNtHeader.OptionalHeader.SectionAlignment);
lJumpSize += 1;
lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
}
lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
// Copy Sections To Buffer
for(lSectionCount = 0; lSectionCount < ntNtHeader.FileHeader.NumberOfSections; lSectionCount++)
{
lJumpSize = 0;
lSectionSize = shSections[lSectionCount].SizeOfRawData;
memcpy(lpImageMemoryDummy,(LPVOID)((long int)lpImage + shSections[lSectionCount].PointerToRawData),lSectionSize);
if((shSections[lSectionCount].Misc.VirtualSize % ntNtHeader.OptionalHeader.SectionAlignment)==0)
{
lJumpSize = shSections[lSectionCount].Misc.VirtualSize;
}
else
{
lJumpSize = (shSections[lSectionCount].Misc.VirtualSize/ntNtHeader.OptionalHeader.SectionAlignment);
lJumpSize += 1;
lJumpSize *= (ntNtHeader.OptionalHeader.SectionAlignment);
}
lpImageMemoryDummy = (LPVOID)((long int)lpImageMemoryDummy + lJumpSize);
}
ZeroMemory(&suStartUpInformation,sizeof(STARTUPINFO));
ZeroMemory(&piProcessInformation,sizeof(PROCESS_INFORMATION));
ZeroMemory(&cContext,sizeof(CONTEXT));
suStartUpInformation.cb = sizeof(suStartUpInformation);
// Create Process
if(CreateProcess(NULL,pProcessName,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&suStartUpInformation,&piProcessInformation))
{
cContext.ContextFlags = CONTEXT_FULL;
GetThreadContext(piProcessInformation.hThread,&cContext);
// Check image base and image size
if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
{
VirtualProtectEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,PAGE_EXECUTE_READWRITE,(unsigned long*)&lPreviousProtection);
}
else
{
if(!NtUnmapViewOfSection(piProcessInformation.hProcess,(LPVOID)((DWORD)lLocalImageBase)))
VirtualAllocEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
}
// Write Image to Process
if(WriteProcessMemory(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lpImageMemory,lImageSize,(unsigned long*)&lWritten))
{
bReturnValue = true;
}
// Set Image Base
if(WriteProcessMemory(piProcessInformation.hProcess,(LPVOID)((long int)cContext.Ebx + 8),&ntNtHeader.OptionalHeader.ImageBase,4,(unsigned long*)&lWritten))
{
if(bReturnValue == true)
bReturnValue = true;
}
if(bReturnValue == false)
{
delete [] pProcessName;
delete [] lpImageMemory;
return bReturnValue;
}
// Set the new entry point
cContext.Eax = ntNtHeader.OptionalHeader.ImageBase + ntNtHeader.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(piProcessInformation.hThread,&cContext);
if(lLocalImageBase == (long int)ntNtHeader.OptionalHeader.ImageBase && lImageSize <= lLocalImageSize)
VirtualProtectEx(piProcessInformation.hProcess,(LPVOID)((long int)ntNtHeader.OptionalHeader.ImageBase),lImageSize,lPreviousProtection,0);
// Resume the process
ResumeThread(piProcessInformation.hThread);
}
delete [] pProcessName;
delete [] lpImageMemory;
return bReturnValue;
}
/////////////////////////////////////////////////////////////
// Fork Process From Resource
// Dynamically create a process from a resource file.
bool ForkProcessFromResource(int iResource,char* pResourceSection)
{
HGLOBAL hResData;
HRSRC hResInfo;
LPVOID lpRes;
LPVOID lpMemory;
long int lSize;
HMODULE hModule;
bool bReturn;
hModule = GetModuleHandle(0);
bReturn = false;
if(!hModule)
return bReturn;
hResInfo = FindResource(hModule, MAKEINTRESOURCE(iResource), pResourceSection);
if(!hResInfo)
{
return bReturn;
}
hResData = LoadResource(hModule, hResInfo);
if(!hResData)
{
return bReturn;
}
lpRes = LockResource(hResData);
if(!lpRes)
{
FreeResource(hResData);
return bReturn;
}
lSize = SizeofResource(hModule, hResInfo);
lpMemory = new LPVOID[lSize];
ZeroMemory(lpMemory,lSize);
memcpy (lpMemory, lpRes, lSize);
bReturn = ForkProcess(lpMemory);
FreeResource(hResData);
delete [] lpMemory;
return bReturn;
}
It would be used like this:
Code:
ForkProcess(pointer to executable memory);
or
ForkProcessFromResource(IDE_FILE1,"EXE"); (If you wanna load it from a resource)
This is a great routine you could use for extra protection. Like for example, you can have an encrypted process in your resources and decrypt in memory and use the ForkProcess to run it.
|
E.T. is offline
|
|
|
29th December 2009, 08:50 PM
|
#3
|
Posting Well
Join Date: Dec 2009
Posts: 28
Reputation: 157
Rep Power: 349
|
You 'ought to post your MKII project here, you'll get some decent CC
Quote:
Originally Posted by Krtek
C-style programming rules.
+rep
|
Imagine how clean this could be as a process class, though, with fork just being a function you can call for managing the process.
Also:
Code:
lFirstSection = (long int)(((long int)lpImage+dsDosHeader.e_lfanew) + sizeof(IMAGE_NT_HEADERS));
Why wouldn't you just use the IMAGE_FIRST_SECTION macro? It's albeit more readable, imo.
|
Guy` is offline
|
|
30th March 2010, 12:02 PM
|
#5
|
n00bie
Join Date: Mar 2010
Posts: 1
Reputation: 10
Rep Power: 343
|
doesnt work on windows 7 tried and tested
can anyone update the code plzz... thanks
|
ankurmay1988 is offline
|
|
We strive to provide all our services for free and not interrupt your visit with overly intrusive advertisements or restrictions - support us by disabling your ad blocker or whitelisting our site.
All times are GMT. The time now is 06:07 PM.
|
|
sponsored advertisement |
| | |