def ptr2struct(z, addr, struct_class): """ Returns an instance of struct_class read starting from addr """ data = z.memory.read(addr, ctypes.sizeof(struct_class)) instance = struct_class() str2struct(instance, bytes(data)) return instance
def _parse_sockaddr(p, addr, size): class SOCKADDR(ctypes.Structure): _fields_ = [ ("sa_family", ctypes.c_ushort), ("sa_addr", ctypes.c_char * 14), ] sockaddr = SOCKADDR() str2struct(sockaddr, bytes(p.memory.read(addr, size)))
def _parse_sockaddr_in(p, addr, size): class SOCKADDR_IN(ctypes.Structure): _fields_ = [ ("sin_family", ctypes.c_ushort), ("sin_port", ctypes.c_ushort), ("sin_addr", ctypes.c_uint32), ("sin_zero", ctypes.c_char * 8), ] sockaddr_in = SOCKADDR_IN() str2struct(sockaddr_in, bytes(p.memory.read(addr, size)))
def readstruct(self, addr: int, obj: ctypes.Structure) -> ctypes.Structure: """ Reads a ctypes structure from memory. Args: addr: Address in memory to begin reading structure from. obj: An instance of the structure to create from memory. Returns: Instance of structure read from memory. """ data = self.emu.mem_read(addr, ctypes.sizeof(obj)) util.str2struct(obj, data) return obj
def get_host_and_port(domain, struct_bytes): host = "255.255.255.255" port = 65536 if len(struct_bytes) == 0: return (None, None) if domain == SocketFamily.AF_INET: s_in = SOCKADDR_IN() zelos_util.str2struct(s_in, bytes(struct_bytes)) host = _bytes_to_host(s_in.sin_addr, domain) port = _bytes_to_port(s_in.sin_port) elif domain == SocketFamily.AF_INET6: s_in6 = SOCKADDR_IN6() zelos_util.str2struct(s_in6, bytes(struct_bytes)) host = _bytes_to_host(s_in6.sin6_addr, domain) port = _bytes_to_port(s_in6.sin6_port) return (host, port)
def sys_poll(sm, p): args = sm.get_args([("struct pollfd *", "fds"), ("nfds_t", "nfds"), ("int", "timeout")]) # parse the file descriptors of interest sz = ctypes.sizeof(POLLFD()) fds = {} for i in range(args.nfds): pollfd = POLLFD() fd_addr = args.fds + i * sz pollfd_data = p.memory.read(fd_addr, sz) str2struct(pollfd, bytes(pollfd_data)) fds[fd_addr] = pollfd fds_poll = [(v.fd, v.events) for k, v in fds.items()] e = ", ".join([f"fd={x[0]:x} events={repr(POLL(x[1]))}" for x in fds_poll]) sm.print("polled_fds: " + e) revents = sm.z.network.select.poll(fds_poll, timeout=0.1) e = ", ".join([f"fd={x[0]:x} events={repr(POLL(x[1]))}" for x in revents]) sm.print("signaled_fds: " + e) # commit pollfd struct changes ready_fds = 0 for i in range(len(fds_poll)): revent = revents[i][1] if revent >= 0: fd_addr = args.fds + i * sz v = fds[fd_addr] v.revents = revent pollfd_data = struct2str(v) p.memory.write(fd_addr, struct2str(v)) ready_fds += 1 return ready_fds