⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 juinject.pas

📁 《参透Delphi Kylix》通过131个事例
💻 PAS
字号:
unit JuInject;

interface

uses
  Windows, SysUtils, JuSectionObjs;

type
  TInjectDllCallbackProc = procedure (Buffer: PChar; BufferSize: Cardinal); stdcall;

procedure StubBeforeRemoteThread(); stdcall;
function RemoteThread(Param: Pointer): Cardinal; stdcall;
procedure StubAfterRemoteThread(); stdcall;

function GetRemoteProcessId(): Cardinal;

function OpenRemoteProcess(RemoteProcessId: Cardinal): THandle;

procedure Depart(InjectDllCallback: TInjectDllCallbackProc);
function InjectDll(const RemoteProcessId: Cardinal; const DllFileName: string;
  InjectDllCallback: TInjectDllCallbackProc): THandle;

implementation

uses
  Math;

const
  SReturnedInfoMemMapping = 'JuMemMapping.ReturnedInfo';

type
  TLoadProc = function (LibFileName: PChar): THandle; stdcall;
  TFreeProc = procedure (LibModule: THandle); stdcall;
  TGetModuleProc = function (LibFileName: PChar): THandle; stdcall;
  TGetProcProc = function (LibModule: THandle; ProcName: PChar): Pointer; stdcall;
  TVMWalkProc = function (Detailed: Boolean): Boolean; stdcall;

type
  PInjectedStartupInfo = ^TInjectedStartupInfo;
  TInjectedStartupInfo = record
    LoadProc: TLoadProc;
    FreeProc: TFreeProc;
    GetModuleProc: TGetModuleProc;
    GetProcProc: TGetProcProc;
    VMWalkProc: TVMWalkProc;
    VMWalkProcName: array [0..7] of Char;
    DllFileName: array [0..MAX_PATH + 3] of Char;
  end;

  PReturnedInfo = ^TReturnedInfo;
  TReturnedInfo = record
    Size: Cardinal;
    Data: array [0..64 * 1024 - 5] of Char;
  end;

var
  StartupInfo: TInjectedStartupInfo;
  ReturnedInfoMemMapping: TJuMemMapping;
  RemoteProcessHandle, RemoteThreadHandle: THandle;
  RemoteThreadId: Cardinal;
  RemoteStartupInfoBase, RemoteCodeBase: Pointer;
  CodeSize: Cardinal;

{$W-}
procedure StubBeforeRemoteThread(); stdcall;
begin
end;

function RemoteThread(Param: Pointer): Cardinal; stdcall;
var
  StartupInfo: PInjectedStartupInfo;
  InjectedDllHandle: THandle;
begin
  StartupInfo := PInjectedStartupInfo(Param);

  InjectedDllHandle := StartupInfo.LoadProc(StartupInfo.DllFileName);
  StartupInfo.VMWalkProc := StartupInfo.GetProcProc(InjectedDllHandle, StartupInfo.VMWalkProcName);
  StartupInfo.VMWalkProc(True);

  if InjectedDllHandle <> 0 then StartupInfo.FreeProc(InjectedDllHandle);
  Result := Cardinal(InjectedDllHandle);
end;

procedure StubAfterRemoteThread(); stdcall;
begin
end;
{$W+}

function GetRemoteProcessId(): Cardinal;
begin
  Result := GetCurrentProcessId();
end;

function OpenRemoteProcess(RemoteProcessId: Cardinal): THandle;
begin
  Result := Windows.OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION
    or PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, RemoteProcessId);
  if Result = 0 then raise Exception.Create('Failed to open remote process');
end;

procedure SetStartupInfo();
var
  KernelHandle: THandle;
  I: Integer;
  S: string;
begin
  KernelHandle := GetModuleHandle('kernel32.dll');

  StartupInfo.LoadProc := GetProcAddress(KernelHandle, 'LoadLibraryA');
  StartupInfo.FreeProc := GetProcAddress(KernelHandle, 'FreeLibrary');
  StartupInfo.GetProcProc := GetProcAddress(KernelHandle, 'GetProcAddress');
  StartupInfo.GetModuleProc := GetProcAddress(KernelHandle, 'GetModuleHandleA');
  StartupInfo.VMWalkProc := nil;
  StartupInfo.VMWalkProcName := 'VMWalk';
  S := ExpandFileName('VMQuery.dll');
  for I := 0 to Length(S) - 1 do
    StartupInfo.DllFileName[I] := S[I + 1];
end;

procedure CopyToRemoteProcess();
var
  StubCode, StubBefore, StubAfter: Cardinal;
  SizeWriting, SizeWritten: Cardinal;
begin
  StubBefore := Cardinal(@StubBeforeRemoteThread);
  StubCode := Cardinal(@RemoteThread);
  StubAfter := Cardinal(@StubAfterRemoteThread);
  CodeSize := Max(StubBefore, StubAfter) - StubCode;

  SizeWriting := SizeOf(TInjectedStartupInfo) + CodeSize;
  RemoteStartupInfoBase := VirtualAllocEx(RemoteProcessHandle, nil, SizeWriting, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if not Assigned(RemoteStartupInfoBase) then raise Exception.Create('Failed to allocate memory in remote process');

  if not WriteProcessMemory(RemoteProcessHandle, RemoteStartupInfoBase, @StartupInfo, SizeOf(TInjectedStartupInfo), SizeWritten) then
    raise Exception.Create('Failed to write data to remote process');

  RemoteCodeBase := Pointer(Cardinal(RemoteStartupInfoBase) + SizeOf(TInjectedStartupInfo));
  if not WriteProcessMemory(RemoteProcessHandle, RemoteCodeBase, Pointer(StubCode), CodeSize, SizeWritten) then
    raise Exception.Create('Failed to write data to remote process');
end;

procedure Depart(InjectDllCallback: TInjectDllCallbackProc);
var
  ReturnedInfo: PReturnedInfo;
  P: PChar;
begin
  ReturnedInfo := PReturnedInfo(ReturnedInfoMemMapping.Read());
  P := ReturnedInfo^.Data;
  repeat
    if Assigned(InjectDllCallback) then InjectDllCallback(P, StrLen(P));
    Inc(P, StrLen(P) + 1);
  until P^ = #0;
end;

function InjectDll(const RemoteProcessId: Cardinal; const DllFileName: string; InjectDllCallback: TInjectDllCallbackProc): THandle;
begin
  Result := 0;
  try
    SetStartupInfo();
    RemoteProcessHandle := OpenRemoteProcess(RemoteProcessId);
    CopyToRemoteProcess();
    RemoteThreadHandle := CreateRemoteThread(RemoteProcessHandle, nil, 0,
      RemoteCodeBase, RemoteStartupInfoBase, 0, RemoteThreadId);
    if RemoteThreadHandle = 0 then raise Exception.Create('Failed to create remote thread');
    WaitForSingleObject(RemoteThreadHandle, INFINITE);
    GetExitCodeThread(RemoteThreadHandle, Result);
    // Read returned data
    Depart(InjectDllCallback);
  finally
    if RemoteThreadHandle <> 0 then
    begin
      CloseHandle(RemoteThreadHandle);
      RemoteThreadHandle := 0;
    end;
    VirtualFreeEx(RemoteProcessHandle, RemoteCodeBase, CodeSize, MEM_RELEASE);
    if RemoteProcessHandle <> 0 then
    begin
      CloseHandle(RemoteProcessHandle);
      RemoteProcessHandle := 0;
    end;
  end;
end;

initialization
  ReturnedInfoMemMapping := TJuMemMapping.Create(True, SReturnedInfoMemMapping, Sizeof(TReturnedInfo));

finalization
  if Assigned(ReturnedInfoMemMapping) then FreeAndNil(ReturnedInfoMemMapping);

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -