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

📄 unitpefile.pas

📁 海盗远控1.23源代码
💻 PAS
📖 第 1 页 / 共 4 页
字号:

  offset := iSize + fCommentSize;

  align := fOptionalHeader^.FileAlignment;
  addrAlign := fOptionalHeader^.SectionAlignment;

  address := addrAlign;
  offset := DWORD ((integer (offset) + align - 1) div align * align);

                                                // First section starts at $1000 (when loaded)
                                                // and at 'offset' in file.

  fOptionalHeader^.SizeOfHeaders := DWORD ((integer (iSize) + align - 1) div align * align);

  fOptionalHeader^.BaseOfCode := $ffffffff;
  fOptionalHeader^.CheckSum := 0;               // Calculate it during 'SaveToStream' when
                                                // we've got all the info.

  iSize  := DWORD ((integer (iSize) + addrAlign - 1) div addrAlign * addrAlign);

  for i := 0 to fSectionList.Count - 1 do      // Recalculate the section offsets
  begin
    section := TImageSection (fSectionList [i]);

    section.fSectionHeader.PointerToRawData := offset;
    section.fSectionHeader.VirtualAddress := address;

// Virtual size is size of data in memory, and is not padded to an 'alignment'.
//
// SizeOfRawData is size of data in file, padded to (file) alignment.
//
// 1.  If VirtualSize < SizeOfRawData, that's simply because the raw data is aligned, and virt data isn't.
//
// 2.  If VirtualSize > SizeOfRawData, the additional memory is filled with zeros when it's loaded.
//
// Because SizeOfRawData is padded it's impossible to tell how much Virtual Memory is really required.
//
// We do our best by saving the original difference in '2.' above in fUninitializeDataSize

    section.fSectionHeader.Misc.VirtualSize := section.fRawData.Size + section.fUninitializedDataSize;
    section.fSectionHeader.SizeOfRawData := (section.fRawData.Size + align - 1) div align * align;

    alignedSize := (Integer (section.fSectionHeader.Misc.VirtualSize) + align - 1) div align * align;
    addrAlignedSize := (Integer (section.fSectionHeader.Misc.VirtualSize) + addrAlign - 1) div addrAlign * addrAlign;

    if (section.fSectionHeader.Characteristics and IMAGE_SCN_MEM_EXECUTE) <> 0 then
    begin
      Inc (codeSize, alignedSize);
      if DWORD (address) < fOptionalHeader^.BaseOfCode then
        fOptionalHeader^.BaseOfCode := address
    end
    else
      if (section.fSectionHeader.Characteristics and IMAGE_SCN_CNT_INITIALIZED_DATA) <> 0 then
        Inc (iDataSize, alignedSize)
      else
        if (section.fSectionHeader.Characteristics and IMAGE_SCN_CNT_UNINITIALIZED_DATA) <> 0 then
          Inc (uDataSize, alignedSize);

    Inc (iSize, addrAlignedSize);
    Inc (offset, section.fSectionHeader.SizeOfRawData);
    Inc (address, (Integer (section.fSectionHeader.Misc.VirtualSize) + addrAlign - 1) div addrAlign * addrAlign);
  end;

  fOptionalHeader^.SizeOfCode := codeSize;
  fOptionalHeader^.SizeOfInitializedData := iDataSize;
  fOptionalHeader^.SizeOfUninitializedData := uDataSize;

  i := SizeOf (DWORD) +                   // NT signature
       sizeof (fCoffHeader) +
       fCOFFHeader.SizeOfOptionalHeader +
       codeSize;

  i := (i + addrAlign - 1) div addrAlign * addrAlign;

  // With explorer.exe, codeSize is $14800, i is 148E8, so aligned 'i' is $15000
  // .. so BaseOfData should be $15000 + BaseOfCode ($1000) = $16000.
  //
  // ... but it's not - it's $15000, which means that the last $8e8 bytes of code
  // should be stampled over by the data!
  //
  // But obviously explorer.exe works, so I'm, missing a trick here.  Never mind - it
  // doesn't do any harm making it $16000 instead, and the formula works for everything
  // else I've tested...

  fOptionalHeader^.BaseOfData := fOptionalHeader.BaseOfCode + DWORD (i);

  fOptionalHeader^.SizeOfImage := iSize;
end;

(*----------------------------------------------------------------------*
 | function PEModule.FindDictionaryEntrySection                         |
 |                                                                      |
 | Return the index of the specified section.  The 'entryNo' to find    |
 | should be a 'IMAGE_DIRECTORY_ENTRY_xxxx' constant defined in         |
 | Windows.pas.                                                         |
 *----------------------------------------------------------------------*)
function TPEModule.FindDictionaryEntrySection (entryNo: Integer): Integer;
var
  i : Integer;
  p : PImageDataDirectory;
begin
  result := -1;
  p := DataDictionary [entryNo];
                                // Find section with matching virt address.
  for i := 0 to ImageSectionCount - 1 do
    if ImageSection [i].fSectionHeader.VirtualAddress = p^.VirtualAddress then
    begin
      result := i;
      break
    end
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetCOFFHeader                                     |
 |                                                                      |
 | Return COFF header                                                   |
 *----------------------------------------------------------------------*)
function TPEModule.GetCOFFHeader: TImageFileHeader;
begin
  result := fCoffHeader;
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetDataDictionary                                 |
 |                                                                      |
 | Return the data dictionary for a specified                           |
 | IMAGE_DIRECTORY_ENTRY_xxxx  index                                    |
 *----------------------------------------------------------------------*)
function TPEModule.GetDataDictionary(index: Integer): PImageDataDirectory;
var
  p : PImageDataDirectory;
begin
  if index < DataDictionaryCount then
  begin
    p := @fOptionalHeader.DataDirectory [0];
    Inc (p, index);
    result := p
  end
  else
    raise ERangeError.Create (rstBadDictionaryIndex);
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetDataDictionaryCount                            |
 |                                                                      |
 | Return no of entries in the Data Directory                           |
 *----------------------------------------------------------------------*)
function TPEModule.GetDataDictionaryCount: Integer;
begin
  result := fOptionalHeader^.NumberOfRvaAndSizes
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetDosHeader                                      |
 |                                                                      |
 | Return DOS header                                                    |
 *----------------------------------------------------------------------*)
function TPEModule.GetDOSHeader: TImageDosHeader;
begin
  result := fDOSHeader;
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetImageSection () : TImageSection                |
 |                                                                      |
 | Get the specified image section                                      |
 *----------------------------------------------------------------------*)
function TPEModule.GetImageSection(index: Integer): TImageSection;
begin
  result := TImageSection (fSectionList [index]);
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetImageSectionCount                              |
 |                                                                      |
 | Return no of image sections                                          |
 *----------------------------------------------------------------------*)
function TPEModule.GetImageSectionCount: Integer;
begin
  result := fSectionList.Count
end;

(*----------------------------------------------------------------------*
 | function TPEModule.GetImageSectionCount                              |
 |                                                                      |
 | Get the optional header                                              |
 *----------------------------------------------------------------------*)
function TPEModule.GetOptionalHeader: TImageOptionalHeader;
begin
  result := fOptionalHeader^
end;

(*----------------------------------------------------------------------*
 | procedure TPEModule.LoadFromFile                                     |
 |                                                                      |
 | Load the module from a file                                          |
 *----------------------------------------------------------------------*)
procedure TPEModule.LoadFromFile(const name: string);
var
  f : TFileStream;
begin
  f := TFileStream.Create (name, fmOpenRead or fmShareDenyNone);
  try
    LoadFromStream (f)
  finally
    f.Free
  end
end;

(*----------------------------------------------------------------------*
 | procedure TPEModule.LoadFromFile                                     |
 |                                                                      |
 | Load the module from a stream                                        |
 *----------------------------------------------------------------------*)
procedure TPEModule.LoadFromStream(s: TStream);
var
  m : TMemoryStream;
begin
  m := TMemoryStream.Create;
  try
    m.CopyFrom (s, 0);

    Decode (m.memory, m.size)
  finally
    m.Free
  end
end;

(*----------------------------------------------------------------------*
 | procedure TPEModule.SaveToFile                                       |
 |                                                                      |
 | Save the module to a file                                            |
 *----------------------------------------------------------------------*)
procedure TPEModule.SaveToFile(const name: string);
var
  f : TFileStream;
begin
  f := TFileStream.Create (name, fmCreate);
  try
    SaveToStream (f)
  finally
    f.Free
  end
end;

(*----------------------------------------------------------------------*
 | procedure TPEModule.SaveToStream                                     |
 |                                                                      |
 | Save the module to a stream                                          |
 *----------------------------------------------------------------------*)
procedure TPEModule.SaveToStream(s: TStream);
var
  NTSignature : DWORD;
  i : Integer;
  section : TImageSection;
  paddingSize, paddingLen : Integer;
  padding : PChar;
  f : TMemoryStream;
  oldCheckSum, newCheckSum : DWORD;
  ntHeaders : PImageNTHEaders;
  ckOffset : DWORD;
begin
  Encode;                       // Encode the data.

  NTSignature := IMAGE_NT_SIGNATURE;

                                // Write the DOS stub
  s.Write (fDOSHeader, sizeof (fDOSHeader));
  s.CopyFrom (fDOSStub, 0);

                                // Write NT sig and COFF header
  s.Write (NTSignature, sizeof (NTSignature));
  s.Write (fCOFFHeader, sizeof (fCOFFHeader));
  ckOffset := s.Position + Integer (@fOptionalHeader^.CheckSum) - Integer (@fOptionalHeader^);
  s.Write (fOptionalHeader^, fCOFFHeader.SizeOfOptionalHeader);

                                // Write the section headers
  for i := 0 to fSectionList.Count - 1 do
  begin
    section := TImageSection (fSectionList [i]);
    s.Write (section.fSectionHeader, sizeof (section.fSectionHeader))
  end;

  if fCommentSize > 0 then      // Save the 'comment' section.  See 'Decode' for details
    s.Write (fCommentBlock^, fCommentSize);

                                // Write the sections
  padding := Nil;
  paddingLen := 0;
  try
    for i := 0 to fSectionList.Count - 1 do
    begin
                                // Write padding up to file offset of the section
      section := TImageSection (fSectionList [i]);
      paddingSize := section.fSectionHeader.PointerToRawData - DWORD (s.Position);

      if paddingSize > paddingLen then
      begin
        paddingLen := paddingSize + 65536;
        ReallocMem (padding, paddingLen);
        ZeroMemory (padding, paddingLen);
      end;

      if paddingSize > 0 then   // Put our signature at the start of the first
          s.Write (padding^, paddingSize);

                                // Write the section data.
      s.CopyFrom (section.fRawData, 0);

                                // Write data
      with section.fSectionHeader do
        paddingSize := SizeOfRawData - misc.VirtualSize;

                                // Pad data
      if paddingSize > paddingLen then
      begin
        paddingLen := paddingSize + 65536;
        ReallocMem (padding, paddingLen);

⌨️ 快捷键说明

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