Skip to content

Commit b6e5662

Browse files
committed
Add module::for_each_section
1 parent 130664b commit b6e5662

3 files changed

Lines changed: 33 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ Below is a summary of the current support for libhat's platform-dependent APIs:
115115
| `hp::is_executable` ||| ||
116116
| `hp::module::get_module_data` ||| ||
117117
| `hp::module::get_section_data` || | | |
118+
| `hp::module::for_each_section` || | | |
118119
| `hp::module::for_each_segment` |||||
119120

120121
## Quick start

include/libhat/process.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ LIBHAT_EXPORT namespace hat::process {
2828
/// Returns the memory region for a named section
2929
[[nodiscard]] std::span<std::byte> get_section_data(std::string_view name) const;
3030

31+
/// Invokes the callback for each named linker section defined by this module as long as it returns true. The
32+
/// returned byte range is not guaranteed to have page aligned begin and end addresses.
33+
void for_each_section(const std::function<bool(std::string_view name, std::span<std::byte>, hat::protection)>& callback) const;
34+
3135
/// Invokes the callback for each memory segment defined by this module as long as it returns true. Depending on
3236
/// the platform, a segment may be represented by multiple linker sections. The returned byte range is not
3337
/// guaranteed to have page aligned begin and end addresses.

src/os/win32/Process.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ namespace hat::process {
126126
return {scanBytes, sizeOfImage};
127127
}
128128

129-
std::span<std::byte> hat::process::module::get_section_data(const std::string_view name) const {
130-
auto* bytes = reinterpret_cast<std::byte*>(this->address());
129+
std::span<std::byte> module::get_section_data(const std::string_view name) const {
131130
const auto& ntHeaders = getNTHeaders(*this);
132131

133132
const auto* sectionHeader = IMAGE_FIRST_SECTION(&ntHeaders);
@@ -138,15 +137,40 @@ namespace hat::process {
138137
};
139138
if (sectionName == name) {
140139
return {
141-
bytes + sectionHeader->VirtualAddress,
140+
reinterpret_cast<std::byte*>(this->address() + sectionHeader->VirtualAddress),
142141
static_cast<size_t>(sectionHeader->Misc.VirtualSize)
143142
};
144143
}
145144
}
146145
return {};
147146
}
148147

149-
void hat::process::module::for_each_segment(const std::function<bool(std::span<std::byte>, hat::protection)>& callback) const {
148+
void module::for_each_section(const std::function<bool(std::string_view, std::span<std::byte>, hat::protection)>& callback) const {
149+
const auto& ntHeaders = getNTHeaders(*this);
150+
151+
const auto* sectionHeader = IMAGE_FIRST_SECTION(&ntHeaders);
152+
for (WORD i = 0; i < ntHeaders.FileHeader.NumberOfSections; i++, sectionHeader++) {
153+
const std::string_view name{
154+
reinterpret_cast<const char*>(sectionHeader->Name),
155+
strnlen_s(reinterpret_cast<const char*>(sectionHeader->Name), IMAGE_SIZEOF_SHORT_NAME)
156+
};
157+
const std::span data{
158+
reinterpret_cast<std::byte*>(this->address() + sectionHeader->VirtualAddress),
159+
sectionHeader->Misc.VirtualSize
160+
};
161+
162+
hat::protection prot{};
163+
if (sectionHeader->Characteristics & IMAGE_SCN_MEM_READ) prot |= hat::protection::Read;
164+
if (sectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) prot |= hat::protection::Write;
165+
if (sectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) prot |= hat::protection::Execute;
166+
167+
if (!callback(name, data, prot)) {
168+
break;
169+
}
170+
}
171+
}
172+
173+
void module::for_each_segment(const std::function<bool(std::span<std::byte>, hat::protection)>& callback) const {
150174
const auto& ntHeaders = getNTHeaders(*this);
151175

152176
const auto* sectionHeader = IMAGE_FIRST_SECTION(&ntHeaders);

0 commit comments

Comments
 (0)