mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
Revamp POSIX syscalls readv / writev
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user