Fixed some issues, added some helper functions.

Fixed some issues with signature scanning (seemed to be a odd bug where offsets were skipped), added ChangeRelocationType to change a relocation type at a specific RVA. Added Address class. Added GetIATOffsets to ImportDirectory, returns begin and end offsets of the IAT.
This commit is contained in:
mike1k
2021-08-04 11:57:54 -05:00
parent b3f6e5cfcb
commit 876b3ca2eb
7 changed files with 254 additions and 7 deletions
+5 -5
View File
@@ -307,7 +307,7 @@ std::vector<std::uint32_t> Image<bitsize>::FindBinarySequence(SectionHeader* s,
std::uint32_t result = 0;
std::uint32_t match_count = 0;
for (std::uint32_t i = start_offset; i <= start_offset + s->GetSizeOfRawData();)
for (std::uint32_t i = start_offset; i <= start_offset + s->GetSizeOfRawData(); ++i)
{
for (int c = 0; c < binary_seq.size();)
{
@@ -337,9 +337,10 @@ std::vector<std::uint32_t> Image<bitsize>::FindBinarySequence(SectionHeader* s,
if (result)
{
offsets.emplace_back(i);
i += match_count - 1;
}
i += std::max<int>(match_count, 1);
match_count = 0;
result = 0;
}
@@ -367,7 +368,7 @@ std::vector<std::pair<std::int32_t, std::uint32_t>> Image<bitsize>::FindBinarySe
std::pair<std::int32_t, std::uint32_t> result{};
std::uint32_t match_count = 0;
for (std::uint32_t i = start_offset; i <= start_offset + s->GetSizeOfRawData();)
for (std::uint32_t i = start_offset; i <= start_offset + s->GetSizeOfRawData(); ++i)
{
for (auto const& seq : binary_seq)
{
@@ -408,8 +409,7 @@ std::vector<std::pair<std::int32_t, std::uint32_t>> Image<bitsize>::FindBinarySe
result = { 0, 0 };
}
i += std::max<int>(match_count, 1);
i += std::max<int>(match_count - 1, 0);
match_count = 0;
}
+17 -1
View File
@@ -482,4 +482,20 @@ void ImportDirectory<bitsize>::TraverseImports(const std::function<void(ModuleIm
descriptor++;
}
}
}
template<unsigned int bitsize>
void ImportDirectory<bitsize>::GetIATOffsets(std::uint32_t& begin, std::uint32_t& end) noexcept
{
//
// Null out.
begin = end = 0;
IMAGE_DATA_DIRECTORY const& iat = m_image->GetPEHeader().GetOptionalHeader().GetDataDirectory(IMAGE_DIRECTORY_ENTRY_IAT);
if (iat.Size == 0)
return;
begin = m_image->GetPEHeader().RvaToOffset(iat.VirtualAddress);
end = begin + iat.Size;
}
+2
View File
@@ -61,6 +61,8 @@ namespace pepp
return (ord & IMPORT_ORDINAL_FLAG_32) != 0;
}
void GetIATOffsets(std::uint32_t& begin, std::uint32_t& end) noexcept;
private:
//! Setup the directory
void _setup(Image<bitsize>* image) {
+1
View File
@@ -11,6 +11,7 @@
#include "misc/NonCopyable.hpp"
#include "misc/ByteVector.hpp"
#include "misc/Concept.hpp"
#include "misc/Address.hpp"
#include "Image.hpp"
#include "PEHeader.hpp"
+28 -1
View File
@@ -44,6 +44,33 @@ std::uint32_t RelocationDirectory<bitsize>::GetRemainingFreeBytes() const
return std::max<std::uint32_t>(m_section->GetVirtualSize() - count, 0);
}
template<unsigned int bitsize>
bool pepp::RelocationDirectory<bitsize>::ChangeRelocationType(std::uint32_t rva, RelocationType type)
{
auto base = m_base;
std::vector<BlockEntry> entries;
while (base->VirtualAddress)
{
int numEntries = GetNumberOfEntries(base);
std::uint16_t* entry = (std::uint16_t*)(base + 1);
for (int i = 0; i != numEntries; i++, entry++)
{
BlockEntry block(base->VirtualAddress, *entry);
if (block.GetRva() == rva)
{
*entry = CraftRelocationBlockEntry(type, block.GetOffset());
return true;
}
}
base = decltype(base)((char*)base + base->SizeOfBlock);
}
return false;
}
template<unsigned int bitsize>
std::vector<BlockEntry> RelocationDirectory<bitsize>::GetBlockEntries(int blockIdx)
{
@@ -68,7 +95,7 @@ std::vector<BlockEntry> RelocationDirectory<bitsize>::GetBlockEntries(int blockI
count++;
}
return std::move(entries);
return entries;
}
template<unsigned int bitsize>
+1
View File
@@ -100,6 +100,7 @@ namespace pepp
int GetNumberOfBlocks() const;
int GetNumberOfEntries(detail::Image_t<>::RelocationBase_t* reloc) const;
std::uint32_t GetRemainingFreeBytes() const;
bool ChangeRelocationType(std::uint32_t rva, RelocationType type);
std::vector<BlockEntry> GetBlockEntries(int blockIdx);
BlockStream CreateBlock(std::uint32_t rva, std::uint32_t num_entries);
+200
View File
@@ -0,0 +1,200 @@
#pragma once
#include "Concept.hpp"
namespace pepp {
template<typename ValueType = std::uintptr_t>
class Address
{
ValueType m_address;
public:
template<typename T>
constexpr Address(T value = 0) noexcept requires pepp::msc::MemoryAddress<T>
: m_address((ValueType)(value))
{
}
constexpr Address(const Address& rhs) = default;
~Address() = default;
Address& operator=(const Address& rhs) noexcept
{
m_address = rhs.m_address;
return *this;
}
constexpr explicit operator std::uintptr_t() const noexcept
{
return m_address;
}
constexpr uintptr_t uintptr() const noexcept
{
return m_address;
}
template<typename C>
C* as_ptr() noexcept requires pepp::msc::MemoryAddress<C*>
{
return reinterpret_cast<C*>(m_address);
}
template<typename C>
C as() noexcept
{
return (C)m_address;
}
template<typename C>
C& deref() noexcept
{
return *reinterpret_cast<C*>(m_address);
}
/*
*! Comparison operators
*/
constexpr bool operator==(const Address& rhs) const noexcept
{
return m_address == rhs.m_address;
}
constexpr bool operator!=(const Address& rhs) const noexcept
{
return m_address != rhs.m_address;
}
constexpr bool operator>=(const Address& rhs) const noexcept
{
return m_address >= rhs.m_address;
}
constexpr bool operator<=(const Address& rhs) const noexcept
{
return m_address <= rhs.m_address;
}
constexpr bool operator>(const Address& rhs) const noexcept
{
return m_address > rhs.m_address;
}
constexpr bool operator<(const Address& rhs) const noexcept
{
return m_address < rhs.m_address;
}
/*
/! Arithmetic operators
*/
constexpr Address operator+(const Address& rhs) const noexcept
{
return m_address + rhs.m_address;
}
constexpr Address operator-(const Address& rhs) const noexcept
{
return m_address - rhs.m_address;
}
constexpr Address operator*(const Address& rhs) const noexcept
{
return m_address * rhs.m_address;
}
constexpr Address operator/(const Address& rhs) const noexcept
{
return m_address / rhs.m_address;
}
/*
/!
*/
constexpr Address& operator+=(const Address& rhs) noexcept
{
m_address += rhs.m_address;
return *this;
}
constexpr Address& operator-=(const Address& rhs) noexcept
{
m_address -= rhs.m_address;
return *this;
}
constexpr Address& operator*=(const Address& rhs) noexcept
{
m_address *= rhs.m_address;
return *this;
}
/*
/! Bitwise operators
*/
constexpr Address operator>>(const Address& rhs) const noexcept
{
return m_address >> rhs.m_address;
}
constexpr Address operator<<(const Address& rhs) const noexcept
{
return m_address << rhs.m_address;
}
constexpr Address operator^(const Address& rhs) const noexcept
{
return m_address ^ rhs.m_address;
}
constexpr Address operator&(const Address& rhs) const noexcept
{
return m_address & rhs.m_address;
}
constexpr Address operator|(const Address& rhs) const noexcept
{
return m_address | rhs.m_address;
}
/*
/!
*/
constexpr Address& operator>>=(const Address& rhs) noexcept
{
m_address >>= rhs.m_address;
return *this;
}
constexpr Address& operator<<=(const Address& rhs) noexcept
{
m_address <<= rhs.m_address;
return *this;
}
constexpr Address& operator^=(const Address& rhs) noexcept
{
m_address ^= rhs.m_address;
return *this;
}
constexpr Address& operator&=(const Address& rhs) noexcept
{
m_address &= rhs.m_address;
return *this;
}
constexpr Address& operator|=(const Address& rhs) noexcept
{
m_address |= rhs.m_address;
return *this;
}
};
}