【问题标题】:Can a file both be an executable (EXE) and a dynamic-link library (DLL) at the same time?一个文件可以同时是可执行文件 (EXE) 和动态链接库 (DLL) 吗?
【发布时间】:2016-08-24 19:02:57
【问题描述】:

文件是否可以同时是可执行文件 (EXE) 和动态链接库 (DLL)? (即它可以作为 EXE 执行并在运行时作为共享库加载。)

我不明白为什么不可能,但也许有人可以给出解释?

【问题讨论】:

  • 不能。请参阅以下内容:stackoverflow.com/questions/1210873/…
  • 不是专家,所以我只添加两点需要注意:1)两个主要入口点(exe 与 dll 不同)。 2)dll基地址不固定,所以你的“dll”代码必须是“位置无关代码”。关于文件内容肯定还有很多事情要做,以包含所有必需的部分等。看起来萨米的评论有很好的教程。由于维护原因,我会避免这种混合(我敢打赌,MS 有一天会打破它:))。但如果你坚持的话,它看起来是可能的。
  • 不,这是不可能的。 PE 头中有一个位,加载程序使用它来区分 EXE 和 DLL。一个文件不可能同时存在,因为一个位不能同时设置和取消设置。但是,您可以通过与从 DLL 中加载资源和代码非常相似的方式从 EXE 中加载资源和代码。您是否正在尝试解决实际问题?如果您 edit 提出您的问题,我们可以为您提供更多有用和详细的答案。
  • @CodyGray - IMAGE_FILE_EXECUTABLE_IMAGE (0x002) 和 IMAGE_FILE_DLL (0x2000) 都是 PE 头的特性字段的标志。你的意思是这些标志不能都由它们的描述来设置?但是它们的值可能是 OR'd - 我猜根据你的解释,加载器会产生错误吗?不,我只是提出问题,因为我想知道,而不是因为我有一个实际问题:-)

标签: c++ windows dll exe


【解决方案1】:

来自LoadLibrary 文档:

模块的名称。 这可以是库模块(.dll 文件)或可执行模块(.exe 文件)。指定的名称是模块的文件名,与存储在库模块本身中的名称无关,由模块定义 (.def) 文件中的 LIBRARY 关键字指定。

编辑:当我写这个答案时,我预计会投反对票。我知道很多人认为这是不可能的(所以 cmets 的问题和答案证实了这一点)。但是对于那些有兴趣的人,我可以提供 POC(或简单地查看众所周知的“流程浏览器”来源)

请注意,如果您需要从模块中导出符号,则需要在 .def 文件中使用这些 EXPORT 语句。然后你可以使用GetProcAddress

实际上,我看到这个SO question,也在cmets 中提到,有指向文章"Load EXE as DLL: Mission Possible" 的答案,我也将引用该文章。该答案不被接受,接受的答案说“不”,甚至被视为社区维基。嗯"SO doesn't claim to be (in part) a library reference"

【讨论】:

  • 嗯,这篇文章主要展示了如何完成 LoadLibrary 为 DLL 做的额外工作。它没有说明某些东西如何既可以是 EXE 又可以是 DLL,它说明了如何跳过额外的环节以使 DLL 像 EXE 一样工作。当然这是可能的,您只需编写 Microsoft 在加载程序中所做的相同代码。我不知道您所说的“流程资源管理器来源”是什么意思。你有 Process Explorer 的源代码吗?它与这个问题有什么关系?
  • 另外,我怀疑 LoadLibrary 函数文档说这是历史的真正原因。在 16 位时代,DLL 扩展并没有被广泛使用(当然,在 Windows 1.0 中,它甚至不存在)。所有包含代码的二进制文件都具有文件扩展名 EXE,包括 KRNL386.EXE、USER.EXE、GDI.EXE 等。但这些只是我们现在所知道的 DLL。 PE 标头中的单个位决定了如何加载它们。文档可能从未更新过,向后兼容性表明代码也没有更新过。另外,可以通过这种方式从 EXE 中加载资源。
  • @CodyGray:我认为这不对。 DLL 带有各种扩展名(例如 .ocx),甚至 .exe 也不必以 .exe 结尾。
  • @CodyGray 我不想开始术语讨论,但问题是 “文件是否可以同时是可执行文件 (EXE) 和动态链接库 (DLL ) 同时?” 我的回答是,是的,exe可以动态链接库,i。 e.一个二进制模块,您可以在运行时动态加载并将其用作库,动态链接到其导出的符号
  • 嗯,关键是文件扩展名无关紧要。它可以是你想要的任何东西。二进制文件中的位决定了它,特别是当您谈论 Windows 二进制文件时的 PE 标头。加载器对我们所知的可执行文件(通常带有扩展名 EXE 但不一定)和我们所知的动态库(通常带有扩展名 DLL 但不一定)做了不同的事情。您可以编写额外的代码以使它们以类似的方式运行,但这不会改变就加载程序而言它们是两个不同事物的事实。和规格。
【解决方案2】:

在官方PE文档中,IMAGE_FILE_EXECUTABLE_IMAGE (0x002)IMAGE_FILE_DLL (0x2000)都是PE-header的Characteristics字段的标志。

IMAGE_FILE_DLL (0x2000)中所见:

图像文件是一个动态链接库 (DLL)。此类文件是 几乎所有用途都被视为可执行文件,尽管它们 不能直接运行。

但是,对于IMAGE_FILE_EXECUTABLE_IMAGE (0x002)

仅图像。这表明图像文件是有效的,可以 跑。如果未设置此标志,则表示链接器错误。

由于 DLL 不能直接运行,它可能没有设置IMAGE_FILE_EXECUTABLE_IMAGE (0x002) 标志。

我猜,这些标志 OR'd 会在加载时导致错误,但我不确定。

【讨论】:

    猜你喜欢
    • 2011-06-07
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多