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

📄 pefile.pas

📁 这是个反向工程delphi的程序的全部源代码.能分析几乎所有的结构 Revendepro is a program to reverse engineer Delphi program. Reven
💻 PAS
📖 第 1 页 / 共 2 页
字号:
          RL[I].FName[1], Length(RL[I].FName) * 2);
        if PDWord(PChar(DirEntry) + 4)^ and $80000000 = 0 then
        begin
          // DataEntry
          RL[I].FDataOrEntries := deData;
          RL[I].FData := FFileBase + PDWord(BaseEntry + PDWord(DirEntry + 4)^)^;
          RL[I].FDataSize := PInteger(BaseEntry + PDWord(DirEntry +4)^ +4)^;
        end
        else
        begin
          // SubEntries
          RL[I].FDataOrEntries := deEntries;
          FillResources(RL[I].FEntries,
            Integer(BaseEntry + PDWord(DirEntry + 4)^ and $7FFFFFFF));
        end;
        Inc(DirEntry, 8);
      end;
      for I := NameCount to NameCount + IDCount -1 do
      begin
        // Create object
        RL[I] := TPEResource.Create;
        // Name or ID is Name.
        RL[I].FNameOrID := niID;
        // Copy name.
        RL[I].FID := PDWord(DirEntry)^;
        if PDWord(DirEntry+ 4)^ and $80000000 = 0 then
        begin
          // DataEntry
          RL[I].FDataOrEntries := deData;
          RL[I].FData := FFileBase + PDWord(BaseEntry + PDWord(DirEntry + 4)^)^;
          RL[I].FDataSize := PInteger(BaseEntry + PDWord(DirEntry +4)^ +4)^;
        end
        else
        begin
          // SubEntries
          RL[I].FDataOrEntries := deEntries;
          FillResources(RL[I].FEntries,
            Integer(BaseEntry + PDWord(DirEntry + 4)^ and $7FFFFFFF));
        end;
        Inc(DirEntry, 8);
      end;
    end;

  begin
    if NTHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size <> 0 then
    begin
      BaseEntry := FFileBase +
        NTHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
      FillResources(Resources, Integer(BaseEntry));
    end;
  end;

  procedure LoadImports;

  type
    PImage_Import_Entry = ^Image_Import_Entry;
    Image_Import_Entry = record
      Characteristics: Integer;
      TimeDateStamp: Integer;
      MajorVersion: WORD;
      MinorVersion: WORD;
      Name: Integer;
      LookupTable: Integer;
    end;

  var
    ImportEntry: PImage_Import_Entry;
    LookupEntry: PDWord;
  begin
    ImportEntry := PImage_Import_Entry(FFileBase +
      NTHeader^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    // Keep reading import entry until empty entry.
    while ImportEntry^.Name <> 0 do
    begin
      // New Import entry.
      SetLength(Imports, Length(Imports) +1);
      with Imports[High(Imports)] do
      begin
        DLLName := FFileBase + ImportEntry.Name;
        LookupEntry := PDWord(FFileBase + ImportEntry.LookupTable);
        // Keep reading loolup table until empty lookup
        while LookupEntry^ <> 0 do
        begin
          SetLength(Entries, Length(Entries) +1);
          with Entries[High(Entries)] do
          begin
            if (LookupEntry^ and $80000000) <> 0 then
            begin
              NameOrID := niID;
              ID := LookupEntry^ and $7FFFFFFF;
            end
            else
            begin
              NameOrID := niName;
              Name := PChar(FFileBase + LookupEntry^ + 2);
            end;
            PAddress := PChar(LookupEntry);
          end;
          Inc(LookupEntry);
        end;
        Inc(ImportEntry);
      end;
    end;
  end;

var
  J: Integer;
begin
  inherited Create;
  FFileName := FileName;
  FProjectName := ExtractFileName(FileName);
  SetLength(FProjectName, Length(FProjectName) - Length(ExtractFileExt(FProjectName)));

  FFileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
  with FFileStream do
  begin
    // Read new header address.
    Position := 60;
    ReadBuffer(I, 4);
    Position := I + 52;
    ReadBuffer(ImageBase, 4);
    Seek(24, soFromCurrent);
    // Read Image and Header size.
    ReadBuffer(FImageSize, 4);
    ReadBuffer(FHeaderSize, 4);

    // Allocate memory at ImageAddress.
    FFileBase := VirtualAlloc(ImageBase, FImageSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
    if FFileBase = nil then
    begin
      FFileBase := VirtualAlloc(nil, FImageSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
      if FFileBase = nil then
        Error('Couldn''t allocate memory.');
    end;

    // Read Header
    Position := 0;
    ReadBuffer(PPointer(FFileBase)^, FHeaderSize);

    with PImageDosHeader(FFileBase)^ do
    begin
      // Check magic number.
      if not e_magic = IMAGE_DOS_SIGNATURE then Error('unrecognized file format');
      // Load NT Header.
      FNTHeader := PIMAGE_NT_HEADERS(FFileBase + _lfanew);
    end;

    with NTHeader^ do
    begin
      // Check NT Header.
      if Signature <> IMAGE_NT_SIGNATURE then
        Error('Not a PE (WIN32 Executable) file');

      // Save StackCommitSize
      StackCommitSize := OptionalHeader.SizeOfStackCommit;
      // Save StackReserveSize
      StackReserveSize := OptionalHeader.SizeOfStackReserve;
      // Save EntryPoint
      EntryPoint := FFileBase + OptionalHeader.AddressOfEntryPoint;
      // Save Code Size
      CodeSize := OptionalHeader.SizeOfCode;
      // Save Code Address
      Code := FFileBase + OptionalHeader.BaseOfCode;
      // Save Data Size
      DataSize := OptionalHeader.SizeOfInitializedData;
      // Save Data Address
      Data := FFileBase + OptionalHeader.BaseOfData;

      { Read the object from file and save the information }

      // Set the number of Objects
      SetLength(Objects, FileHeader.NumberOfSections);
      // Save the Objects
      for I := 0 to High(Objects) do
      begin
        // Copy the name.
        SetLength(Objects[I].ObjectName, 8);
        Move(OptionalHeader.Objects[I].Name, Objects[I].ObjectName[1], 8);
        SetLength(Objects[I].ObjectName, StrLen(PChar(Objects[I].ObjectName)));
        // Save the physical size.
        Objects[I].PhysicalSize := OptionalHeader.Objects[I].SizeOfRawData;
        Objects[I].VirtualSize := OptionalHeader.Objects[I].Misc.VirtualSize;
        // Save the address (virtual).
        Objects[I].Address := FFileBase + OptionalHeader.Objects[I].VirtualAddress;
        // Read the data to the Address
        Objects[I].PointerToRawData := OptionalHeader.Objects[I].PointerToRawData;
        Position := OptionalHeader.Objects[I].PointerToRawData;
        ReadBuffer(PPointer(Objects[I].Address)^, Objects[I].PhysicalSize);
        // Save the Characteristics.
        Objects[I].Characteristics := OptionalHeader.Objects[I].Characteristics;
      end;

      // Load the BBS
      for J := 0 to High(Objects) -1 do
        if Objects[J].ObjectName = 'BSS' then
        begin
          BSS := Objects[J].Address;
          BSSSize := Objects[J +1].Address - Objects[J].Address;
          Break;
        end;

      // Set IsConsole
      FIsConsole := OptionalHeader.SubSystem = 3;

      Fixups := TFixups.Create(Self);
      Fixups.ApplyFixups;

      LoadResources;
      LoadImports;
    end;
  end;

  PEExports := TpeExportList.Create(Self);
end;

destructor TPEFile.Destroy;

  procedure FreeResources(const AResources: TPEResourceList);
  var
    I: Integer;
  begin
    for I := 0 to High(AResources) do
    begin
      if AResources[I].DataOrEntries = deEntries then
        FreeResources(AResources[I].Entries);
      AResources[I].Free;
    end;
  end;

begin
  FreeResources(Resources);
  PEExports.Free;
  Fixups.Free;
  if FFileBase <> nil then
    VirtualFree(FFileBase, 0, MEM_RELEASE);
  FFileStream.Free;
  inherited Destroy;
end;

procedure TPEFile.Error(S: string);
begin
  raise EPEError.Create(S);
end;

function TPEFile.PhysOffset(Address: PChar): Integer;
var
  I: Integer;
begin
  // Return a address is physical offset in the file, for modifying it.
  if (Address < FileBase) or
     (Address >= Objects[High(Objects)].Address + Objects[High(Objects)].VirtualSize) then
    raise EPEError.CreateFmt(SErrorAddressNotInFile, [Pointer(Address)]);
  // If the address in one of the objects.
  for I := 0 to High(Objects) do
    if (Address >= Objects[I].Address) and (Address < Objects[I].Address + Objects[I].VirtualSize) then
    begin
      // Address must be inside the physical declared part.
      if Address >= Objects[I].Address + Objects[I].PhysicalSize then
        raise EPEError.CreateFmt(SErrorAddressNotInFile, [Pointer(Address)]);
      // Calculate the address.
      Result := Address - Objects[I].Address + Objects[I].PointerToRawData;
      Exit;
    end;
  if Address < PChar(NTHeader) + SizeOf(Windows.IMAGE_NT_HEADERS) +
      Length(Objects) * SizeOf(TImageSectionHeader) then
  begin
    Result := Address - FFileBase;
    Exit;
  end;
  raise EPEError.CreateFmt(SErrorAddressNotInFile, [Pointer(Address)]);
end;

end.

⌨️ 快捷键说明

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