| 153 | } |
| 154 | |
| 155 | bool readMemory_impl(uint64_t addr, unsigned byteSize, uint64_t& value) { |
| 156 | // Guard against buffer overflow: memcpy into uint64_t is only safe for |
| 157 | // reads up to 8 bytes. Wider loads (SSE/AVX 128/256/512-bit) must not |
| 158 | // reach this path — they require vector-aware memory handling. |
| 159 | if (byteSize > sizeof(uint64_t)) { |
| 160 | fprintf(stderr, "readMemory: wide load rejected (byteSize=%u > 8)\n", byteSize); |
| 161 | return 0; |
| 162 | } |
| 163 | uint64_t mappedAddr = address_to_mapped_address(addr); |
| 164 | if (mappedAddr > 0) { |
| 165 | uint64_t tempValue = 0; |
| 166 | std::memcpy(&tempValue, reinterpret_cast<const void*>(mappedAddr), |
| 167 | byteSize); |
| 168 | value = tempValue; |
| 169 | return 1; |
| 170 | } |
| 171 | |
| 172 | // Handle zero-initialized virtual tails (BSS) and raw->BSS boundary reads. |
| 173 | uint64_t rva64 = addr - imageBase; |
| 174 | if (rva64 > UINT32_MAX) |
| 175 | return 0; |
| 176 | uint32_t rva = static_cast<uint32_t>(rva64); |
| 177 | |
| 178 | auto it = |
| 179 | std::upper_bound(sections.begin(), sections.end(), rva, |
| 180 | [](uint32_t val, const win::section_header_t& s) { |
| 181 | return val < s.virtual_address; |
| 182 | }); |
| 183 | if (it == sections.begin()) |
| 184 | return 0; |
| 185 | --it; |
| 186 | |
| 187 | if (rva >= it->virtual_address + it->virtual_size) |
| 188 | return 0; |
| 189 | |
| 190 | uint32_t offset_in_section = rva - it->virtual_address; |
| 191 | if (offset_in_section + byteSize > it->virtual_size) |
| 192 | return 0; |
| 193 | |
| 194 | uint64_t tempValue = 0; |
| 195 | if (offset_in_section < it->size_raw_data) { |
| 196 | uint32_t rawAvailable = |
| 197 | std::min<uint32_t>(byteSize, it->size_raw_data - offset_in_section); |
| 198 | std::memcpy(&tempValue, |
| 199 | reinterpret_cast<const void*>(FileBase + it->ptr_raw_data + |
| 200 | offset_in_section), |
| 201 | rawAvailable); |
| 202 | } |
| 203 | |
| 204 | value = tempValue; |
| 205 | return 1; |
| 206 | } |
| 207 | |
| 208 | const char* getName_impl(uint64_t offset) { |
| 209 | auto rvaOffset = RvaToFileOffset(offset); |
no test coverage detected