通过直接调用Loadlibrary函数和通过dll注入方法加载dll的区别:Delphi

时间:2016-11-15 11:08:23

标签: delphi dll dll-injection

我正在开发Delphi的注射项目。 注入dll包含一个窗体,它有几个事件,如formcreate,timer,formdestroy等.... dll项目代码如下...

uses
  SysUtils,
  Forms,
  Classes,
  UnitClient in 'UnitClient.pas' {ClientForm},

{$R *.res}

begin
  Application.CreateForm(TClientForm, ClientForm);
end.

当我调用LoadLibrary函数在主exe项目中加载这个dll时,它运行良好(显示ClientForm和dll的所有事件都运行良好)

procedure TForm2.Button1Click(Sender: TObject);
var
  hmod: HMODULE;
begin
  hmod := LoadLibrary(PWideChar(Format('%s%s',[ExtractFilePath(Application.ExeName),'inj.dll'])));
  if hmod <> 0 then
    Caption := 'Loading successful'
  else
    Caption := 'Loading failed';

end;

但是当我使用注入方法通过第三个进程加载dll时,Clientform出现了几毫秒,然后消失了。所有dll表单的事件也不起作用。

以下是注射码。

function InjectDLL(const dwPID: DWORD; {$IFDEF UNICODE} DLLPath: PWideChar
  {$ELSE} DLLPath: PAnsiChar {$ENDIF}): Integer;
const
  Kernel32 = 'kernel32.dll';
var
  dwThreadID: Cardinal;
  hProc, hThread, hKernel: THandle;
  BytesToWrite, BytesWritten: NativeUInt; 
  pRemoteBuffer, pLoadLibrary: Pointer;
begin
  hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
      PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False,
    dwPID);
  if hProc = 0 then
    Exit(0);
  try
    BytesToWrite := SizeOf(WideChar) * (Length(DLLPath) + 1);
    pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT,
      PAGE_READWRITE);
    if pRemoteBuffer = nil then
      Exit(0);
    try

      if WriteProcessMemory(hProc, pRemoteBuffer, DLLPath, BytesToWrite,
        BytesWritten) = False then
        Exit(0);
{$REGION 'Check for UNICODE'}
{$IFDEF UNICODE}
      hKernel := GetModuleHandleW(Kernel32);
      pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryW');
{$ELSE}
      hKernel := GetModuleHandleA(Kernel32);
      pLoadLibrary := GetProcAddress(hKernel, 'LoadLibraryA');
{$ENDIF}
{$ENDREGION}
      hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer,
        0, dwThreadID);
      try
        WaitForSingleObject(hThread, INFINITE);
      finally
        CloseHandle(hThread);
      end;
    finally
      VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE);
    end;
  finally
    CloseHandle(hProc);
  end;
  Exit(1);
end;

我确认过程浏览器正确地将dll注入第三个进程。 如何通过注射方法对dll形式的异常工作做什么? 请提供建议,帮助,

1 个答案:

答案 0 :(得分:0)

您不能像这样注入第二个UI。要解决此问题,请创建一个新窗口并将UI放入其中,然后在注入DLL时弹出第二个窗口,其中包含您的表单。