int engine_read_message(time_t delay) { fd_set read_set, write_set; struct timeval wt; int nfds, length, i; unsigned int fdflags; int fdtype; void *fdvalue; aClient *cptr; aListener *lptr; engine_get_fdsets(&read_set, &write_set); wt.tv_sec = delay; wt.tv_usec = 0; nfds = select(MAXCONNECTIONS, &read_set, &write_set, NULL, &wt); if (nfds == -1) { if(((errno == EINTR) || (errno == EAGAIN))) return -1; report_error("select %s:%s", &me); sleep(5); return -1; } else if (nfds == 0) return 0; if(delay) NOW = timeofday = time(NULL); for (i = 0; i < MAXCONNECTIONS; i++) { get_fd_info(i, &fdtype, &fdflags, &fdvalue); cptr = NULL; length = -1; if (nfds) { int rr = FD_ISSET(i, &read_set); int rw = FD_ISSET(i, &write_set); if(rr || rw) nfds--; else continue; fdfprintf(stderr, "fd %d: %s%s\n", i, rr ? "read " : "", rw ? "write" : ""); switch(fdtype) { case FDT_NONE: break; case FDT_AUTH: cptr = (aClient *) fdvalue; if (rr) read_authports(cptr); if (rw && cptr->authfd >= 0) send_authports(cptr); check_client_fd(cptr); break; case FDT_LISTENER: lptr = (aListener *) fdvalue; if(rr) accept_connection(lptr); break; case FDT_RESOLVER: do_dns_async(); break; case FDT_CLIENT: cptr = (aClient *) fdvalue; readwrite_client(cptr, rr, rw); break; case FDT_CALLBACKP: { struct fd_callbackp *fdcb = (struct fd_callbackp *) fdvalue; fdcb->rdf = rr; fdcb->wrf = rw; (*fdcb->callback)(fdcb); } break; default: abort(); /* unknown client type? bail! */ } } else break; /* no more fds? break out of the loop */ } /* end of for() loop for testing selected sockets */ return 0; }
int ecfs_exec(char **argv, const char *filename) { int i, ret; ecfs_elf_t *ecfs_desc; siginfo_t siginfo; struct elf_prstatus *prstatus; int prcount; struct user_regs_struct *regs; const char *old_prog = argv[0]; void *fault_address; void *entrypoint, *stack; void (*tramp_code)(void); unsigned long tramp_addr; unsigned long fpreg_addr; pid_t tid[MAX_THREADS]; fd_info_t *fdinfo; if ((ecfs_desc = load_ecfs_file(filename)) == NULL) { printf("error loading file: %s\n", argv[1]); exit(-1); } /* * Convert register set into user_regs_struct for each thread * that was in the process represented by the ecfs file. */ prcount = get_prstatus_structs(ecfs_desc, &prstatus); regs = malloc(prcount * sizeof(struct user_regs_struct)); for (i = 0; i < prcount; i++) memcpy(®s[i], &prstatus[i].pr_reg, sizeof(struct user_regs_struct)); get_siginfo(ecfs_desc, &siginfo); entrypoint = (void *)regs[0].rip; stack = (void *)regs[0].rsp; #if DEBUG printf("[+] Using entry point: %lx\n", entrypoint); printf("[+] Using stack vaddr: %lx\n", stack); #endif do_unmappings(old_prog); /* * load ecfs binary into memory to prepare * for execution. */ ret = load_ecfs_binary(ecfs_desc->mem); if (ret == -1) { fprintf(stderr, "load_ecfs_binary() failed\n"); return -1; } /* * restore file descriptors */ int fdcount = get_fd_info(ecfs_desc, &fdinfo); for (i = 0; i < fdcount; i++) { reload_file_desc(&fdinfo[i]); } /* * get source location of fpregset_t */ elf_fpregset_t *fpregs; ret = get_section_pointer(ecfs_desc, ".fpregset", (uint8_t **)&fpregs); if (ret < 0) { printf("get_section_pointer() failed\n"); exit(-1); } /* * inject code for restoring register state * and setting up trampoline for execution on * entry point. */ tramp_addr = create_reg_loader(®s[0], fpregs, (unsigned long)entrypoint); tramp_code = (void *)tramp_addr; tramp_code(); exit(0); }
int engine_read_message(time_t delay) { static struct pollfd poll_fdarray[MAXCONNECTIONS]; struct pollfd *pfd; long nfds, nbr_pfds; int length, i; unsigned int fdflags; int fdtype; void *fdvalue; aClient *cptr; aListener *lptr; engine_get_pollfds(&pfd, &nbr_pfds); memcpy(poll_fdarray, pfd, sizeof(struct pollfd) * nbr_pfds); nfds = poll(poll_fdarray, nbr_pfds, delay * 1000); if (nfds == -1) { if(((errno == EINTR) || (errno == EAGAIN))) return -1; report_error("poll %s:%s", &me); sleep(5); return -1; } if(delay) NOW = timeofday = time(NULL); for (pfd = poll_fdarray, i = 0; nfds && (i < nbr_pfds); i++, pfd++) { get_fd_info(pfd->fd, &fdtype, &fdflags, &fdvalue); cptr = NULL; length = -1; if (nfds && pfd->revents) { int rr = pfd->revents & (POLLIN|POLLHUP|POLLERR); int rw = pfd->revents & (POLLOUT); fdfprintf(stderr, "fd %d: %s%s\n", pfd->fd, rr ? "read " : "", rw ? "write" : ""); nfds--; switch(fdtype) { case FDT_NONE: break; case FDT_AUTH: cptr = (aClient *) fdvalue; if (rr) read_authports(cptr); if (rw && cptr->authfd >= 0) send_authports(cptr); check_client_fd(cptr); break; case FDT_LISTENER: lptr = (aListener *) fdvalue; if(rr) accept_connection(lptr); break; case FDT_RESOLVER: do_dns_async(); break; case FDT_CLIENT: cptr = (aClient *) fdvalue; readwrite_client(cptr, rr, rw); break; case FDT_CALLBACKP: { struct fd_callbackp *fdcb = (struct fd_callbackp *) fdvalue; fdcb->rdf = rr; fdcb->wrf = rw; (*fdcb->callback)(fdcb); } break; default: abort(); /* unknown client type? bail! */ } } } /* end of for() loop for testing polled sockets */ return 0; }
int engine_read_message(time_t delay) { struct pollfd events[ENGINE_MAX_EVENTS], *pevent; struct dvpoll dopoll; int nfds, i, numloops = 0, eventsfull; unsigned int fdflags, fdevents; int fdtype; void *fdvalue; aClient *cptr; aListener *lptr; dopoll.dp_fds = events; dopoll.dp_nfds = ENGINE_MAX_EVENTS; dopoll.dp_timeout = delay; do { nfds = ioctl(devpoll_id, DP_POLL, &dopoll); if (nfds < 0) { if (errno == EINTR || errno == EAGAIN) return -1; report_error("ioctl(devpoll): %s:%s", &me); sleep(5); return -1; } eventsfull = nfds == ENGINE_MAX_EVENTS; if (delay || numloops) NOW = timeofday = time(NULL); numloops++; for (i = 0, pevent = events; i < nfds; i++, pevent++) { fdevents = (unsigned int)get_fd_internal(pevent->fd); if (pevent->fd != -1) { int rr = (pevent->revents & (POLLIN|POLLHUP|POLLERR)) && (fdevents & (POLLIN|POLLHUP|POLLERR)); int rw = (pevent->revents & POLLOUT) && (fdevents & POLLOUT); get_fd_info(pevent->fd, &fdtype, &fdflags, &fdvalue); switch (fdtype) { case FDT_NONE: break; case FDT_AUTH: cptr = (aClient*)fdvalue; if (rr) read_authports(cptr); if (rw && cptr->authfd >= 0) send_authports(cptr); check_client_fd(cptr); break; case FDT_LISTENER: lptr = (aListener*)fdvalue; if (rr) accept_connection(lptr); break; case FDT_RESOLVER: do_dns_async(); break; case FDT_CLIENT: cptr = (aClient*)fdvalue; readwrite_client(cptr, rr, rw); break; case FDT_CALLBACKP: { struct fd_callbackp *fdcb = (struct fd_callbackp*)fdvalue; fdcb->rdf = rr; fdcb->wrf = rw; (*fdcb->callback)(fdcb); break; } default: abort(); } } } } while (eventsfull && numloops < ENGINE_MAX_LOOPS); return 0; }