Jump to content
Tuts 4 You

Start executable from memory


wyrda

Recommended Posts

Hi,

I'm new to this stuff so I think you can help me. Can I load into the memory an executable and start it from there? Something like this: fread("myexecutable.exe"), shellexecute_from_memory("myexecutable.exe").

Have a nice day,

wyrda

Link to comment
  • 1 month later...
e_z_minded_guy

This method is often used in malware or pe packers/protectors and is called dynamic forking or RunPE. With google you should be able to find a lot of snippets and papers to this.

e.g. : http://www.security....de/loadexe.html

~Zer0Flag

I also was uncertain what this was called though I did have an idea of what it could be used for... thanks for the information ~Zer0Flag!

Link to comment
  • 5 months later...

The process to execute file (PE) from memory is know as Process Forking. I am giving the sample source code and attaching the VS 2008 project. What we do is, first create a suspended process, now we write the new PE file in the memory of the newly created process. After writing, we will continue the executation of the suspended process. This process also depends on Operating system, like in Windows Vista and above the memory is guarded.


 



#include <Windows.h> typedef LONG (WINAPI * NtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);
LPVOID LoadFileInMemory(LPCSTR szFileName)
{
HANDLE hFile;
DWORD dwRead;
DWORD dwSize;
LPVOID pBuffer = NULL; hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile)
{
dwSize = GetFileSize(hFile, NULL);
if (dwSize > 0)
{
pBuffer = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (pBuffer)
{
SetFilePointer(hFile, NULL, NULL, FILE_BEGIN);
ReadFile(hFile, pBuffer, dwSize, &dwRead, NULL);
}
}
CloseHandle(hFile);
}
return pBuffer;
} void ExecuteFile(LPSTR szFilePath, LPVOID pFile)
{
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INH;
PIMAGE_SECTION_HEADER ISH;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
PCONTEXT CTX;
PDWORD dwImageBase;
NtUnmapViewOfSection xNtUnmapViewOfSection;
LPVOID pImageBase;
int Count; IDH = PIMAGE_DOS_HEADER(pFile);
if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
{
INH = PIMAGE_NT_HEADERS(DWORD(pFile) + IDH->e_lfanew);
if (INH->Signature == IMAGE_NT_SIGNATURE)
{
RtlZeroMemory(&SI, sizeof(SI));
RtlZeroMemory(&PI, sizeof(PI)); if (CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
{
CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL;
if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
{
ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL); if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase)
{
xNtUnmapViewOfSection = NtUnmapViewOfSection(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase));
} pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
if (pImageBase)
{
WriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL);
for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
{
ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40));
WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
}
WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL);
CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(PI.hThread, LPCONTEXT(CTX));
ResumeThread(PI.hThread);
}
}
}
}
}
VirtualFree(pFile, 0, MEM_RELEASE);
}
int main()
{
LPVOID pFile;
TCHAR szFilePath[1024]; pFile = LoadFileInMemory("test.exe");
if (pFile)
{
GetModuleFileNameA(0, LPSTR(szFilePath), 1024);
ExecuteFile(LPSTR(szFilePath), pFile);
}
return 0;
}

 


ForkProcess.zip

  • Like 7
Link to comment
  • 4 weeks later...
  • 8 months later...

pretty sloppy coding..

ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40));

thats just horrible right there, hard coded values.. .bad bad bad

  • Like 2
Link to comment

wait, it Works.... on all OS' [at least for Vmware (trial evals)]


why is that bad; loaded up all my test exe's... 


 


what would you suggest about those "hard codes"  .. 


 


out of 23 jotti scanners: only 4 say they think its an "injector"

Link to comment

as of today, now Mcafee says its an Artemis variant.. but sometimes i can re-compile the above code and run it without the scanner thinking anything is wrong


 


:/


Edited by JMC31337
Link to comment

@evlncrn8


AFAIK even with using sizeof it will be hardcoded. Well unless if you change the defined structures inside included files.


Should this be IMAGE_NT_HEADERS only makes the code more readable i think.


Edited by Lostin
Link to comment

@evlncrn8

AFAIK even with using sizeof it will be hardcoded. Well unless if you change the defined structures inside included files.

Should this be IMAGE_NT_HEADERS only makes the code more readable i think.

thats pretty much what i meant, should actually walk the pe header struct, sizeof extra header and so on... doing so makes it considerably more generic

and a hell of a lot easier to read / understand, i used to code stuff like that many many years ago [eax+4+5+1+2] and so on... then i learned to use structs

properly, and it lead to the code being a lot easier to read / follow, and also made it a lot more stable, even when porting to x64 etc

  • Like 1
Link to comment
  • 4 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...