Finding classes

Finding Delphi classes in binary code.

For knowing how to find a class in a program, you first need to known. A class exist only of a Virtual Method Table (VMT), this table contains except the virtual methods also information about the class (for more information search for VMT in the Delphi help file). Including a pointer to itself at offset vmtSelfPtr, so if you search for addresses with at vmtSelfPtr a pointer back to the address it most likely is a class.

      I := Code - vmtSelfPtr;
      while I < Code + CodeSize do
      begin
        // vmtSelfPtr must point to itself.
        if PPChar(I + vmtSelfPtr)^ = I then
        begin
            if PPChar(I + vmtParent)^ = nil then
            try
              // If no classParent then class can be object
              if (not UsePackages) and (TClass(I).ClassName = 'TObject') then
                // if class if object add it to classes.
                Add(TClass(I))
            except
              on EAccessViolation do
            end
            else
              // className must be in the code section.
              // classParent must be in the code section or the import section (when it is imported).
              if (PPChar(I + vmtClassName)^ <= Code + CodeSize) and
                 (PPChar(I + vmtClassName)^ >= Code) and
                 (((PPChar(I + vmtParent)^ <= Code + CodeSize) and
                   (PPChar(I + vmtParent)^ >= Code)) or
                  ((PPChar(I + vmtParent)^ <= ImportStart + ImportSize) and
                   (PPChar(I + vmtParent)^ >= ImportStart))) then
              // Add possible class to possible class list.
              PossClasses.Add(I);
        end;
        Inc(I, 4);
      end;
       // Can't be more then 1 TObject.
      if (not TPEFileClass(PEFileClass).UsePackages) and (Count > 1) then
        raise EDecompilerError.Create('There can only be one TObject.');
To filter out real classes search for a class named TObject from the list of possible classes,
  
      // If no classParent then class can be object
      if TClass(I).ClassName = 'TObject' then
        // if class if object add it to classes.
        Add(TClass(I))
After finding TObject, search the list of possible classes with a already found class as parent, continue this search until no new class is found.
      // Add Classes to the list which parent is in the list.
	  repeat
        Added := False;
        for J := PossClasses.Count -1 downto 0 do
		begin
          // Try to find parent class in classList
          if FindClass(TClass(PossClasses[J]).ClassParent) <> nil then
          begin
            // Class in class list
            Add(PossClasses[J]);
            PossClasses.Delete(J);
            Added := True;
          end;
          // Try to find parent class in a other package.
          for K := 0 to High(PEFiles) do
            if PEFiles[K].Classes.FindClass(TClass(PossClasses[J]).ClassParent) <> nil then
            begin
              // Class in class list
              Add(PossClasses[J]);
              PossClasses.Delete(J);
              Added := True;
              Break;
            end;
		end;
      until not Added;