unit Inject;
interface
uses Windows, SysUtils, Messages, Classes;
//再目标程序中申請空間,寫入注射代碼後 ,開啟遠端線程以執行
function InjectDll(pid: thandle; dllname: string; timeout: cardinal = 7000):
boolean;
//參數 pid 程序ID ,dllname 欲注射dll的名字
//調用樣例 InjectDll(pid,'./inject.dll');
//原理 使得目标程序通過API函數LoadLibraryA主動加載欲注射的DLL。
var
RemoteCode: array[0..18] of char = (#$60, #$9C, #$B8, #$88, #$77, #$66, #$55,
#$BA, #$44, #$33, #$22, #$11, #$52, #$FF, #$D0, #$9D, #$61, #$C3, #$00);
{
注射的代碼
60 pushad
9C pushfd
B8 88776655 mov eax, 55667788
BA 44332211 mov edx, 11223344
52 push edx
FFD0 call eax
9D popfd
61 popad
C3 retn
}
implementation
function InjectDll(pid: thandle; dllname: string; timeout: cardinal = 7000):
boolean;
var
Rpid: thandle;
RemotePoint, RemoteFilename: pointer;
LoadLibptr: pointer;
rcode: longbool;
temp: cardinal;
threadid: cardinal;
begin
result := false;
Rpid := OpenProcess(PROCESS_ALL_ACCESS, false, pid); //打開目标程序
if Rpid = 0 then
exit; //打開失敗則退出
RemoteFilename := VirtualAllocEx(Rpid, nil, length(dllname) + 1, MEM_COMMIT,
PAGE_READWRITE);
//在目标程序中申請空間 大小為欲注射dll名字長度+1 權限為可讀寫
if RemoteFilename = nil then
begin
CloseHandle(Rpid);
exit; //申請空間失敗則退出
end;
rcode := WriteProcessMemory(Rpid, RemoteFileName, @dllname[1],
length(dllname), temp);
//将欲注射dll名字寫入剛剛已經申請的空間中
if not rcode then
begin
CloseHandle(rpid);
exit; //寫入失敗則退出
end;
LoadLibptr := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'LoadLibraryA');
//擷取LoadLibraryA函數的位址指針
if LoadLibptr = nil then
begin
CloseHandle(rpid);
exit; //擷取失敗則退出
end;
RemotePoint := VirtualAllocEx(Rpid, nil, sizeof(RemoteCode) + 1, MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
//在目标程序中申請空間 大小為注射代碼的位元組數+1 權限為可執行可讀寫
if RemotePoint = nil then
begin
CloseHandle(rpid);
exit; //申請失敗則退出
end;
{
注射的代碼
60 pushad
9C pushfd
B8 88776655 mov eax, 55667788
BA 44332211 mov edx, 11223344
52 push edx
FFD0 call eax
9D popfd
61 popad
C3 retn
}
CopyMemory(@RemoteCode[3], @LoadLibptr, 4);
//将LoadLibraryA的位址指針(4位元組)寫入 将如上88776655覆寫
CopyMemory(@RemoteCode[8], @RemoteFilename, 4);
//将dll名字的首位址指針(4位元組)寫入 将如上44332211覆寫
rcode := WriteProcessMemory(Rpid, RemotePoint, @RemoteCode[0],
sizeof(Remotecode), temp); //将注射代碼寫入申請的空間中
if rcode then
begin
result := CreateRemoteThread(rpid, nil, 0, RemotePoint, nil, 0, threadid) <>
0; //寫入成功則開啟一個遠端線程執行
CloseHandle(rpid);
end;
end;
end.