Forms 创建Delphi Dll并使用DllMain加载它

Forms 创建Delphi Dll并使用DllMain加载它,forms,delphi,load,dllmain,Forms,Delphi,Load,Dllmain,朋友 我有点小问题。我试图在RAD Studio中创建一个带有表单的delphi Dll,但我不知道如何使用DllMain加载它。我想在之后的运行时将此Dll注入第三方进程 我用这个表单创建了Dll项目,没有任何问题,但是我找不到与“如何用DllMain加载它”相关的好东西,或者至少我找到的教程/东西对我没有帮助(或者我只是个傻瓜)。 有人能帮我吗?给我一些提示或一个我可以学习的网站/视频 我真的很感谢你们的时间,伙计们 您可以使用assembly将基于ebp的堆栈注入到一些变量中。以下是一个例

朋友

我有点小问题。我试图在RAD Studio中创建一个带有表单的delphi Dll,但我不知道如何使用DllMain加载它。我想在之后的运行时将此Dll注入第三方进程

我用这个表单创建了Dll项目,没有任何问题,但是我找不到与“如何用DllMain加载它”相关的好东西,或者至少我找到的教程/东西对我没有帮助(或者我只是个傻瓜)。 有人能帮我吗?给我一些提示或一个我可以学习的网站/视频


我真的很感谢你们的时间,伙计们

您可以使用assembly将基于ebp的堆栈注入到一些变量中。以下是一个例子:

library Project1;

uses
  System.SysUtils,
  Windows,
  System.Classes;

var
  hInstDLL: THandle;
  fdwReason: DWORD;
  lpReserved: DWORD;
begin
  asm
    push eax; // Save the current eax
    mov eax, [ebp+$8] // Put into eax the first argument of the current function (DLLMain)
    mov [hInstDLL], eax; // Put into hInstDLL this argument
    mov eax, [ebp+$c] // Load into eax the second argument
    mov [fdwReason], eax; // Save to fdwReason
    mov eax, [ebp+$10] // Put into eax the last argument
    mov [lpReserved], eax; // Put into lpReserved (unnecessery)
    pop eax; // Restore the original eax value
  end;

  if fdwReason = 1 {DLL_PROCESS_ATTACH} then
  begin
    // Do your stuff;
  end;
end.

加载DLL时,Windows会调用DLLMain。你自己从来不调用它。是的,但是我想在第三方进程中加载我的表单,以防DLL\u进程\u附加。你想做什么并不重要-你自己不能调用DLLMain。无论如何,在
DLLMain()
中调用UI函数是不安全的。请参阅:“您不应该从DllMain中执行以下任务:……调用User32.dll或Gdi32.dll中的函数。有些函数加载另一个dll,但可能未初始化。”猜猜哪个库
CreateWindow/Ex()
在其中?提示:
user32.dll
。因此,不要试图直接在
DllMain()
中显示UI表单。不过,如果您要遵循最佳实践,您可以在单元的初始化部分编写代码。只是为了说明:Windows函数使用公共堆栈([esp+x])来传递和接收参数,Delphi在任何函数的一开始就将esp移到ebp中,因此,一开始,Delphi并不希望其入口点有任何参数,但仍然会调整堆栈,以便我们可以接受它。:)我不明白你的回答与这个问题有什么关系。你能解释一下吗?这段代码只访问操作系统传递到DLL中的参数。Delphi为此提供了/callbacks(尽管您必须为
DLL\u PROCESS\u ATTACH
手动调用它们)。但是,这并没有回答被问及的基本问题——当DLL加载到进程中时如何创建表单。DPR的代码已经在响应
DLL\u PROCESS\u ATTACH
时执行,无需手动检查
fdreason=1
。此外,我认为显示的此代码仅适用于32位,它在64位下会失败,64位下的参数调用堆栈布局完全不同。如果替换“//做你的事”通过创建表单代码,它将精确地执行他想要的操作。我知道他想将DLL注入到某个进程中,然后该进程将运行DLLMain,他想选择DLLMain在连接时做什么。