Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine which libraries are used in a Delphi program I don't have the source for?

I have a windows .exe file, but the source code for it is missing. The developer was not responsible and left our company. I think it was a delphi/pascal program. The developer used many libraries but I am not sure which ones. Is there a tool that can tell me which libraries were used to make this exe?

like image 332
sayf Avatar asked Feb 18 '11 14:02

sayf


3 Answers

One application that lists the used units in a delphi binary (similar to RRUZ's demonstration), is XN Resource Editor. Latest version is here AFAIK. The below sample screen shot for instance (by luck :)), points to a particular 3rd party library:

XN Resource Editor

As 'Worm Regards' suggested in the comments to the question, the application also displays 'dfm' contents, hence one can see the class names of used components. But for that, I'd suggest DFM Editor, because this application displays the used components in a tree structure, much like the 'structure pane' in the Delphi IDE:

DFM Editor

XN or any other resource editor can be used to export a dfm resource to a file, to be examined with DFM Editor.

like image 175
Sertac Akyuz Avatar answered Nov 10 '22 02:11

Sertac Akyuz


how some users as recommended, you can use the info stored in the PACKAGEINFO resource which is included in each exe, dll or bpl generated by delphi.

you can use the GetPackageInfo function to obtain the data in the package's information table.

check this sample code to see how use this function.

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.
like image 44
RRUZ Avatar answered Nov 10 '22 04:11

RRUZ


You mentioned that you "think" it was written in Delphi. If you are not sure, then you can use this small utility. It is just a command line tool- the usage is "IsDelphi.exe ".

If it is indeed written in Delphi, then the Interactive Delphi Reconstructor can do amazing things. Here are step-by-step instructions for using it:

  1. Go to that link

  2. Download three files:

    a) The exe

    b) The support dll

    c) The 'dictionary' for the version of Delphi your former coworker used

  3. Extract all three

    (use 7-zip if you don't already have a rar file extractor)

  4. Open IDK.exe
  5. Choose File->Load->Autodetect version
  6. Pick your EXE in the dialog box
  7. Start poking around the Code Viewer and Class Viewer.

Finally, you can find some more general guidelines as well as links to additional tools at this page.

Good luck!

like image 41
JosephStyons Avatar answered Nov 10 '22 03:11

JosephStyons