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

📄 unitpefile.pas

📁 灰鸽子VIP1.2经典源代码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
        ZeroMemory (padding, paddingLen);
      end;

      if paddingSize > 0 then
        s.Write (padding^, paddingSize)

    end;

    if fEndCommentSize > 0 then  // Save the debug info.
      s.Write (fEndComment^, fEndCommentSize)
  finally
    ReallocMem (padding, 0)
  end;

  f := TMemoryStream.Create;    // Now calculate the checksum....
  try
    s.Seek (0, soFromBeginning);
    f.LoadFromStream (s);
    ntHeaders := ChecksumMappedFile (f.Memory, f.Size, @oldCheckSum, @newCheckSum);

    if Assigned (ntHeaders) then
    begin
      s.Seek (ckOffset, soFromBeginning);
      s.Write (newChecksum, sizeof (newChecksum))
    end
  finally
    f.Free
  end;

  s.Seek (0, soFromEnd);
end;


{ TImageSection }

(*----------------------------------------------------------------------*
 | constructor TImageSection.Create                                     |
 |                                                                      |
 | Constructor for TImageSection.                                       |
 *----------------------------------------------------------------------*)
constructor TImageSection.Create(AParent: TPEModule;
  const AHeader : TImageSectionHeader; rawData : pointer);
begin
  fSectionHeader := AHeader;
  fRawData := TMemoryStream.Create;

//  nb.  SizeOfRawData is usually bigger than VirtualSize because it's padded,
//       and VirtualSize isn't.


  if fSectionHeader.Misc.VirtualSize <= fSectionHeader.SizeOfRawData then
  begin

// Some linkers (?) set VirtualSize to 0 - which isn't correct.  Work round it.
// (Encountered in MCL Link Lite HHT software )

    if fSectionHeader.Misc.VirtualSize = 0 then
      fSectionHeader.Misc.VirtualSize := fSectionHeader.SizeOfRawData;
    fRawData.Write (rawData^, fSectionHeader.Misc.VirtualSize)
  end
  else

// nb.  If VirtualSize is bigger than SizeOfRawData it implies that extra padding is required.
//      Save the amount, so we can get all the COFF header values right.  See 'Encode' above.
  begin
    fRawData.Write (rawData^, fSectionHeader.SizeOfRawData);
    fUninitializedDataSize := fSectionHeader.Misc.VirtualSize - fSectionHeader.SizeOfRawData;
  end;

  fParent := AParent;
end;

(*----------------------------------------------------------------------*
 | function TImageSection.GetSectionName                                |
 |                                                                      |
 | Return the section name - eg. .data                                  |
 *----------------------------------------------------------------------*)
function TImageSection.GetSectionName: string;
begin
  result := PChar (@fSectionHeader.Name)
end;

(*----------------------------------------------------------------------*
 | destructor TImageSection.Destroy                                     |
 |                                                                      |
 | destructor for TImageSection.                                        |
 *----------------------------------------------------------------------*)
destructor TImageSection.destroy;
begin
  fRawData.Free;
  inherited;
end;

{ TPEResourceModule }

(*----------------------------------------------------------------------*
 | function TPEResourceModule.                                          |
 |                                                                      |
 | Return the TImageSection that contains 'resource' data. - eg.  the   |
 | .rsrc one.                                                           |
 *----------------------------------------------------------------------*)
function TPEResourceModule.GetResourceSection : TImageSection;
var
  idx : Integer;
begin
  idx := FindDictionaryEntrySection (IMAGE_DIRECTORY_ENTRY_RESOURCE);
  if idx = -1 then
    result := Nil
  else
    result := ImageSection [idx]
end;

(*----------------------------------------------------------------------*
 | procedure TPEResourceModule.DeleteResource                           |
 |                                                                      |
 | Delete the specified resource (by index)                             |
 *----------------------------------------------------------------------*)
procedure TPEResourceModule.DeleteResource(resourceNo: Integer);
var
  res : TResourceDetails;
begin
  res := ResourceDetails [resourceNo];
  inherited;
  resourceNo := IndexOfResource (Res);
  if resourceNo <> -1 then
    fDetailList.Delete (resourceNo);
end;

(*----------------------------------------------------------------------*
 | constructor TPEResourceModule.Create                                 |
 |                                                                      |
 | Constructor for TPEResourceModule                                    |
 *----------------------------------------------------------------------*)
constructor TPEResourceModule.Create;
begin
  inherited Create;
  fDetailList := TObjectList.Create;
end;

(*----------------------------------------------------------------------*
 | destructor TPEResourceModule.Destroy                                 |
 |                                                                      |
 | Destructor for TPEResourceModule                                     |
 *----------------------------------------------------------------------*)
destructor TPEResourceModule.Destroy;
begin
  fDetailList.Free;
  inherited;
end;

(*----------------------------------------------------------------------*
 | function TPEResourceModule.Decode                                    |
 |                                                                      |
 | Decode the section's resource tree into a list of resource details   |
 *----------------------------------------------------------------------*)
procedure TPEResourceModule.Decode;
var
  section : TImageSection;
  tp, name : string;
  lang : Integer;

  // Get string resource name
  function GetResourceStr (IdorName : boolean; section : TImageSection; n : DWORD) : string;
  var
    p : PWideChar;
  begin
    if IdorName then
      result := IntToStr (n)
    else
    begin
      p := PWideChar (PChar (section.fRawData.Memory) + (n and $7fffffff));
      result := ResourceWideCharToStr (p)
    end
  end;

  // (recursively) get resources
  procedure GetResource (offset, level : Integer);
  var
    entry : PResourceDirectoryEntry;
    i, count : Integer;
    IDorName : boolean;
    dataEntry : PResourceDataEntry;
    table : PResourceDirectoryTable;
    details : TResourceDetails;
  begin
    table := PResourceDirectoryTable (PChar (section.fRawData.memory) + offset);
    with table^ do
      count := cNameEntries + cIDEntries;

    entry := PResourceDirectoryEntry (PChar (section.fRawData.memory) + offset + sizeof (TResourceDirectoryTable));
    for i := 0 to count - 1 do
    begin
      idOrName := i >= table^.cNameEntries;
      case level of
        0 : tp := GetResourceStr (IDOrName, section, entry^.name);
        1 :
            name := GetResourceStr (IDOrName, section, entry^.name);
        2 :
          begin
            if not IdOrName then
              raise EPEException.Create (rstBadLangID);

            lang := entry^.name
          end
      end;

      if (entry^.RVA and $80000000) > 0 then // Not a leaf node - traverse the tree
        GetResource (entry^.RVA and $7fffffff, level + 1)
      else
      begin
                                             // It's a leaf node - create resource details
        dataEntry := PResourceDataEntry (PChar (section.fRawData.Memory) + entry^.RVA);
        details := TResourceDetails.CreateResourceDetails (self, lang, name, tp, dataEntry^.Size, PChar (section.fRawData.Memory) + dataEntry^.OffsetToData - section.fSectionHeader.VirtualAddress);
        details.CodePage := dataEntry^.CodePage;
        details.Characteristics := table^.characteristics;
        details.DataVersion := DWORD (table^.versionMajor) * 65536 + DWORD (table^.versionMinor);
        fDetailList.Add (details);

      end;

      Inc (entry)
    end
  end;

begin
  inherited;
  section := GetResourceSection;
  if section <> nil then
    GetResource (0, 0)
end;

(*----------------------------------------------------------------------*
 | function TPEResourceModule.GetResourceCount                          |
 |                                                                      |
 | Return the number of resources in the resource section               |
 *----------------------------------------------------------------------*)
function TPEResourceModule.GetResourceCount: Integer;
begin
  result := fDetailList.Count
end;

(*----------------------------------------------------------------------*
 | function TPEResourceModule.GetResourceDetails                        |
 |                                                                      |
 | Get the resource details for the specified resource.                 |
 *----------------------------------------------------------------------*)
function TPEResourceModule.GetResourceDetails(
  idx: Integer): TResourceDetails;
begin
  result := TResourceDetails (fDetailList [idx]);
end;

(*----------------------------------------------------------------------*
 | function TPEResourceModule.IndexOfResource                           |
 |                                                                      |
 | Return the index of the specified resource details in the resource   |
 *----------------------------------------------------------------------*)
function TPEResourceModule.IndexOfResource(details: TResourceDetails): Integer;
begin
  result := fDetailList.IndexOf (details);
end;

(*----------------------------------------------------------------------*
 | function TPEResourceModule.InsertResource                            |
 |                                                                      |
 | Insert a resource in the list.                                       |
 *----------------------------------------------------------------------*)
procedure TPEResourceModule.InsertResource(idx: Integer;
  details: TResourceDetails);
begin
  fDetailList.Insert (idx, details);
end;

(*----------------------------------------------------------------------*
 | function TPEResourceModule.Encode                                    |
 |                                                                      |
 | Complicated?  I'll give you complicated ...                          |
 *----------------------------------------------------------------------*)
procedure TPEResourceModule.Encode;
var
  i : Integer;
  details : TResourceDetails;
  section : TImageSection;
  root : TResourceNode;
  versMajor, versMinor : word;
  TimeStamp : DWORD;
  nameSize, nameOffset, namePos, tableOffset : DWORD;
  deOffset, dePos, deSize : DWORD;
  dataOffset, dataPos, dataSize : DWORD;

  nameTable : PChar;
  deTable : PChar;
  data : PChar;
  zeros : PChar;

  //------------------------------------------------------------------
  // Calculate offset and size of name table and DirectoryEntry table.
  // Calculate size of data

  procedure GetNameTableSize (node : TResourceNode);
  var
    i : Integer;
  begin
    Inc (nameOffset, sizeof (TResourceDirectoryTable));
    Inc (deOffset, sizeof (TResourceDirectoryTable));

    for i := 0 to node.count - 1 do
    begin
      Inc (nameOffset, sizeof (TResourceDirectoryEntry));
      Inc (deOffset, sizeof (TResourceDirectoryEntry));

      if not node.nodes [i].intID then
        Inc (nameSize, Length (node.nodes [i].id) * sizeof (WideChar) + sizeof (word));

      if not node.nodes [i].leaf then
        GetNameTableSize (node.nodes [i].next)
      else
      begin

⌨️ 快捷键说明

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