📄 juinject.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 + -