#include "memory.h" #include "array/sc_array.h" #include "files.h" #include "logger.h" #include "types.h" static inline int ptr_in_range(uptr ptr, uptr start, uptr end) { return ptr >= start && ptr <= end; } HiloadResult memory_find_pointer(uptr ptr, struct sc_array_memreg *const regions, size_t *index) { for (size_t i = 0; i < sc_array_size(regions); i++) { uptr start = regions->elems[i].region_start; uptr end = regions->elems[i].region_end; if (ptr_in_range(ptr, start, end)) { if (index) *index = i; sc_log_debug("Pointer match (%p) found in index: %u, range: %p - %p\n", ptr, i, start, end); return HILOAD_OK; } } return HILOAD_FAIL; } HiloadResult read_memory_maps_self(struct sc_array_memreg *regions) { str memory_str = str_null; sc_array_clear(regions); sc_array_init(regions); HiloadResult res = read_stream_to_str(&memory_str, "/proc/self/maps"); if (res == HILOAD_FAIL) return HILOAD_FAIL; char *strptr = (char *)str_ptr(memory_str); char *line = strtok(strptr, "\n"); while (line) { MemoryRegion reg = {0}; char perm_str[5]; u32 dev_major; u32 dev_minor; char pathname[256]; // clang-format off // Example from `cat /proc/self/maps` // 7fa0b66ca000-7fa0b66cc000 rw-p 00033000 fe:02 28063911 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 int result = sscanf(line, "%lx-%lx %4s %lx %x:%x %lu %255s", ®.region_start, ®.region_end, perm_str, ®.offset, &dev_major, &dev_minor, ®.inode, pathname); if (perm_str[0] == 'r') reg.permission |= HI_MEMORY_READ; if (perm_str[1] == 'w') reg.permission |= HI_MEMORY_WRITE; if (perm_str[2] == 'x') reg.permission |= HI_MEMORY_EXECUTE; if (perm_str[3] == 'p') reg.permission |= HI_MEMORY_PRIVATE; if (perm_str[3] == 's') reg.permission |= HI_MEMORY_SHARED; // clang-format on // pathname could be empty, so we check for it if (result >= 8) { reg.pathname = strdup(pathname); } sc_array_add(regions, reg); line = strtok(NULL, "\n"); } str_free(memory_str); return HILOAD_OK; }