我正在使用DLL Injection进行测试,仅用于测试目的。如果一切顺利,我可能会使用这种技术。但到目前为止,我只遇到了问题,也许是因为这是我第一次编写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秒给我一个'Timer'的消息跑'...但我没有收到这个消息,尝试了一切,没有任何作用......任何帮助?这完全是一团糟还是什么?
答案 0 :(得分:4)
TTimer依赖于Window Messages,因此您需要一个消息循环才能使其正常运行。
答案 1 :(得分:4)
Delphi TTimer对象是Win32 SetTimer API函数的松散包装器。 VCL包装器创建一个隐藏窗口,然后调用SetTimer传递该窗口。然后,计时器通过Windows在名为SetTimer的线程的消息队列中合成WM_TIMER消息来触发。对于您的方案,该线程是您创建的远程线程。因此,您需要在该线程中调度消息,以便触发计时器事件。
一般来说,我会质疑将VCL置于注入的DLL中的智慧。这肯定会导致一些痛苦。如果你需要的VCL用于定时器,那么直接调用SetTimer就更简单了。
我还建议你,如果你想进一步发展,你需要创建另一个线程。目前,所有注入的代码都在DllMain中运行。阅读DllMain的文档,以及Raymond Chen关于该主题的文章。特别是解释DllMain在保存DLL加载程序锁时执行的部分。你不应该在DllMain中做任何事情。您可以调用CreateThread。这样做,仅此而已。