void* safemem_read_pid_to_null(pid_data& pdata, uintptr_t remote_addr) { size_t max_size; char* wptr = safe_mem_allocator.allocate_largest(&max_size); if(!wptr) { return NULL; } for(size_t i = 0; ; ) { uintptr_t a = (remote_addr + i) & (sizeof(long) - 1); errno = 0; long v = ptrace(PTRACE_PEEKDATA, pdata.pid, remote_addr + i - a, NULL); if(errno == EFAULT) { return NULL; } char* vptr = (char*)&v + a; for(size_t ie = i + sizeof(long) - a; i != ie; i++, vptr++) { if(!(wptr[i] = *vptr)) { size_t sz = ((i + 8) & ~0x7); safe_mem_allocator.free(wptr + sz, max_size - sz); pdata.allocations.push_back(std::make_pair(wptr, sz)); return wptr; } else if(i + 1 == max_size) { safe_mem_allocator.free(wptr, max_size); return NULL; } } } }
void safemem_reset(pid_data& pdata) { for(auto i : pdata.allocations) { safe_mem_allocator.free(i.first, i.second); } pdata.allocations.clear(); }