Merge pull request #145 from orange-cpp/feature/macho_improvement

Feature/macho improvement
This commit is contained in:
2026-02-04 19:27:44 +03:00
committed by GitHub

View File

@@ -22,6 +22,7 @@ namespace
constexpr std::uint32_t lc_segment = 0x1; constexpr std::uint32_t lc_segment = 0x1;
constexpr std::uint32_t lc_segment_64 = 0x19; constexpr std::uint32_t lc_segment_64 = 0x19;
// ReSharper disable CppDeclaratorNeverUsed
// Mach-O header for 32-bit // Mach-O header for 32-bit
struct MachHeader32 final struct MachHeader32 final
{ {
@@ -118,7 +119,7 @@ namespace
std::uint32_t reserved2; std::uint32_t reserved2;
std::uint32_t reserved3; std::uint32_t reserved3;
}; };
// ReSharper enable CppDeclaratorNeverUsed
#pragma pack(pop) #pragma pack(pop)
enum class MachOArch : std::int8_t enum class MachOArch : std::int8_t
@@ -183,13 +184,21 @@ namespace
if (!file.read(reinterpret_cast<char*>(&lc), sizeof(lc))) [[unlikely]] if (!file.read(reinterpret_cast<char*>(&lc), sizeof(lc))) [[unlikely]]
return std::nullopt; return std::nullopt;
if (lc.cmd == segment_cmd) if (lc.cmd != segment_cmd)
{ {
cmd_offset += static_cast<std::streamoff>(lc.cmdsize);
continue;
}
SegmentType segment{}; SegmentType segment{};
file.seekg(cmd_offset, std::ios_base::beg); file.seekg(cmd_offset, std::ios_base::beg);
if (!file.read(reinterpret_cast<char*>(&segment), sizeof(segment))) [[unlikely]] if (!file.read(reinterpret_cast<char*>(&segment), sizeof(segment))) [[unlikely]]
return std::nullopt; return std::nullopt;
if (!segment.nsects)
{
cmd_offset += static_cast<std::streamoff>(lc.cmdsize);
continue;
}
std::streamoff sect_offset = cmd_offset + static_cast<std::streamoff>(sizeof(segment)); std::streamoff sect_offset = cmd_offset + static_cast<std::streamoff>(sizeof(segment));
for (std::uint32_t j = 0; j < segment.nsects; ++j) for (std::uint32_t j = 0; j < segment.nsects; ++j)
@@ -199,26 +208,24 @@ namespace
if (!file.read(reinterpret_cast<char*>(&section), sizeof(section))) [[unlikely]] if (!file.read(reinterpret_cast<char*>(&section), sizeof(section))) [[unlikely]]
return std::nullopt; return std::nullopt;
if (get_section_name(section.sectname) == section_name) if (get_section_name(section.sectname) != section_name)
{ {
sect_offset += static_cast<std::streamoff>(sizeof(section));
continue;
}
ExtractedSection out; ExtractedSection out;
out.virtual_base_addr = static_cast<std::uintptr_t>(section.addr); out.virtual_base_addr = static_cast<std::uintptr_t>(section.addr);
out.raw_base_addr = static_cast<std::uintptr_t>(section.offset); out.raw_base_addr = static_cast<std::uintptr_t>(section.offset);
out.data.resize(static_cast<std::size_t>(section.size)); out.data.resize(static_cast<std::size_t>(section.size));
file.seekg(static_cast<std::streamoff>(section.offset), std::ios_base::beg); file.seekg(static_cast<std::streamoff>(section.offset), std::ios_base::beg);
if (!file.read(reinterpret_cast<char*>(out.data.data()), if (!file.read(reinterpret_cast<char*>(out.data.data()), static_cast<std::streamsize>(out.data.size())))
static_cast<std::streamsize>(out.data.size()))) [[unlikely]] [[unlikely]]
return std::nullopt; return std::nullopt;
return out; return out;
} }
sect_offset += static_cast<std::streamoff>(sizeof(section));
}
}
cmd_offset += static_cast<std::streamoff>(lc.cmdsize);
} }
return std::nullopt; return std::nullopt;
@@ -243,7 +250,6 @@ namespace
if (arch.value() == MachOArch::x64) if (arch.value() == MachOArch::x64)
return extract_section_impl<MachHeader64, SegmentCommand64, Section64, lc_segment_64>(file, section_name); return extract_section_impl<MachHeader64, SegmentCommand64, Section64, lc_segment_64>(file, section_name);
else
return extract_section_impl<MachHeader32, SegmentCommand32, Section32, lc_segment>(file, section_name); return extract_section_impl<MachHeader32, SegmentCommand32, Section32, lc_segment>(file, section_name);
} }
@@ -259,8 +265,11 @@ namespace
{ {
const auto* lc = reinterpret_cast<const LoadCommand*>(base + cmd_offset); const auto* lc = reinterpret_cast<const LoadCommand*>(base + cmd_offset);
if (lc->cmd == segment_cmd) if (lc->cmd != segment_cmd)
{ {
cmd_offset += lc->cmdsize;
continue;
}
const auto* segment = reinterpret_cast<const SegmentType*>(base + cmd_offset); const auto* segment = reinterpret_cast<const SegmentType*>(base + cmd_offset);
std::size_t sect_offset = cmd_offset + sizeof(SegmentType); std::size_t sect_offset = cmd_offset + sizeof(SegmentType);
@@ -268,23 +277,19 @@ namespace
{ {
const auto* section = reinterpret_cast<const SectionType*>(base + sect_offset); const auto* section = reinterpret_cast<const SectionType*>(base + sect_offset);
if (get_section_name(section->sectname) == target_section_name && section->size > 0) if (get_section_name(section->sectname) != target_section_name && section->size > 0)
{ {
sect_offset += sizeof(SectionType);
continue;
}
const auto* section_begin = base + static_cast<std::size_t>(section->addr); const auto* section_begin = base + static_cast<std::size_t>(section->addr);
const auto* section_end = section_begin + static_cast<std::size_t>(section->size); const auto* section_end = section_begin + static_cast<std::size_t>(section->size);
const auto scan_result = const auto scan_result = omath::PatternScanner::scan_for_pattern(section_begin, section_end, pattern);
omath::PatternScanner::scan_for_pattern(section_begin, section_end, pattern);
if (scan_result != section_end) if (scan_result != section_end)
return reinterpret_cast<std::uintptr_t>(scan_result); return reinterpret_cast<std::uintptr_t>(scan_result);
} }
sect_offset += sizeof(SectionType);
}
}
cmd_offset += lc->cmdsize;
} }
return std::nullopt; return std::nullopt;
@@ -309,8 +314,8 @@ namespace omath
std::memcpy(&magic, base, sizeof(magic)); std::memcpy(&magic, base, sizeof(magic));
if (magic == mh_magic_64 || magic == mh_cigam_64) if (magic == mh_magic_64 || magic == mh_cigam_64)
return scan_in_module_impl<MachHeader64, SegmentCommand64, Section64, lc_segment_64>( return scan_in_module_impl<MachHeader64, SegmentCommand64, Section64, lc_segment_64>(base, pattern,
base, pattern, target_section_name); target_section_name);
if (magic == mh_magic_32 || magic == mh_cigam_32) if (magic == mh_magic_32 || magic == mh_cigam_32)
return scan_in_module_impl<MachHeader32, SegmentCommand32, Section32, lc_segment>(base, pattern, return scan_in_module_impl<MachHeader32, SegmentCommand32, Section32, lc_segment>(base, pattern,