本文介绍了钩子LdrLoadDll在Delphi中的应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我挂着 LdrLoadDll 来检测程序中的所有Dll加载。



这是我的钩子部分的代码:

  var 
Old_LdrLoadDll:function(szcwPath:PChar; pdwLdrErr:PULONG;
pUniModuleName:PUnicodeString; pResultInstance:PPointer)
:NTStatus;标准
....

它工作:

 函数New_LdrLoadDll(szcwPath:PChar; pdwLdrErr:PULONG; 
pUniModuleName:PUnicodeString; pResultInstance:PPointer):NTStatus;标准
begin

OutputDebugString('New_LdrLoadDll');
Result:= Old_LdrLoadDll(szcwPath,pdwLdrErr,pUniModuleName,
pResultInstance);
结束

但是当我在中添加任何其他命令时New_LdrLoadDll 应用程序崩溃了!
我使用可持续的hook方法,我确定问题不是为了钩住nethod,我测试许多其他的API,并完全期待这个!



任何想法?
{请问我的不好的英文}

解决方案

据我所知()第二个参数实际上是一个 DWORD



另一个明显的问题是第三个参数不是 PUnicodeString 。这被声明为 ^ UnicodeString ,一个指向Delphi Unicode字符串的指针。您需要以下内容:

 键入
PUNICODE_STRING = ^ UNICODE_STRING;
UNICODE_STRING =打包记录
长度:Word;
MaximumLength:Word;
缓冲区:PWideChar;
结束

然后这些函数应该这样声明:


$ b $函数(szcwPath:PWideChar; dwFlags:DWORD; pUniModuleName:
PUNICODE_STRING; pResultInstance:PPointer):NTSTATUS; $ {code $ var
Old_LdrLoadDll:标准

函数LdrLoadDll(szcwPath:PWideChar; dwFlags:DWORD; pUniModuleName:
PUNICODE_STRING; pResultInstance:PPointer):NTSTATUS;标准
begin
结果:= Old_LdrLoadDll(szcwPath,pdwLdrErr,pUniModuleName,pResultInstance);
结束

当您尝试阅读 pUniModuleName



另一个明显的问题是,您可能会最终调用尚未加载的模块中的代码,并且尚未准备好叫做。一些模块在运行时按需加载。例如,查看当您调用 ShowMessage 时会发生什么。



另一个问题是,如果您的 LdrLoadDll 调用功能导致递归调用 LdrLoadDll 。我发现调用 MessageBox



这里的底线是你可能安全地调用 kernel32 ,但可能没有什么其他的。请记住, LdrLoadDll 执行一个非常具体的任务,您必须小心避免中断。


I hooked the LdrLoadDll to detect all Dlls load in a program.

It's my hook section of code :

var
  Old_LdrLoadDll: function(szcwPath: PChar; pdwLdrErr: PULONG;
    pUniModuleName: PUnicodeString; pResultInstance: PPointer)
    : NTStatus; stdcall;
....

It work :

function New_LdrLoadDll(szcwPath:PChar ; pdwLdrErr: PULONG;
  pUniModuleName: PUnicodeString; pResultInstance: PPointer): NTStatus; stdcall;
begin

  OutputDebugString('New_LdrLoadDll');
  Result := Old_LdrLoadDll(szcwPath, pdwLdrErr, pUniModuleName,
    pResultInstance);
end;

But when i add any other command in New_LdrLoadDll application was crashed !I use a Sustainable hook method and i sure the problem isn't for hooking nethod, I test many other APIs and work perfectly expect this !

Any idea ?{Excuse me for my bad English}

解决方案

So far as I can tell (http://msdn.microsoft.com/en-us/magazine/cc301727.aspx) the second parameter is actually a DWORD.

The other obvious problem is that the third parameter is not PUnicodeString. That is declared as ^UnicodeString, a pointer to a Delphi Unicode string. You need the following:

type
  PUNICODE_STRING = ^UNICODE_STRING;
  UNICODE_STRING = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
  end;

And then the functions should be declared like this:

var
  Old_LdrLoadDll: function(szcwPath: PWideChar; dwFlags: DWORD; pUniModuleName: 
    PUNICODE_STRING; pResultInstance: PPointer): NTSTATUS; stdcall;

function LdrLoadDll(szcwPath: PWideChar; dwFlags: DWORD; pUniModuleName: 
  PUNICODE_STRING; pResultInstance: PPointer): NTSTATUS; stdcall;
begin
  Result := Old_LdrLoadDll(szcwPath, pdwLdrErr, pUniModuleName, pResultInstance);
end;

Perhaps your crash comes when you attempt to read pUniModuleName.

Another other obvious problem that you might have is that you may end up calling code that is in a module that has not yet been loaded and is not ready to be called. Some modules are loaded on demand at runtime. For instance, see what happens when you call ShowMessage.

And yet another problem is that you can easily end up with a stack overflow if your LdrLoadDll calls functions that lead to recursive calls to LdrLoadDll. I encountered that when calling MessageBox.

The bottom line here is that you are probably safe to call functions in kernel32, but probably not much else. Remember that LdrLoadDll performs a very specific task and you must be careful to avoid disrupting that.

这篇关于钩子LdrLoadDll在Delphi中的应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 02:55