之前我猜测 Delphi里的 dcp类似 java里的 maven 的 pom.xml,经过测试 发现,和猜想的才不多,既包含了pom.xml 的信息,又包含了本bpl的信息;测试如下:

DCP 英文全称:delphi compiled package,是 package 编译时跟 bpl 一起产生出来的,记录着 package 中公开的 class、procedure、function、variable、const.... 等等的名称和相对位址


在本文中,我将展示如何从 Delphi 的 DCP 文件中读取一些非常基本的信息。这包括要链接的 BPL 名称、所需的 DCP 和包含的单元。在过去的几周里,我编写了一个 Project-Analyzationtool,它能够完全解开所有单元依赖关系并修复搜索路径。但是,要做到这一点,我也必须与 DCP 合作。一些搜索并没有透露太多(除了和我相同的问题)。我知道从 XE 到 XE8 的情况可能已经发生了变化,但我希望这篇文章仍然有助于让 XE 以外的任何人开始。

因此,让我们开始我们的肮脏工作。为了分析 DCP,我创建了一个名为 TestPackage.bpl 的新包。它只需要 RTL,并且有 2 个空单元:MyUnit 和 Foo.OtherUnit。这应该可以完成实验的工作。拿起你选择的十六进制编辑器并研究它。您将看到如下内容:

image

您会注意到的是,流以 4 个 AnsiChars “PKX0” 开头。所有 DCP 似乎都以它开头,所以我将其声明为我们的 DCP 签名。您可能会在加载文件时验证这一点,以确保您拥有 DCP。在第 3 行,您将看到“TestPackage.bpl”。这是链接器将链接到的 BPL 的名称。在处理具有后缀的 BPL 时,这是必需的。例如,对于 VCL150.bpl,仅存在 VCL.dcp。在这里,您可以找到最终的 BPL 名称。通过比较不同的 DCP,您会注意到 BPL-Name 始终从同一位置(字节 33)开始。因此,我们的前 32 个字节肯定是某种标头。让我们仔细看看:

image

我已经概述了我已经分析过的领域并在这里进行了描述。如前所述,Red-Field 是我们的签名。绿色和蓝色包含数字,这些数字根据包含的单位数量和所需的 DCP 而变化。通过摆弄,您会注意到绿色是所需的 DCP 数量,蓝色是包含的单元数量。等等,我们必须单位,为什么它告诉我有 3 个?很简单,包的 DPK 文件(在本例中为 TestPackage.dpk)也包含在此列表中。橙色框仅包含标头后面的 BPL-Name 的长度(以 Bytes 为单位)(不包括终止的 NULL-Character)。总而言之,我们的标题在 Delphi 中是这样的:

image

但是等等,还有更多!

image

在我们的 BPL 名称之后,我们会注意到“RTL”。这是因为它后面直接跟着一个零终止字符串列表,其中包括所需 DCP 的名称。在我们的例子中,它只是“RTL”。因此,要获取所需 DCP 的列表,只需根据标头中注明的所需 DCP 数量,在零终止字符串之后读取零终止字符串。之后,将出现包含的单元列表,并带有自己的标题。总而言之,此列表的每个元素都包含一个 60 字节的 Blob,我还没有调查过。每个块后面有 2 个以零结尾的字符串。第一个字符串是我们的 Unit-Name,第二个字符串似乎是某种 NameSpace。当单位未带点时,第二个字符串始终为空,仅由 NULL 字符组成。但是,当您的单位像“Foo.OtherUnit”一样点缀时,它将包含“Foo”。这种模式适用于“Foo.Bar.MyUnit”等单位,其中命名空间为“Foo.Bar”。我用绿色/棕色和蓝色/橙色突出显示了这些字段。因此,要在此处获取包含的单元列表,您只需跳过 60 个字节,并根据标头中包含的单元数为每个元素读取 2 个字符串。最后一个元素始终是 Package-DPK 单元。因此,如果你做对了所有事情,你可以得到这样的输出:

image

这里需要注意的是:最后一个条目,即 DPK-Entry,似乎有一个长度为 61 的 Header。我只是在这里循环了 60 字节的模式,这就是为什么我在姓氏前面有一个额外的字符。您可能想跳过那个。

我希望这篇文章能让你开始了解 Delphi 的 DCP-File。

posted on 2024-06-12 17:53  del88  阅读(10)  评论(0编辑  收藏  举报