【问题标题】:explorer crashing on CreateProcess hook资源管理器在 CreateProcess 挂钩上崩溃
【发布时间】:2014-07-09 01:28:46
【问题描述】:

我在 explorer.exe 中注入一个 DLL 来挂钩 CreateProcess,这样我可以在用户打开一些可执行文件时进行拦截(我选择这个挂钩方法是因为我想了解更多关于挂钩的信息,我知道可以使用WMI 或其他方式)。 我用来挂钩的库是: DDetours

钩子正在工作,我执行的每个应用程序都会弹出我在 HookProc 中设置的消息框,但在消息框之后,explorer.exe 崩溃。 注入 DLL 的代码工作正常,如果我只注入一个空 dll 或只有一个消息框的 dll,一切正常。所以我相信问题出在钩子设置的某个地方。这是DLL代码:

library DLL;

uses
  Windows, DDetours;

{$R *.res}

var
  CreateProcessHook: function(var lpApplicationName:String;
            lpCommandLine:String;
            lpProcessAttributes:IntPtr;
            lpThreadAttributes:IntPtr;
            bInheritHandles:Boolean;
            dwCreationFlags:Int32;
            lpEnvironment:IntPtr;
            lpCurrentDirectory:IntPtr;
            lpStartupInfo:STARTUPINFO;
            lpProcessInformation:PROCESS_INFORMATION): Boolean; stdcall = nil;

function InterceptCreateProcess(lpApplicationName:String;
            lpCommandLine:String;
            lpProcessAttributes:IntPtr;
            lpThreadAttributes:IntPtr;
            bInheritHandles:Boolean;
            dwCreationFlags:Int32;
            lpEnvironment:IntPtr;
            lpCurrentDirectory:IntPtr;
            lpStartupInfo:STARTUPINFO;
            lpProcessInformation:PROCESS_INFORMATION): Boolean; stdcall;
  begin
    MessageBoxA(0, 'Process created :)', 'Hooked', 0);
  end;

procedure DLLMain(dwReason: DWORD);
begin
  case dwReason of
  DLL_PROCESS_ATTACH:
  begin
    MessageBoxA(0,'Injected', 'Injected', MB_OK);
    @CreateProcessHook:= InterceptCreate(@CreateProcess, @InterceptCreateProcess);
  end;
  end;
end;

begin
 DLLProc := @DLLMain;
 DLLMain(DLL_PROCESS_ATTACH);
end.

如您所见,InterceptCreateProcess 只显示一个消息框,当我打开一些可执行文件时,它正在工作,但如上所述,资源管理器崩溃。我认为这与 CreateProcess 函数变量的声明有关。有小费吗? 一切都是 64 位

【问题讨论】:

  • 你有使用 C# 的经验吗?

标签: delphi hook


【解决方案1】:

您的CreateProcess 绕道签名完全错误。该函数是一个 Win32 函数,不能对 Delphi 字符串进行操作。最后两个参数是指向结构的指针。

第一步是修复这些签名。使用 RTL 中 Windows 单元的签名。

看起来像这样:

function CreateProcessW(
  lpApplicationName: PWideChar;
  lpCommandLine: PWideChar;
  lpProcessAttributes: PSecurityAttributes;
  lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL;
  dwCreationFlags: DWORD;
  lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar;
  const lpStartupInfo: STARTUPINFO;
  var lpProcessInformation: PROCESS_INFORMATION
): BOOL; stdcall;

【讨论】:

  • 是的,我试过了。但仍然崩溃。等等,我再试一次,把签名贴在这里。
  • 不完全。看我的回答。
  • 没有。你只需要按照我在回答中所说的去做。使用与 Windows 单元中完全相同的定义。我回滚了您的编辑,因为它使我的答案无效。
  • 好的。没问题。我会检查 Windows 单元。谢谢大家的帮助。
  • 与另一个问题相关的评论属于该问题,而不是这个问题。
【解决方案2】:

您的钩子函数与CreateProcess() 的正确签名不匹配。试试这个:

library DLL;

uses
  Windows, DDetours;

{$R *.res}

var
  CreateProcessHook: function(lpApplicationName: PChar;
            lpCommandLine: PChar;
            lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
            bInheritHandles: BOOL;
            dwCreationFlags: DWORD;
            lpEnvironment: Pointer;
            lpCurrentDirectory: PChar;
            const lpStartupInfo: STARTUPINFO;
            var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall = nil;

function InterceptCreateProcess(lpApplicationName: PChar;
            lpCommandLine: PChar;
            lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
            bInheritHandles: BOOL;
            dwCreationFlags: DWORD;
            lpEnvironment: Pointer;
            lpCurrentDirectory: PChar;
            const lpStartupInfo: STARTUPINFO;
            var lpProcessInformation: PROCESS_INFORMATION): BOOL; stdcall;
begin
  Result := CreateProcessHook(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);    
  MessageBox(0, 'CreateProcess', 'Hooked', 0);
end;

procedure DLLMain(dwReason: DWORD);
begin
  case dwReason of
    DLL_PROCESS_ATTACH:
    begin
      @CreateProcessHook := InterceptCreate(@CreateProcess, @InterceptCreateProcess);
      MessageBox(0, 'Injected', 'Injected', MB_OK);
    end;
    DLL_PROCESS_DETACH:
    begin
      InterceptRemove(@CreateProcessHook);
    end;
  end;
end;

begin
 DLLProc := @DLLMain;
 DLLMain(DLL_PROCESS_ATTACH);
end.

【讨论】:

  • 是的,这行得通。奇怪的是,当我尝试使用来自 msdn 的完全相同的签名时(正如我在主要问题中提出的那样),仍然崩溃。
  • 您使用的签名与 msdn 中的签名不同
  • 现在我把Result := CreateProcessHook(lpApplicationName... 试图打开我之前请求的进程,但是我得到了一个 Windows 错误,比如:系统找不到指定的文件...我打开的文件的路径。关于如何打开文件的任何想法?
  • 在将它传递给蹦床之前,您是否验证了绕道接收的路径(而不是您传递给截获的CreateProcess() 的路径)是否正确?
  • 是的,因为路径出现在错误框中。这是正确的。也许是关于 Unicode 和 Ansi 的东西......但我试图改变类似的东西:Result := CreateProcessHook(PAnsiChar(lpApplicationName) 但没有用。
猜你喜欢
  • 2012-05-28
  • 2018-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多