天天看点

Delphi通过开启远程线程注射DLL至目标进程

 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.

继续阅读