完美的线程注入和卸载

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    function GetExplorId:Cardinal;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  AsmBuf:Array [0..20] of Byte = ($B8,$00,$00,$00,$00,$68,$00,$00,$00,$00,$FF,$D0,$B8,$00,$00,$00,00,$6A,$00,$FF,$D0);

function EnabledDebugPrivilege(const bEnabled: Boolean):Boolean;
var
  hToken: THandle;
  tp: TOKEN_PRIVILEGES;
  a: DWORD;
const
  SE_DEBUG_NAME = 'SeDebugPrivilege';
begin
  Result:=False;
  if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken)) then
  begin
    tp.PrivilegeCount :=1;
    LookupPrivilegeValue(nil,SE_DEBUG_NAME ,tp.Privileges[0].Luid);
    if bEnabled then
      tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
      tp.Privileges[0].Attributes := 0;
    a:=0;
    AdjustTokenPrivileges(hToken,False,tp,SizeOf(tp),nil,a);
    Result:= GetLastError = ERROR_SUCCESS;
    CloseHandle(hToken);
  end;
end;

function InjectDll(pid:cardinal;Dll:string):Cardinal;
var
  hProc:Cardinal;
  wDllPath:PwideChar;
  pRemote:Pointer;
  cbSize:cardinal;
  TempVar:Cardinal;
begin
  result:=0;
  if pid=0 then exit;
  EnabledDebugPrivilege(true);
  cbSize:= length(Dll)*2+21;
  GetMem(wDllPath,cbSize);
  StringToWideChar(Dll,wDllPath,cbSize);
  hProc:=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
  try
    pRemote:=VirtualAllocEx( hProc, nil, cbSize, MEM_COMMIT, PAGE_READWRITE);
    if WriteProcessMemory(hProc,pRemote, wDllPath, cbSize, TempVar) then
    begin
      TempVar:=0;
      Result := CreateRemoteThread(hProc, nil, 0,
                              GetProcAddress(GetModuleHandle('Kernel32'),
                              'LoadLibraryW'), pRemote, 0, TempVar);
    end;
  finally
    CloseHandle(hProc);
    FreeMem(wDllPath);
  end;
end;

function EjectDll(pid:cardinal;Dll:string):Cardinal;
type
    PDebugModule = ^TDebugModule;
    TDebugModule = packed record
    Reserved: array [0..1] of Cardinal;
    Base: Cardinal;
    Size: Cardinal;
    Flags: Cardinal;
    Index: Word;
    Unknown: Word;
    LoadCount: Word;
    ModuleNameOffset: Word;
    ImageName: array [0..$FF] of Char;
    end;
  type
    PDebugModuleInformation = ^TDebugModuleInformation;
    TDebugModuleInformation = record
    Count: Cardinal;
    Modules: array [0..0] of TDebugModule;
  end;
  type
    PDebugBuffer = ^TDebugBuffer;
    TDebugBuffer = record
      SectionHandle: THandle;
      SectionBase: Pointer;
      RemoteSectionBase: Pointer;
      SectionBaseDelta: Cardinal;
      EventPairHandle: THandle;
      Unknown: array [0..1] of Cardinal;
      RemoteThreadHandle: THandle;
      InfoClassMask: Cardinal;
      SizeOfInfo: Cardinal;
      AllocatedSize: Cardinal;
      SectionSize: Cardinal;
      ModuleInformation: PDebugModuleInformation;
      BackTraceInformation: Pointer;
      HeapInformation: Pointer;
      LockInformation: Pointer;
      Reserved: array [0..7] of Pointer;
    end;
const
  PDI_MODULES = $01;
  ntdll = 'ntdll.dll';
var
  HNtDll: HMODULE;
type
  TFNRtlCreateQueryDebugBuffer = function(Size: Cardinal;EventPair: Boolean): PDebugBuffer;stdcall;
  TFNRtlQueryProcessDebugInformation = function(ProcessId,
               DebugInfoClassMask: Cardinal; var DebugBuffer: TDebugBuffer): Integer;stdcall;
  TFNRtlDestroyQueryDebugBuffer = function(DebugBuffer: PDebugBuffer): Integer;stdcall;
var
  RtlCreateQueryDebugBuffer: TFNRtlCreateQueryDebugBuffer;
  RtlQueryProcessDebugInformation: TFNRtlQueryProcessDebugInformation;
  RtlDestroyQueryDebugBuffer: TFNRtlDestroyQueryDebugBuffer;

  function LoadRtlQueryDebug: LongBool;
  begin
    HNtDll := LoadLibrary(ntdll);
    if HNtDll <> 0 then
    begin
      RtlCreateQueryDebugBuffer := GetProcAddress(HNtDll, 'RtlCreateQueryDebugBuffer');
      RtlQueryProcessDebugInformation := GetProcAddress(HNtDll, 'RtlQueryProcessDebugInformation');
      RtlDestroyQueryDebugBuffer := GetProcAddress(HNtDll, 'RtlDestroyQueryDebugBuffer');
    end;
    Result := Assigned(RtlCreateQueryDebugBuffer) and
    Assigned(RtlQueryProcessDebugInformation) and
    Assigned(RtlQueryProcessDebugInformation);
  end;

  function ReleaseRtlQueryDebug: LongBool;
  begin
    result:=FreeLibrary(HNtDll);
  end;

var
  hProc:Cardinal;
  hMod:cardinal;
  TempVar:Cardinal;
  DbgBuffer: PDebugBuffer;
  i,j:integer;
  pd:PDWORD;
  pRemoteFunc:pointer;
begin
  result:=0;
  if pid=0 then exit;
  EnabledDebugPrivilege(true);
  LoadRtlQueryDebug;
  DbgBuffer := RtlCreateQueryDebugBuffer(0, False);
  if Assigned(DbgBuffer) then
    try
      if RtlQueryProcessDebugInformation(pid, PDI_MODULES, DbgBuffer^) >= 0 then
        for i:=0 to DbgBuffer.ModuleInformation.Count-1 do
          if UpperCase(DbgBuffer.ModuleInformation.Modules[i].ImageName)=
             UpperCase(Dll) then
          begin
            hMod:=DbgBuffer.ModuleInformation.Modules[i].Base;
            j:=DbgBuffer.ModuleInformation.Modules[i].LoadCount;
            Break;
          end;
    finally
      RtlDestroyQueryDebugBuffer(DbgBuffer);
      ReleaseRtlQueryDebug;
    end;
  hProc:=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
  try
    TempVar:=DWORD(GetProcAddress(GetModuleHandle('Kernel32'),'FreeLibrary'));
    pd:=@AsmBuf[1];
    pd^:=TempVar;
    pd:=@AsmBuf[6];
    pd^:=hMod;
    TempVar:=DWORD(GetProcAddress(GetModuleHandle('Kernel32'),'ExitThread'));
    pd:=@AsmBuf[13];
    pd^:=TempVar;
    pRemoteFunc:=VirtualAllocEx( hProc, nil, 21, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if WriteProcessMemory(hProc, pRemoteFunc, @AsmBuf[0], 21, TempVar) then
    for i:=0 to j-1 do
    begin
      TempVar:=0;
      Result := CreateRemoteThread(hProc, nil, 0, pRemoteFunc, nil, 0, TempVar);
    end;
  finally
    CloseHandle(hProc);
  end;
end;
       
function TForm1.GetExplorId:Cardinal;
begin
  GetWindowThreadProcessId(GetWindow(Handle,GW_HWNDLAST),@result);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  InjectDll(GetExplorId,'c:/ExHook.Dll');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin           
  EjectDll(GetExplorId,'c:/ExHook.Dll');
end;

end.

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值