current commit
260929.11 · deps: update lief to 1.0.0
/* Copyright 2017 - 2026 R. Thomas
 * Copyright 2017 - 2026 Quarkslab
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "LIEF/PE/Relocation.hpp"
#include "LIEF/PE/RelocationEntry.hpp"
#include "LIEF/BinaryStream/BinaryStream.hpp"
#include "LIEF/BinaryStream/SpanStream.hpp"
#include "LIEF/PE/LoadConfigurations/DynamicRelocation/DynamicRelocationV1.hpp"
#include "LIEF/PE/LoadConfigurations/DynamicRelocation/FunctionOverride.hpp"

#include "PE/Structures.hpp"

#include "logging.hpp"
#include "internal_utils.hpp"

namespace LIEF::PE {

template<class PE_T>
std::unique_ptr<DynamicRelocationV1>
    DynamicRelocationV1::parse(Parser& ctx, BinaryStream& strm) {
  using ptr_t = typename PE_T::uint;
  // typedef struct _IMAGE_DYNAMIC_RELOCATION32 {
  //     DWORD      Symbol;
  //     DWORD      BaseRelocSize;
  // //  IMAGE_BASE_RELOCATION BaseRelocations[0];
  // } IMAGE_DYNAMIC_RELOCATION32, *PIMAGE_DYNAMIC_RELOCATION32;
  //
  // typedef struct _IMAGE_DYNAMIC_RELOCATION64 {
  //     ULONGLONG  Symbol;
  //     DWORD      BaseRelocSize;
  // //  IMAGE_BASE_RELOCATION BaseRelocations[0];
  // } IMAGE_DYNAMIC_RELOCATION64, *PIMAGE_DYNAMIC_RELOCATION64;
  auto Symbol = strm.read<ptr_t>();
  if (!Symbol) {
    LIEF_DEBUG("Error: {}:{}", __FUNCTION__, __LINE__);
    return nullptr;
  }
  auto BaseRelocSize = strm.read<uint32_t>();
  if (!BaseRelocSize) {
    LIEF_DEBUG("Error: {}:{}", __FUNCTION__, __LINE__);
    return nullptr;
  }

  auto dyn_reloc = std::make_unique<DynamicRelocationV1>();
  dyn_reloc->symbol(*Symbol);

  LIEF_DEBUG("  Symbol={}, BaseRelocSize={}", *Symbol, *BaseRelocSize);

  std::vector<uint8_t> buffer;
  if (!strm.read_data(buffer, *BaseRelocSize)) {
    LIEF_DEBUG("Error: {}: {}", __FUNCTION__, __LINE__);
    return dyn_reloc;
  }

  SpanStream payload_strm(buffer);
  if (!DynamicFixup::parse(ctx, payload_strm, *dyn_reloc)) {
    LIEF_WARN("Dynamic relocation failed to parse fixup (Symbol={:#018x})",
              dyn_reloc->symbol());
  }
  return dyn_reloc;
}

std::string DynamicRelocationV1::to_string() const {
  std::ostringstream oss;
  oss << "Dynamic Value Relocation Table (version: 1)\n";
  if (symbol() < IMAGE_DYNAMIC_RELOCATION::_RELOC_LAST_ENTRY) {
    oss << fmt::format("Symbol VA: {:#018x} ({})\n", symbol(),
                       PE::to_string((IMAGE_DYNAMIC_RELOCATION)symbol()));
  } else {
    oss << fmt::format("Symbol VA: {:#018x}\n", symbol());
  }

  if (const DynamicFixup* F = fixups()) {
    oss << F->to_string();
  }
  return oss.str();
}

template std::unique_ptr<DynamicRelocationV1>
    DynamicRelocationV1::parse<details::PE32>(Parser& ctx, BinaryStream&);

template std::unique_ptr<DynamicRelocationV1>
    DynamicRelocationV1::parse<details::PE64>(Parser& ctx, BinaryStream&);
}