Jump to content
Tuts 4 You
Sign in to follow this  
wyrda

Start executable from memory

Recommended Posts

wyrda

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

Share this post


Link to post
NewHitman

Do u mean loading a process or a running exe into olly or u want to to code something like that using APIs

Share this post


Link to post
Zer0Flag

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.org.sg/code/loadexe.html

~Zer0Flag

  • Like 2

Share this post


Link to post
wyrda

Thank you ZeroFlag, this is what I am looking for but I didn't know it's name. I'll come back if I have any trouble with this :D.

Share this post


Link to post
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!

Share this post


Link to post
LulzCoder

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

Share this post


Link to post
e_z_minded_guy

LulzCoder,

Thank you so much for the information and the source code you've provided. It's a big help!

Share this post


Link to post
JMC31337

Thats nice sh*t right there... Worked for my Vista and Win 7 Vmware (trial evals)


 and SP3


Share this post


Link to post
evlncrn8

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

Share this post


Link to post
JMC31337

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"

Share this post


Link to post
JMC31337

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 (see edit history)

Share this post


Link to post
Lostin

@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 (see edit history)

Share this post


Link to post
evlncrn8

@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

Share this post


Link to post

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
Sign in to follow this  
×
×
  • Create New...