Revamp POSIX syscalls readv / writev

This commit is contained in:
elicn
2024-02-04 20:03:43 +02:00
parent 68558df727
commit b8ad3ebed5
+52 -33
View File
@@ -3,42 +3,61 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
from qiling import Qiling
from __future__ import annotations
from typing import TYPE_CHECKING, Iterator, Tuple
def ql_syscall_writev(ql: Qiling, fd: int, vec: int, vlen: int):
regreturn = 0
size_t_len = ql.arch.pointersize
iov = ql.mem.read(vec, vlen * size_t_len * 2)
ql.log.debug('writev() CONTENT:')
for i in range(vlen):
addr = ql.unpack(iov[i * size_t_len * 2 : i * size_t_len * 2 + size_t_len])
l = ql.unpack(iov[i * size_t_len * 2 + size_t_len : i * size_t_len * 2 + size_t_len * 2])
regreturn += l
buf = ql.mem.read(addr, l)
ql.log.debug(f'{bytes(buf)}')
if hasattr(ql.os.fd[fd], 'write'):
ql.os.fd[fd].write(buf)
return regreturn
from qiling.os.posix.structs import make_iovec
def ql_syscall_readv(ql: Qiling, fd: int, vec: int, vlen: int):
regreturn = 0
size_t_len = ql.arch.pointersize
iov = ql.mem.read(vec, vlen * size_t_len * 2)
ql.log.debug('readv() CONTENT:')
if TYPE_CHECKING:
from qiling import Qiling
for i in range(vlen):
addr = ql.unpack(iov[i * size_t_len * 2 : i * size_t_len * 2 + size_t_len])
l = ql.unpack(iov[i * size_t_len * 2 + size_t_len : i * size_t_len * 2 + size_t_len * 2])
regreturn += l
if hasattr(ql.os.fd[fd], 'read'):
data = ql.os.fd[fd].read(l)
ql.log.debug(f'{data!r}')
ql.mem.write(addr, data)
def __iter_iovec_array(ql: Qiling, base: int, count: int) -> Iterator[Tuple[int, int]]:
"""Iterate over an iovec array, yielding one iovec's fields at a time.
"""
return regreturn
iovec = make_iovec(ql.arch.bits, ql.arch.endian)
for i in range(count):
obj = iovec.load_from(ql.mem, base + i * iovec.sizeof())
yield (obj.iov_base, obj.iov_len)
def ql_syscall_writev(ql: Qiling, fd: int, iov: int, iovcnt: int):
ret = 0
if hasattr(ql.os.fd[fd], 'write'):
ql.log.debug('writev CONTENT:')
for iov_base, iov_len in __iter_iovec_array(ql, iov, iovcnt):
data = ql.mem.read(iov_base, iov_len)
ql.log.debug(f' {iov_base = :#x}, {iov_len = :#x} : {bytes(data)}')
ql.os.fd[fd].write(data)
ret += len(data)
else:
ql.log.debug('writev: destination fd is not writeable, no bytes were written')
return ret
def ql_syscall_readv(ql: Qiling, fd: int, iov: int, iovcnt: int):
ret = 0
if hasattr(ql.os.fd[fd], 'read'):
ql.log.debug('readv CONTENT:')
for iov_base, iov_len in __iter_iovec_array(ql, iov, iovcnt):
data = ql.os.fd[fd].read(iov_len)
ql.log.debug(f' {iov_base = :#x}, {iov_len = :#x} : {bytes(data)}')
ql.mem.write(iov_base, data)
ret += len(data)
else:
ql.log.debug('readv: source fd is not readable, no bytes were read')
return ret