?? vars.pas
字號:
Result := Format('%s F%d: %s;', [Result, I, GetXTypeName(I)]);
if Types[I] = Pointer(xtArray) then
Inc(I, 3)
else
Inc(I);
end;
Result := Result + ' end = (';
I := 0;
J := 0;
while I <= Types.Count -1 do
begin
Result := Format('%sF%d: %s; ', [Result, I, GetXTypeInitName(I, J)]);
Inc(J, GetXTypeSize(I));
if Types[I] = Pointer(xtArray) then
Inc(I, 3)
else
Inc(I);
end;
Result[Length(Result) -1] := ')';
end
finally
Types.Free;
end;
end;
end;
begin
case AType.TypeKind of
etkUnknown: // Add the var and its type.
Result := Format(' %s: %s;', [Name, GetTypeName]);
etkUTInteger: Result := Format(' %s = %d;', [Name, PInteger(InitValue)^]);
else
raise EDecompilerError.Create('Unsupported Type');
end;
end;
procedure TVar.SetVarSize(Value: Integer);
begin
FVarSize := Value;
ReAllocMem(FInitValue, Value);
FillChar(FInitValue^, Value, 0);
end;
function TVar.IsRefAddress(AAddress: PChar): Boolean;
begin
Result := (AAddress >= Address) and (AAddress < Address + Size);
end;
procedure TVar.SetAppendBefore(Value: TAppendType);
begin
if Value <> FAppendBefore then
begin
FAppendBefore := Value;
end;
end;
procedure TVar.SetAppendAfter(Value: TAppendType);
begin
if Value <> FAppendAfter then
begin
FAppendAfter := Value;
end;
end;
{ TVarInfos }
procedure TVarInfos.LoadVars;
var
I, J: Integer;
VarList: TList;
DC: TDecompItem;
NMInfo: TNameManglingInfo;
VarInfo: TVar;
resourcestring
SUnitNotFound = 'Unit name %s not found';
SVarAlreadyHasAName = 'Var already has the name %s, so it can''t be set to %s.';
SVarAlreadyHasAUnit = 'Var already has a unit %s, so it can''t be set to %s.';
SAddressAlreadySet = 'Var address already set to %p, so it can''t be set to %p.';
begin
with TPEFileClass(PEFileClass) do
begin
varList := TList.Create;
try
if ProjectType = ptPackage then
// Load vars from the peexports.
for I := 0 to PEExports.Count -1 do
begin
NMInfo := GetNameManglingInfo(PEExports[I].Name);
// Exported item must be a var and must be in the data section.
if (PEExports[I].Address >= Data) and (PEExports[I].Address < Data + DataSize) and
(NMInfo.NMType = eitVar) and (VarList.IndexOf(PEExports[I].Address) = -1) and
(IndexOfAddress(PEExports[I].Address) = -1) then
begin
VarList.Add(PEExports[I].Address);
end;
end;
// Load the vars, the start at the first
// Search all items in the BSS section.
for I := 0 to Fixups.Count -1 do
begin
if (Fixups[I].FixupType = 3) and (PPChar(Fixups[I].Address)^ >= Data) and
(PPChar(Fixups[I].Address)^ < BSS + BSSSize) and
(varList.IndexOf(PPChar(Fixups[I].Address)^) = -1) and
(IndexOfAddress(PPChar(Fixups[I].Address)^) = -1) then
begin
VarList.Add(PPChar(Fixups[I].Address)^);
end;
end;
VarList.Sort(ListSimpleSort);
// Create the var.
for I := 0 to VarList.Count -1 do
begin
J := IndexOfAddress(VarList[I]);
if J = -1 then
VarInfo := TVar.Create(Self)
else
VarInfo := Items[J];
with VarInfo do
begin
// Set the addresses.
if (Address <> nil) and (Address <> VarList[I]) then
raise EDecompilerError.CreateFmt(SAddressAlreadySet, [Pointer(Address), Pointer(VarList[I])]);
Address := VarList[I];
RefAddress := VarList[I];
// calculate the Size.
if Size = 0 then
begin
DC := TPEFileClass(PEFileClass).FindDecompItemAfter(VarList[I]);
if I = VarList.Count -1 then
begin
if (DC <> nil) and (DC.Address < BSS + BSSSize) then
Size := DC.Address - Address
else
Size := BSS + BSSSize - Address;
end
else
begin
if (DC <> nil) and (DC.Address < VarList[I+1]) then
Size := DC.Address - VarList[I]
else
Size := Integer(VarList[I+1]) - Integer(VarList[I]);
end;
end;
if VarList[I] < Data + DataSize then
InitValue := VarList[I]
else
VarConst := [vtVar];
// Set the properties, using the export info.
if ProjectType = ptPackage then
begin
J := PEExports.FindByAddress(VarList[I]);
if J <> -1 then
begin
NMInfo := GetNameManglingInfo(PEExports[J].Name);
// This var may not appendbefore
AppendBefore := atMayNot;
// Set the name
if (Name <> '') and (AnsiCompareText(NMInfo.ItemName, Name) = 0) then
raise EDecompilerError.CreateFmt(SVarAlreadyHasAName, [Name, NMInfo.ItemName]);
Name := NMInfo.ItemName;
// Set the unit.
J := Units.FindByName(NMInfo.UnitName);
if J = -1 then
raise EDecompilerError.CreateFmt(SUnitNotFound, [NMInfo.UnitName]);
if (AUnit <> nil) and (AUnit <> Units[J]) then
raise EDecompilerError.CreateFmt(SVarAlreadyHasAUnit, [TUnit(AUnit).Name, Units[J].Name]);
AUnit := Units[J];
end;
end;
end;
end;
finally
varList.Free;
end;
end;
end;
procedure TVarInfos.LoadFixups;
var
J, I, K: Integer;
Decomp: TDecompItem;
begin
with TPEFileClass(PEFileClass) do
begin
// Add the fixups to the vars.
for I := 0 to Fixups.Count -1 do
begin
if (Fixups[I].Address >= Data) and
(Fixups[I].FixupType <> 0) then
begin
if Fixups[I].FixupType <> 3 then
raise EDecompilerError.Create('Unexpected fixup type');
K := -1;
for J := 0 to Count -1 do
if (Fixups[I].Address >= Items[J].Address) and
(Fixups[I].Address < Items[J].Address + Items[J].Size) then
begin
K := J;
Break;
end;
if K <> -1 then
begin
Decomp := FindDecompItemByRef(PPChar(Fixups[I].Address)^);
if Decomp <> nil then
Items[K].AddDecomp(Decomp, Fixups[I].Address - Items[K].Address, dtNormal);
with TPEFileClass(PEFileClass).Units[TPEFileClass(PEFileClass).Units.Count - 1] do
if (PPChar(Fixups[I].Address)^ >= Address) and
(PPChar(Fixups[I].Address)^ < Address + Size) then
Items[K].AUnit := TPEFileClass(PEFileClass).Units[TPEFileClass(PEFileClass).Units.Count - 1];
end;
end;
end;
end;
end;
procedure TVarInfos.LoadInitVars;
var
I: Integer;
begin
with TPEFileClass(PEFileClass) do
for I := 0 to Units.Count -1 do
begin
if Units[I].UnitType <> utProgram then
with TVar.Create(Self) do
begin
Size := 4;
Address := PPChar(Units[I].FInit.Address + $13)^;
Name := Format('!InitCount%x', [I]);
AUnit := Units[I];
end
end;
end;
function TVarInfos.GetItem(Index: Integer): TVar;
begin
Result := TVar(inherited GetItem(Index));
end;
procedure TVarInfos.SetItem(Index: Integer; Value: TVar);
begin
inherited SetItem(Index, Value);
end;
procedure TVarInfos.GenerateNames;
var
I: Integer;
begin
for I := 0 to Count -1 do
if Items[I].Name = '' then
begin
if vtVar in Items[I].VarConst then
Items[I].Name := Format('Var%p', [Pointer(Items[I].Address)])
else
Items[I].Name := Format('Const%p', [Pointer(Items[I].Address)]);
end;
end;
function TVarInfos.IndexOfName(Name: string): Integer;
begin
for Result := 0 to Count -1 do
if Items[Result].Name = Name then
exit;
Result := -1;
end;
function TVarInfos.IndexOfAddress(AAddress: PChar): Integer;
begin
for Result := 0 to Count -1 do
with Items[Result] do
if (Address <= AAddress) and (Address + Size > AAddress) then
Exit;
Result := -1;
end;
procedure TVarInfos.LoadVar(Address: PChar; Name: string; AUnit: TUnit);
var
V: TVar;
I: Integer;
begin
V := TPEFileClass(PEFileClass).FindDecompItemByRef(Address) as TVar;
if V = nil then
begin
V := TVar.Create(Self);
V.Address := Address;
end
else
if (V.Name <> '') and (CompareText(V.Name, Name) <> 0) then
raise EDecompilerError.Create('Var already exists ' + V.Name + ' ' + Name);
// Create the var and set the name and the address.
for I := 0 to High(SysVarList) do
if CompareText(SysVarList[I]^.Name, Name) = 0 then
begin
V.Name := Name;
V.Size := SysVarList[I]^.Size;
V.AUnit := AUnit;
V.AppendBefore := atMayNot;
V.AppendAfter := atMayNot;
exit;
end;
raise EDecompilerError.Create('Hard coded var not found. ' + Name);
end;
procedure TVarInfos.DeterUnits;
var
I, J: Integer;
UIndex: Integer;
ReqUnit: TUnit;
begin
// Sort the vars on address.
for I := 0 to Count -1 do
for J := I +1 to Count -1 do
if Items[J].Address < Items[I].Address then
Items[J].Index := I;
// The unit index can't have a lower index than a previous unit.
UIndex := 2;
for I := 0 to Count -1 do
begin
// Reset the minimal unit index if we are starting with the BSS section or
// if this var may not append before.
if (Items[I].Address = PEFileClass.BSS) or (Items[I].AppendBefore = atMayNot) then
UIndex := 2;
if Items[I].AUnit = nil then
begin
ReqUnit := nil;
// If the item is requires in two different units it must be in the interface section.
for J := 0 to Items[I].ReqByDecompCount -1 do
if (Items[I].ReqByDecomps[J].AUnit <> nil) then
begin
if ReqUnit <> nil then
// This item is required in two different units
Items[I].IntfImpl := iiInterface
else
ReqUnit := Items[I].ReqByDecomps[J].AUnit as TUnit;
end;
if Items[I].IntfImpl = iiInterface then
begin
// If it is in the interface section it can't require a decomp after it.
for J := 0 to Items[I].ReqDecompCount -1 do
if (Items[I].ReqDecomps[J].AUnit <> nil) and
(Items[I].ReqDecomps[J].AUnit.Index > UIndex) and
(Items[I].ReqDecomps[J].PEFileClass = PEFileClass) then
UIndex := Items[I].ReqDecomps[J].AUnit.Index;
end
else
begin
for J := 0 to Items[I].ReqDecompCount -1 do
if (Items[I].ReqDecomps[J].AUnit <> nil) and
(Items[I].ReqDecomps[J].AUnit.Index > UIndex) and
(Items[I].ReqDecomps[J].IntfImpl = iiImplementation) and
(Items[I].ReqDecomps[J].PEFileClass = PEFileClass) then
UIndex := Items[I].ReqDecomps[J].AUnit.Index;
end;
Items[I].AUnit := TPEFileClass(PEFileClass).Units[UIndex];
end
else
if Items[I].AUnit.Index > UIndex then
UIndex := Items[I].AUnit.Index;
// If this var may not append after, reset the unit index
if Items[I].AppendAfter = atMayNot then
UIndex := 2;
end;
end;
end.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -