如何确定在Delphi程序中使用哪些库我没有源代码?

时间:2011-02-18 14:38:50

标签: delphi libraries exe pascal

我有一个Windows .exe文件,但缺少源代码。开发人员没有责任离开我们公司。我认为这是一个delphi / pascal程序。开发人员使用了很多库,但我不确定哪些库。有没有一个工具可以告诉我哪些库用来制作这个exe?

4 个答案:

答案 0 :(得分:6)

如何推荐一些用户,您可以使用存储在PACKAGEINFO资源中的信息,该资源包含在delphi生成的每个exe,dll或bpl中。

您可以使用GetPackageInfo函数获取包信息表中的数据。

检查此示例代码以了解如何使用此功能。

program ResPACKAGEINFO;

{$APPTYPE CONSOLE}

uses
  Windows,
  Classes,
  SysUtils;


function GetUnitFlagInfo(Flags: Byte):string;
begin

  { PackageUnitFlags:
    bit      meaning
    -----------------------------------------------------------------------------------------
    0      | main unit
    1      | package unit (dpk source)
    2      | $WEAKPACKAGEUNIT unit
    3      | original containment of $WEAKPACKAGEUNIT (package into which it was compiled)
    4      | implicitly imported
    5..7   | reserved
  }

  Result:='';
  if (Flags and ufMainUnit<>0) then
  Result:='[Main Unit] ';

  if (Flags and ufPackageUnit<>0) then
  Result:=Result+'[Package Unit] ';

  if (Flags and ufWeakUnit<>0) then
  Result:=Result+'[Weak Unit] ';

  if (Flags and ufImplicitUnit<>0) then
  Result:=Result+'[implicitly imported] ';

  if (Flags and ufWeakPackageUnit<>0) then
  Result:=Result+'[$WEAKPACKAGEUNIT unit] ';

  if (Flags and ufOrgWeakUnit<>0) then
  Result:=Result+'[original containment of $WEAKPACKAGEUNIT]';
end;


procedure GetInfoPackageFlags(Flags:Cardinal);
begin

        { Package flags:
          bit     meaning
          -----------------------------------------------------------------------------------------
          0     | 1: never-build                  0: always build
          1     | 1: design-time only             0: not design-time only      on => bit 2 = off
          2     | 1: run-time only                0: not run-time only         on => bit 1 = off
          3     | 1: do not check for dup units   0: perform normal dup unit check
          4..25 | reserved
          26..27| (producer) 0: pre-V4, 1: undefined, 2: c++, 3: Pascal
          28..29| reserved
          30..31| 0: EXE, 1: Package DLL, 2: Library DLL, 3: undefined
        }


        if  (Flags and pfModuleTypeMask = pfExeModule) then
         Writeln('Type Exe')
        else
        if  (Flags and pfModuleTypeMask = pfPackageModule) then
         Writeln('Type Package')
        else
        if  (Flags and pfModuleTypeMask = pfLibraryModule) then
         Writeln('Type Library');

        if  (Flags and pfNeverBuild = 0) then
         Writeln('Build with runtime packages')
        else
         Writeln('Build without runtime packages');

        if  (Flags and pfIgnoreDupUnits = 0) then
         Writeln('perform normal dup unit check')
        else
         Writeln('Ignore Dup Units');

        if  (Flags and pfProducerMask = pfDelphi4Produced) then
         Writeln('Producer Pascal');

        if  (Flags and pfProducerMask = pfV3Produced) then
         Writeln('Producer pre-V4');

        if  (Flags and pfProducerMask = pfProducerUndefined) then
         Writeln('Producer undefined');

        if  (Flags and pfProducerMask = pfBCB4Produced) then
         Writeln('Producer c++');

        if  (Flags and pfConsumerMask = pfConsumerCompat) then
         Writeln('Consumer Compatible')
        else
        if  (Flags and pfConsumerMask = pfConsumerDelphi) then
         Writeln('Consumer Delphi')
        else
        if  (Flags and pfConsumerMask = pfConsumerBCB) then
         Writeln('Consumer BCB');
end;

procedure PackageInfoCallback(const Name: string; NameType: TNameType; Flags: Byte; Param: Pointer);
begin
    case NameType of
      ntContainsUnit   :  Writeln(Format('Contains %s  %s',[Name+#13#10,GetUnitFlagInfo(Flags)]));
      ntRequiresPackage:  Writeln(Format('Requires %s  %s',[Name+#13#10,GetUnitFlagInfo(Flags)]));
    end;
end;


procedure GetPackageResInfo(const FileName:string);
const
 ResPACKAGEINFO='PACKAGEINFO';
var
  FModule    : Cardinal;
  Flags      : Integer;
begin
  FModule := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
  try
    SysUtils.GetPackageInfo(FModule, nil, Flags, PackageInfoCallback);
    GetInfoPackageFlags(Flags);
    Writeln(GetPackageDescription(PChar(FileName)));
  finally
    FreeLibrary(FModule);
  end;
end;

begin
  try
     GetPackageResInfo('yourApp.exe');
     Readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

答案 1 :(得分:6)

列出delphi二进制文件中使用的单位(类似于RRUZ's demonstration)的一个应用程序是XN Resource Editor。最新版本为here AFAIK。以下示例屏幕截图(通过运气:)),指向特定的第三方库:

XN Resource Editor

在问题评论中建议的'蠕虫问候',应用程序还显示'dfm'内容,因此可以看到使用过的组件的类名。但为此,我建议DFM Editor,因为此应用程序在树结构中显示使用的组件,就像Delphi IDE中的“结构窗格”:

DFM Editor

可以使用XN或任何其他资源编辑器将dfm资源导出到文件,以便使用DFM编辑器进行检查。

答案 2 :(得分:5)

你提到你“认为”它是用Delphi编写的。如果您不确定,则可以使用this small utility。它只是一个命令行工具 - 用法是“IsDelphi.exe”。

如果它确实是用Delphi编写的,那么the Interactive Delphi Reconstructor可以做出惊人的事情。以下是使用它的逐步说明:

  1. 转到该链接

  2. 下载三个文件:

    a)exe

    b)支持dll

    c)前任同事使用的Delphi版本的“词典”

  3. 提取所有三个

    (如果您还没有rar文件提取器,请使用7-zip

  4. 打开IDK.exe
  5. 选择文件 - &gt;加载 - &gt;自动检测版本
  6. 在对话框中选择您的EXE
  7. 开始探索Code Viewer和Class Viewer。
  8. 最后,您可以找到一些更一般的指南以及其他工具at this page的链接。

    祝你好运!

答案 3 :(得分:1)

不,对Delphi应用程序进行逆向工程几乎是不可能的。如果你这样做,你只得到一堆装配。实际上不可能重建调用哪些VCL函数,更不用说使用哪些库。

除非这个程序包含一些非常天真且不可重复的逻辑,否则最好从头开始并全部写完。