87 lines
2.5 KiB
C
87 lines
2.5 KiB
C
#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;
|
|
// we assume a sorted region by start address, so we can do a quick discard
|
|
// here. very useful for relative vs absolute address checks
|
|
if (ptr < start)
|
|
return HILOAD_FAIL;
|
|
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) {
|
|
sc_array_clear(regions);
|
|
sc_array_init(regions);
|
|
|
|
const char* maps_str = hi_file_to_str_dyn("/proc/self/maps");
|
|
if (!maps_str)
|
|
return HILOAD_FAIL;
|
|
|
|
sc_log_debug("/proc/self/maps:\n%s", maps_str);
|
|
|
|
char *strptr = (char *)maps_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");
|
|
}
|
|
|
|
free((void*)maps_str);
|
|
|
|
return HILOAD_OK;
|
|
}
|