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;