【问题标题】:How can I place code before SysInit._InitExe call?如何在 SysInit._InitExe 调用之前放置代码?
【发布时间】:2018-02-28 08:58:12
【问题描述】:

我已将asm INT 3 end; 放在主程序的第一行。

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  asm INT 3 end;

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

然而,SysInit._InitExe 调用被放置在它之前。 请参考下图。 从 uses 子句中删除 VCL 单元不是一种选择。

【问题讨论】:

  • 简单的答案是没有破解编译的可执行文件,您无法在单元初始化之前运行您的代码。你想达到什么目的?
  • 您是否尝试过将Int 3 放入新单元的Initialization 部分,然后将该单元作为第一个单元添加到.Dpr 文件中?那行得通...
  • @DavidHeffernan 说,我的程序由管理程序运行,它启动的线程有点“损坏”。在执行 VCL 代码之前,我需要在 TEB 中修复一些问题。
  • 如何将中断放入DLL中,然后让EXE静态链接到DLL?这样,DLL 在 EXE 初始化之前就被初始化了。
  • 图片有误。您标记为 VCL init 的是调用 SysInit._InitExe 然后调用 System._StartExe 调用 System.InitUnits 最终调用模块中正在使用的单元的所有初始化部分,按它们在使用中出现的顺序(参见 docwiki.embarcadero.com/RADStudio/Tokyo/en/… )。首先放入 dpr 用途的单元将首先执行其初始化部分(如果它本身没有任何其他单元)

标签: delphi assembly compilation delphi-7 vcl


【解决方案1】:

使用内置工具无法满足您的需求。您需要对可执行文件进行一些编译后修改。

  1. 在源文件中包含您需要首先执行的代码,以便将其编译为可执行文件,但不要调用它。
  2. 修改 PE 标头中的入口点以指向您的新入口点代码。
  3. 安排新入口点代码在完成后跳转到原始入口点。

【讨论】:

  • 使用调试器在您希望它停止的任何 asm 指令处设置断点可能更容易,而不是为了永久插入所有这些麻烦。
  • @PeterCordes 当我读到问题的 cmets 时,这不是一个实际的解决方案
  • 如果我再说不,你会第三次问这个问题吗?为了修改可执行文件,您需要阅读详细的地图文件以找到函数的位置。
【解决方案2】:

您可以将 asm 代码放入新单元的初始化部分,然后将此单元首先放入项目的 uses 子句中。这样代码应该在系统单元的初始化部分之后执行。 (这个一定要测试,我完全没试过。)

【讨论】:

  • 问题中的图形表明代码应该在此之前运行,作为可执行文件中执行的第一件事
  • 是的,这是我之前在评论和答案中建议的,它确实在任何其他单元的初始化部分之前执行。当@DavidHeffernan 反对它没有回答问题时,我删除了我的答案,因为它没有在 VCL 的初始化代码之前执行,尽管我不确定他想到的是哪个代码。
  • 嗯?当然,在 dpr 中放置 before Forms 的任何单元的初始化都将执行 before 任何在 @987654322 的任何初始化块内某处执行的任何 VCL 初始化代码@ 或其他单位。在他的 int 3 之前执行的有问题的调用是 InitExe 调用,然后按照使用出现的顺序调用所有初始化部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多