⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vars.pas

📁 这是个反向工程delphi的程序的全部源代码.能分析几乎所有的结构 Revendepro is a program to reverse engineer Delphi program. Reven
💻 PAS
📖 第 1 页 / 共 2 页
字号:
              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
              Comments.AddComment('Exported var: ' + PEExports[J].Name, ctDebug);
              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
          Comments.AddComment('Init var', ctDebug);
          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;
    V.Comments.AddComment('LoadVar: ' + Name, ctDebug);
  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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -