-2

我正在做一个使用 DLL 注入的项目,只是为了测试目的。如果一切正常,也许我会使用这种技术。但到目前为止,我只遇到了问题,可能是因为我是第一次编写 DLL 项目。为了快速理解,我正在创建一个暂停的 explorer.exe 进程并将这个 DLL 注入到暂停的资源管理器中。一切正常,但是当我试图在 DLL 中放置一个计时器时出现了问题。查看 DLL 代码:

uses
  SysUtils,
  Classes,
  Windows,
  ExtCtrls,
  Dialogs;

{$R *.res}
type
  TMyTimer = Class(TTimer)
  public
    procedure OnMyTimer(Sender: TObject);
  end;

var
  MyTimer: TMyTimer;

procedure EntryPoint(Reason: integer);
begin
  if Reason = DLL_PROCESS_ATTACH then
    begin
      MessageBox(0, 'DLL Injected', 'DLL Injected', 0);
      MyTimer := TMyTimer.Create(nil);
      MyTimer.Interval := 5000;
      MyTimer.OnTimer := MyTimer.OnMyTimer;
      MyTimer.Enabled:= true;
    end
  else
  if Reason = DLL_PROCESS_DETACH then
    begin
      MessageBox(0, 'DLL De-Injected', 'DLL De-Injected', 0);
    end;
end;

procedure TMyTimer.OnMyTimer(Sender: TObject);
begin
  MessageBox(0, 'Timer Running', 'Timer Running', 0);
end;

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

好的,所以当我在暂停的 explorer.exe 进程中注入 DLL 时,我收到消息“DLL Injected”...之后,它应该创建计时器,并且每 5 秒给我一条“计时器正在运行”的消息。 ..但是我没有收到此消息,尝试了一切,但没有任何效果...有帮助吗?这完全是一团糟还是什么?

4

2 回答 2

4

Delphi TTimer 对象是 Win32 SetTimer API 函数的松散包装器。VCL 包装器创建一个隐藏窗口,然后调用 SetTimer 传递该窗口。然后,Windows 会在调用 SetTimer 的线程的消息队列中合成 WM_TIMER 消息来触发计时器。对于您的方案,该线程是您创建的远程线程。因此,您需要在该线程中调度消息才能触发您的计时器事件。

一般来说,我会质疑将 VCL 放入注入的 DLL 中是否明智。这肯定会导致一些痛苦。如果您需要 VCL 的只是一个计时器,那么直接调用 SetTimer 会更简单。

我还建议您,如果您想走得更远,您将需要创建另一个线程。目前,所有注入的代码都在 DllMain 中运行。阅读 DllMain 的文档,以及 Raymond Chen 关于该主题的文章。尤其是解释 DllMain 在持有 DLL 加载程序锁时执行的部分。你不应该在 DllMain 中做任何值得注意的事情。您可以调用 CreateThread。这样做,仅此而已。

于 2013-08-23T06:28:48.453 回答
4

TTimer 依赖于窗口消息,因此您需要一个消息循环才能使其运行。

于 2013-08-22T22:18:22.550 回答