82 lines
2.3 KiB
C
82 lines
2.3 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;
|
|
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;
|
|
}
|