📄 dcfields.pas
字号:
unit dcFields;
interface
uses
Classes, TypInfo, dcDecomps;
type
TdcVisibility = (vPrivate, vProtected, vPublic, vPublished, vAutomated);
{ TdcField }
TdcField = class(TCollectionItem)
private
FOffset: Integer;
FName: string;
FSize: Integer;
FTypeInfo: PTypeInfo;
FVisibility: TdcVisibility;
FFieldType: string;
function GetSize: Integer;
function GetDeclaration: string;
public
property Offset: Integer read FOffset;
property Name: string read FName write FName;
property Size: Integer read GetSize write FSize;
property TypeInfo: PTypeInfo read FTypeInfo;
property FieldType: string read FFieldType write FFieldType;
property Declaration: string read GetDeclaration;
property Visiblity: TdcVisibility read FVisibility write FVisibility;
end;
{ TdcFieldList }
TdcFieldList = class(TCollection)
private
FSize: Integer;
FAncestorFieldList: TdcFieldList;
FOwner: TDecompItem;
function GetItem(Index: Integer): TdcField;
procedure SetItem(Index: Integer; Value: TdcField);
public
// Size includes the size of the ancesotr fields.
constructor Create(ASize: Integer; AncestorFieldList: TdcFieldList; AOwner: TDecompItem);
function FindFieldOffset(AOffset: Integer): TdcField;
function AddField(AOffset: Integer; ATypeInfo: PTypeInfo): TdcField; overload;
function AddField(AOffset: Integer): TdcField; overload;
property Size: Integer read FSize;
property AncestorFieldList: TdcFieldList read FAncestorFieldList;
property Items[Index: Integer]: TdcField read GetItem write SetItem; default;
property Owner: TDecompItem read FOwner;
end;
implementation
uses
TypeInfoUtils, PEFileClass;
{ TdcField }
function TdcField.GetSize: Integer;
begin
if FTypeInfo <> nil then
Result := GetVarSize(FTypeInfo)
else
Result := FSize;
end;
function TdcField.GetDeclaration: string;
begin
Result := Name + ': ';
if FFieldType = '' then
begin
if FTypeInfo = nil then
Result := Result + GetSizeName(FSize)
else
Result := Result + GetTypeInfoName(FTypeInfo);
end
else
Result := Result + FFieldType;
end;
{ TdcFieldList }
constructor TdcFieldList.Create(ASize: Integer; AncestorFieldList: TdcFieldList; AOwner: TDecompItem);
begin
inherited Create(TdcField);
FSize := ASize;
FAncestorFieldList := AncestorFieldList;
FOwner := AOwner;
end;
function TdcFieldList.FindFieldOffset(AOffset: Integer): TdcField;
var
I: Integer;
begin
for I := 0 to Count -1 do
if Items[I].Offset = AOffset then
begin
Result := Items[I];
Exit;
end;
if AncestorFieldList = nil then
Result := nil
else
Result := AncestorFieldList.FindFieldOffset(AOffset);
end;
function TdcFieldList.AddField(AOffset: Integer; ATypeInfo: PTypeInfo): TdcField;
begin
// Check to see if this field doesn't belong in the basic field list
if (AncestorFieldList <> nil) and (AncestorFieldList.Size > AOffset) then
// Add it the the basic field list (or one before that one)
Result := AncestorFieldList.AddField(AOffset, ATypeInfo)
else
begin
Result := TdcField.Create(Self);
Result.FOffset := AOffset;
Result.FTypeInfo := ATypeInfo;
Result.Visiblity := vPublic;
// Add the item the the req list of the class
Owner.AddReq(TPEFileClass(Owner.PEFileClass).FindTypeByName(ATypeInfo^.Name), nil);
end;
end;
function TdcFieldList.AddField(AOffset: Integer): TdcField;
begin
// Check to see if this field doesn't belong in the basic field list
if (AncestorFieldList <> nil) and (AncestorFieldList.Size > AOffset) then
// Add it the the basic field list (or one before that one)
Result := AncestorFieldList.AddField(AOffset)
else
begin
Result := TdcField.Create(Self);
Result.FOffset := AOffset;
Result.Visiblity := vPublic;
end;
end;
function TdcFieldList.GetItem(Index: Integer): TdcField;
begin
Result := TdcField(inherited Items[Index]);
end;
procedure TdcFieldList.SetItem(Index: Integer; Value: TdcField);
begin
inherited Items[Index] := Value;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -