Ejemplo n.º 1
0
def open_queue(name, create=False, consume=False):
    """Open a message queue via a context manager

    The message queue will automatically be closed when the
    context ends. The message queue may also optionally be
    created and/or consumed. If the "consume" flag is True,
    the message queue will be unlinked as well when the context
    ends.

    Args:
        name (str): the name of the message queue
        create (bool): whether to create the message queue or try
                       to open a pre-existing one.
        consume (bool): whether or not to unlink the message queue
                        when the context ends.

    Yields:
        posix_ipc.MessageQueue: the message queue
    """
    flags = 0
    if create:
        flags = posix_ipc.O_CREX

    queue = MessageQueue(name, flags=flags)
    try:
        yield queue
    finally:
        queue.close()
        if consume:
            queue.unlink()
Ejemplo n.º 2
0
def pi(n):
    pids = []
    unit = n / 10
    q = Queue("/pi", flags=os.O_CREAT)
    for i in range(10):
        mink = unit * i
        maxk = mink + unit
        pid = os.fork()
        if pid > 0:
            pids.append(pid)
        else:
            s = slice(mink, maxk)
            q.send(str(s))
            q.close()
            sys.exit(0)
    sums = []
    for pid in pids:
        sums.append(float(q.receive()[0]))
        os.waitpid(pid, 0)
    q.close()
    q.unlink()
    return math.sqrt(sum(sums) * 8)
Ejemplo n.º 3
0
class RemoteMemoryProtocol(object):
    """
    This class listens to memoryforward requests and lifts them to avatar
    messages. Likewise it can be directed to emit memoryforward-response
    messages

    :param rx_queue_name: Name of the queue for receiving
    :param tx_queue_name: Name of the queue for sending
    :param avatar_queue:  Queue to dispatch received requests to
    :param origin:        Reference to the Target utilizing this protocol

    """
    def __init__(self,
                 rx_queue_name,
                 tx_queue_name,
                 avatar_queue,
                 origin=None):
        self._rx_queue = None
        self._tx_queue = None
        self._rx_listener = None

        self.rx_queue_name = rx_queue_name
        self.tx_queue_name = tx_queue_name
        self._avatar_queue = avatar_queue
        self._origin = origin

        self.log = logging.getLogger('%s.%s' %
                                     (origin.log.name, self.__class__.__name__)
                                     ) if origin else \
            logging.getLogger(self.__class__.__name__)

    def connect(self):
        """
        Connect to the message queues for remote memory

        :return True on success, else False
        """
        try:
            self._rx_queue = MessageQueue(self.rx_queue_name,
                                          flags=O_RDONLY,
                                          read=True,
                                          write=False)
        except Exception as e:
            self.log.error("Unable to create rx_queue: %s" % e)
            return False

        try:
            self._tx_queue = MessageQueue(self.tx_queue_name,
                                          flags=O_WRONLY,
                                          read=False,
                                          write=True)
        except Exception as e:
            self.log.error("Unable to create tx_queue: %s" % e)
            self._rx_queue.close()
            return False
        self._rx_listener = RemoteMemoryRequestListener(
            self._rx_queue, self._avatar_queue, self._origin)
        self._rx_listener.daemon = True
        self._rx_listener.start()
        self.log.info("Successfully connected rmp")
        return True

    def __del__(self):
        self.shutdown()

    def shutdown(self):
        if self._rx_listener:
            self._rx_listener.stop()
            self._rx_listener = None
        if self._rx_queue:
            try:
                self._rx_queue.unlink()
                self._rx_queue.close()
                self._rx_queue = None
            except ExistentialError:
                self.log.warning("Tried to close/unlink non existent rx_queue")
        if self._tx_queue:
            try:
                self._tx_queue.unlink()
                self._tx_queue.close()
                self._tx_queue = None
            except ExistentialError:
                self.log.warning("Tried to close/unlink non existent tx_queue")

    def send_response(self, id, value, success):
        response = RemoteMemoryResp(id, value, success)
        try:
            self._tx_queue.send(response)
            self.log.debug("Send RemoteMemoryResponse with id %d, %x" %
                           (id, value))
            return True
        except Exception as e:
            self.log.error("Unable to send response: %s" % e)
            return False
Ejemplo n.º 4
0
class ARMV7MInterruptProtocol(Thread):
    """
    This protocol has two purposes: 
        a) injecting interrupts into an analysis target
        b) extracting interrupt exits and putting them into the avatar queue
    (b) is necessary in cases where two targets need to be synched on the
        interrupts.
        The way a v7m-nvic implements interrupt return is to put a magic value
        into $pc, and the hardware does the actual magic of popping from the
        interrupt stack and restoring the context. 
        However, the magic value defines the type of the interrupt return,
        and is hence synchronized on interrupt exit, alongside with the
        interrupt number
    :param origin:        Reference to the Target utilizing this protocol
    :param rx_queue_name: Name of the queue for receiving
    :param tx_queue_name: Name of the queue for sending
    """
    def __init__(self, origin, rx_queue_name, tx_queue_name):
        super(self.__class__, self).__init__()
        self._rx_queue_name = rx_queue_name
        self._tx_queue_name = tx_queue_name
        self._rx_queue = None
        self._tx_queue = None
        self._avatar_queue = origin.avatar.queue
        self._origin = origin
        self._close = Event()
        self._closed = Event()
        self._close.clear()
        self._closed.clear()
        self.log = logging.getLogger('%s.%s' %
                                     (origin.log.name, self.__class__.__name__)
                                     ) if origin else \
            logging.getLogger(self.__class__.__name__)

    def run(self):
        while True:
            if self._close.is_set():
                break

            request = None
            try:
                request = self._rx_queue.receive(0.5)
            except:
                continue

            req_struct = V7MRemoteInterruptNotification.from_buffer_copy(
                request[0])

            if RINOperation(req_struct.operation) == RINOperation.ENTER:
                msg = RemoteInterruptEnterMessage(self._origin, req_struct.id,
                                                  req_struct.num_irq)
            elif RINOperation(req_struct.operation) == RINOperation.EXIT:
                msg = RemoteInterruptExitMessage(self._origin, req_struct.id,
                                                 req_struct.type,
                                                 req_struct.num_irq)
                self.log.debug(
                    "Received an InterruptExitRequest for irq %d (%x)" %
                    (req_struct.num_irq, req_struct.type))

            else:
                msg = None
                raise Exception(
                    ("Received V7MRemoteInterrupt Notification with"
                     "unknown operation type %d") % req_struct.operation)

            self._avatar_queue.put(msg)

        self._closed.set()

    def stop(self):
        self._close.set()
        self._closed.wait()

    def enable_interrupts(self):
        if isinstance(self._origin, QemuTarget):
            # TODO: Make this more clean, i.e., check for remote memory
            rmem_rx_qname = self._origin.protocols.remote_memory.rx_queue_name
            rmem_tx_qname = self._origin.protocols.remote_memory.tx_queue_name
            # the tx-queue for qemu is the rx-queue for avatar and vice versa
            self._origin.protocols.monitor.execute_command(
                'avatar-armv7m-enable-irq', {
                    'irq_rx_queue_name': self._tx_queue_name,
                    'irq_tx_queue_name': self._rx_queue_name,
                    'rmem_rx_queue_name': rmem_tx_qname,
                    'rmem_tx_queue_name': rmem_rx_qname
                })
        else:
            raise Exception("V7MInterruptProtocol is not implemented for %s" %
                            self._origin.__class__)

        try:
            self._rx_queue = MessageQueue(self._rx_queue_name,
                                          flags=O_RDONLY,
                                          read=True,
                                          write=False)
        except Exception as e:
            self.log.error("Unable to create rx_queue: %s" % e)
            return False

        try:
            self._tx_queue = MessageQueue(self._tx_queue_name,
                                          flags=O_WRONLY,
                                          read=False,
                                          write=True)
        except Exception as e:
            self.log.error("Unable to create tx_queue: %s" % e)
            self._rx_queue.close()
            return False

        self.daemon = True
        self.start()
        self.log.info("Enabled Interrupt Forwarding for %s" % self._origin)
        return True

    def ignore_interrupt_return(self, interrupt_number):
        if isinstance(self._origin, QemuTarget):
            self.log.info("Disable handling of irq return for %d" %
                          interrupt_number)
            self._origin.protocols.monitor.execute_command(
                'avatar-armv7m-ignore-irq-return',
                {'num_irq': interrupt_number})

    def unignore_interrupt_return(self, interrupt_number):
        if isinstance(self._origin, QemuTarget):
            self.log.info("Re-enable handling of irq return for %d" %
                          interrupt_number)
            self._origin.protocols.monitor.execute_command(
                'avatar-armv7m-unignore-irq-return',
                {'num_irq': interrupt_number})

    def inject_interrupt(self, interrupt_number, cpu_number=0):
        if isinstance(self._origin, QemuTarget):
            self.log.info("Injecting interrupt %d" % interrupt_number)
            self._origin.protocols.monitor.execute_command(
                'avatar-armv7m-inject-irq', {
                    'num_irq': interrupt_number,
                    'num_cpu': cpu_number
                })

    def set_vector_table_base(self, base, cpu_number=0):
        if isinstance(self._origin, QemuTarget):
            self.log.info("Setting vector table base to 0x%x" % base)
            self._origin.protocols.monitor.execute_command(
                'avatar-armv7m-set-vector-table-base', {
                    'base': base,
                    'num_cpu': cpu_number
                })

    def send_interrupt_exit_response(self, id, success):
        response = V7MInterruptNotificationAck(id, success,
                                               RINOperation.EXIT.value)

        try:
            self._tx_queue.send(response)
            self.log.debug("Send RemoteInterruptExitResponse with id %d" % id)
            return True
        except Exception as e:
            self.log.error("Unable to send response: %s" % e)
            return False

    def send_interrupt_enter_response(self, id, success):
        response = V7MInterruptNotificationAck(id, success,
                                               RINOperation.ENTER.value)
        try:
            self._tx_queue.send(response)
            self.log.debug("Send RemoteInterruptEnterResponse with id %d" % id)
            return True
        except Exception as e:
            self.log.error("Unable to send response: %s" % e)
            return False

    def __del__(self):
        self.shutdown()

    def shutdown(self):
        self.stop()
        if self._rx_queue:
            try:
                self._rx_queue.unlink()
                self._rx_queue.close()
                self._rx_queue = None
            except ExistentialError:
                self.log.warning("Tried to close/unlink non existent rx_queue")
        if self._tx_queue:
            try:
                self._tx_queue.unlink()
                self._tx_queue.close()
                self._tx_queue = None
            except ExistentialError:
                self.log.warning("Tried to close/unlink non existent tx_queue")
Ejemplo n.º 5
0
from posix_ipc import MessageQueue as MsgQ
import sysv_ipc
import os

if __name__ == '__main__':
    q = MsgQ("/tmp", flags=os.O_CREAT, mode=0666)
    q.send("adfg")
    rec = q.receive(1)
    print rec
    q.close()
    q.unlink()

    q2 = sysv_ipc.MessageQueue(16842753, flags=sysv_ipc.IPC_CREAT)
    q2.send("sferogh", type=1)