diff --git a/src/hiload.c b/src/hiload.c index c4f083d..3397161 100644 --- a/src/hiload.c +++ b/src/hiload.c @@ -21,7 +21,7 @@ typedef struct { } ModuleInfos; typedef struct { - struct sc_array_memreg *memory_regions; + struct sc_array_memreg memory_regions; } HiloadContext; static HiloadContext context = {0}; @@ -267,7 +267,7 @@ int hi_init() { sc_log_set_level("DEBUG"); - if (read_memory_maps_self(context.memory_regions) != HILOAD_OK) { + if (read_memory_maps_self(&context.memory_regions) != HILOAD_OK) { sc_log_error("Could not populate program memory maps.\n"); return HILOAD_FAIL; } diff --git a/src/memory.c b/src/memory.c index bc24b07..39add0f 100644 --- a/src/memory.c +++ b/src/memory.c @@ -4,22 +4,68 @@ #include "logger.h" #include "types.h" -void hi_clear_memreg(struct sc_array_memreg *regions) -{ - MemoryRegions *reg; - sc_array_foreach(regions, *reg) { - - } -} - 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; + return HILOAD_FAIL; + + int i = 0; + + MemoryRegions reg = {0}; + char *strptr = (char *)str_ptr(memory_str); + char *line = strtok(strptr, "\n"); + while (line) { + + if (i >= HI_MEM_REG_MAX) { + sc_array_add(regions, reg); + memset(®, 0, sizeof(reg)); + i = 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_starts[i], + ®.region_ends[i], + perm_str, + ®.offsets[i], + &dev_major, + &dev_minor, + ®.inodes[i], + pathname); + + if (perm_str[0] == 'r') reg.permissions[i] |= HI_MEMORY_READ; + if (perm_str[1] == 'w') reg.permissions[i] |= HI_MEMORY_WRITE; + if (perm_str[2] == 'x') reg.permissions[i] |= HI_MEMORY_EXECUTE; + if (perm_str[3] == 'p') reg.permissions[i] |= HI_MEMORY_PRIVATE; + if (perm_str[3] == 's') reg.permissions[i] |= HI_MEMORY_SHARED; + + // pathname could be empty, so we check for it + if (result >= 8) { + reg.pathnames[i] = strdup(pathname); + } + + i++; + line = strtok(NULL, "\n"); + } + + // clang-format on + sc_array_add(regions, reg); sc_log_debug("Memory Map\n-- /proc/self/maps:\n%s\n", str_ptr(memory_str)); + str_free(memory_str); + return HILOAD_OK; } diff --git a/src/memory.h b/src/memory.h index 77c7f5b..19ab459 100644 --- a/src/memory.h +++ b/src/memory.h @@ -7,30 +7,30 @@ #include -enum MemoryPermissions { +typedef enum { HI_MEMORY_READ = 1 << 0, HI_MEMORY_WRITE = 1 << 1, HI_MEMORY_EXECUTE = 1 << 2, HI_MEMORY_SHARED = 1 << 3, HI_MEMORY_PRIVATE = 1 << 4 -}; +} MemoryPermissions; #define HI_MEM_REG_MAX 256 typedef struct { - void *region_starts[HI_MEM_REG_MAX]; - void *region_end[HI_MEM_REG_MAX]; - u32 region_flags[HI_MEM_REG_MAX]; // enum MemoryPermissions - u32 offset[HI_MEM_REG_MAX]; - str pathname[HI_MEM_REG_MAX]; + uptr region_starts[HI_MEM_REG_MAX]; + uptr region_ends[HI_MEM_REG_MAX]; + uptr offsets[HI_MEM_REG_MAX]; + u64 inodes[HI_MEM_REG_MAX]; + u32 permissions[HI_MEM_REG_MAX]; // enum MemoryPermissions + const char *pathnames[HI_MEM_REG_MAX]; } MemoryRegions; + + sc_array_def(MemoryRegions, memreg); -_Static_assert(sizeof(MemoryRegions) < 1024 * 11, "MemoryRegion size has increased. Fix this assert."); +_Static_assert(sizeof(MemoryRegions) < 1024 * 12, "MemoryRegion size has increased. Fix this assert."); -/* Needed to free the underlying pathnames before clear */ -void hi_clear_memreg(struct sc_array_memreg *regions); - -/* A pointer that can be used to place the memory regions into. If mr isn't cleared, the content will be cleared. */ +/* A pointer that can be used to place the memory regions into. Clears regions before use, but uses the same buffer. */ HiloadResult read_memory_maps_self(struct sc_array_memreg *regions); #endif // MEMORY_H_ diff --git a/src/types.h b/src/types.h index 08c03a1..aa173b6 100644 --- a/src/types.h +++ b/src/types.h @@ -2,6 +2,7 @@ #define TYPES_H_ #include +#include typedef uint8_t u8; typedef uint16_t u16; @@ -14,6 +15,9 @@ typedef int64_t i64; typedef float f32; typedef double f64; +typedef uintptr_t uptr; +typedef ptrdiff_t ptrdiff; + typedef enum { HILOAD_OK = 0, HILOAD_FAIL } HiloadResult; #endif // TYPES_H_