【问题标题】:Switch between DLL and .EXE with COM Support in Delphi在 Delphi 中使用 COM 支持在 DLL 和 .EXE 之间切换
【发布时间】:2013-06-03 11:44:28
【问题描述】:

我有以下情况:

我有一个德尔福应用程序{$APPTYPE GUI}。 (APP1)

如果APP1 启动,它会在 beginend.,应该是这样。

稍后,APP1 将转换为 DLL(另一个应用程序将执行此操作 - APP2)。

APP2 IMAGE_FILE_DLL 标志添加APP1NTFileHeader 中的Characteristics。 然后APP2 尝试使用LoadLibrary(或其他一些COM 命令来加载dll)加载DLL(APP1),但它返回错误:

Windows 在初始化 COM 时遇到内部错误 图书馆。

我用C 项目完成了所有这些工作,并使用了WinMain 函数。但是它似乎在 Delphi 中不起作用(APP1 没有作为 DLL 启动)。如何将APP1 转换为工作DLL?

编辑:

我正在尝试将此代码从 C 移植到 Delphi:http://level-23.info/forum/showthread.php?14721-UAC-Bypass-for-Windows-7-RTM-SP1-Windows-8-DP&p=31749

我已正确移植它,一切正常,但 CRYPTBASE.dll (APP1) 无法启动。 (见上面的错误)

简而言之: 创建一个delphi应用,在文件头添加IMAGE_FILE_DLL特征。将其重命名为 CRYPTBASE.dll 并将其复制到 C:\Windows\System32\sysprep。然后开始sysprep.exe

这里的信息: http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html

【问题讨论】:

  • 我认为您需要在这里详细说明。我完全不明白你的意思。
  • 有什么原因不能导出不同的函数名吗?导入的WinMain 可能与宿主应用程序的WinMain 冲突...
  • 我一点也不明白。而且我真的不明白该代码试图做什么。
  • 告诉我们你的应用是$Apptype GUI的原因是什么?默认情况下,这是任何 delphi VCL 表单应用程序,您不必在任何地方声明它。有两种类型,console 和 gui,你创建的是哪一种?
  • 我认为他想要一个可执行文件,将自己“作为 dll”注入到另一个可执行文件中

标签: windows delphi winapi dll portable-executable


【解决方案1】:

WinMain 只是一个名称,按照惯例,用作可执行文件的入口点。 DLL 的约定是使用名称DllMain。 Windows 加载程序不搜索 WinMain,LoadLibrary 也不搜索 DllMain,它只是调用 pe 标头中的入口点。

Delphi也不用,导出的入口名称是start。

WinMain 签名与 DllMain 不同(WinMain 有四个参数),我的建议是声明一个函数 DllMain 并将其导出到您的 exe 中:

function DllMain(hinstDLL: THandle; fdwReason: DWORD; lpvReserverd: Pointer): BOOL; stdcall;
begin
  // do something
end;

  exports
    DllMain;

将您的 exe(我认为在 mem 中)修改为 dll 的代码应将入口点设置为 DllMain(通过 EAT 获取它的地址)。

另外:确保重定位表在重新定位时不会像 DLL 所要求的那样剥离(在发布模式下)。

【讨论】:

  • 那么,是否可以通过更改Characteristics 双击将delphi 项目编译为DLL 并仍将其用作可执行文件?
  • 很可能不会,你会错过各种初始化(如 Delphi RTL)
  • 对不起,我已经改变了我的问题,我想这就像一个 COM 问题或什么的。
  • 赏金给你。感谢您的努力。
  • 没有。我放弃了,但没关系。
【解决方案2】:

我认为你根本不应该这样做。编译 EXE 和 DLL 时的代码假设不同,如果您只是翻转标志并更改扩展名,它将无法工作。

尝试这样的事情是实验和学习东西的好方法,但对于生产来说这是一个坏主意。

用比“将我的 DLL 作为 EXE 运行”更具体的方式告诉我们您想要实现什么。 为什么您需要将 DLL 作为 EXE 运行?

例如,您可以构建 DLL,然后使用 rundll32 加载和调用它。如果COM需要这个,可以自己构建一个COM宿主exe,依靠COM的自动编组来达到“好像我的代码在同一个进程”的效果。这一切都已经存在于 COM 中。

【讨论】:

  • 再次查看我的问题并阅读我所做的最后一个Edit
  • @Behjamin:嗯,你不能构建两个单独的模块,一个 DLL 和一个 EXE,然后用一个将另一个加载到资源管理器中或它正在做什么?
  • 我可以这样做,但我想将它放在 1 个可执行文件中。它不会加载到资源管理器中。只要您在System32\Sysprep 中启动Sysprep.exe,它就会加载(如果存在)CRYTBASE.DLL。更多信息在这里:pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html
  • 只需将其构建为两个独立的模块,然后将 DLL 作为资源包含在应用程序中。这样,APP1.exe(或APP2.exe,如果您愿意)都可以从APP1.exe 中提取CRYPTBASE.DLL 并将其放在需要的位置。
猜你喜欢
  • 2013-03-08
  • 2013-06-18
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-08
相关资源
最近更新 更多