Exemple #1
0
 def finalize_iteration(self):
     try:
         self.control.send('F')
         self.control.recv(1)
     except:
         log_exception()
         log_qemu("finalize_iteration failed...", self.qemu_id)
Exemple #2
0
    def set_payload(self, payload):
        if self.exiting:
            sys.exit(0)

        # TODO: enforce single global size limit through frontend/mutations/backend
        # PAYLOAD_SIZE-sizeof(uint32)-sizeof(uint8) = 131067!
        payload_limit = self.payload_size - 16
        if len(payload) > payload_limit:
            payload = payload[:payload_limit]

        try:
            self.fs_shm.seek(0)
            input_len = to_string_32(len(payload))
            self.fs_shm.write_byte(input_len[3])
            self.fs_shm.write_byte(input_len[2])
            self.fs_shm.write_byte(input_len[1])
            self.fs_shm.write_byte(input_len[0])
            self.fs_shm.write(payload)
            self.fs_shm.flush()
        except:
            if self.exiting:
                sys.exit(0)
            # Qemu crashed. Could be due to prior payload but more likely harness/config is broken..
            print_fail("Failed to set new payload - Qemu crash?")
            log_qemu("Failed to set new payload - Qemu crash?", self.qemu_id)
            raise
Exemple #3
0
    def set_init_state(self, payload=None):
        self.crashed = False
        self.timeout = False
        self.kasan = False
        self.handshake_stage_1 = True
        self.handshake_stage_2 = True
        self.start_ticks = 0
        self.end_ticks = 0

        self.__set_binary(self.binary_filename,
                          self.config.argument_values['executable'],
                          (128 << 20))

        self.__debug_recv_expect(qemu_protocol.RELEASE +
                                 qemu_protocol.PT_TRASHED)
        log_qemu("Initial stage 1 handshake done...", self.qemu_id)
        self.__debug_send(qemu_protocol.RELEASE)
        self.__debug_recv_expect(qemu_protocol.ACQUIRE +
                                 qemu_protocol.PT_TRASHED)
        log_qemu("Initial stage 2 handshake done...", self.qemu_id)
        if payload:
            self.set_payload(payload)
        self.send_payload(timeout_detection=False, apply_patches=False)
        self.crashed = False
        self.timeout = False
        self.kasan = False
Exemple #4
0
    def soft_reload(self):
        log_qemu("soft reload", self.qemu_id)
        self.crashed = False
        self.timeout = False
        self.kasan = False
        self.start_ticks = 0
        self.end_ticks = 0
        self.control.settimeout(10.0)

        # ask qemu to reload the VM and wait for acknowledgement
        self.control.send('L')
        while True:
            ch = self.control.recv(1)
            if ch == 'L' or ch == '' :
                break

        # wait for the initial handshake (acquire)
        v = self.control.recv(1)
        self.__set_binary(self.binary_filename, self.config.argument_values['executable'], (16 << 20))
        if v != 'D':
            raise Exception("this better not happen! v == %r" % v)
            #self.control.send('R')
            #v = self.control.recv(1)

        # now wait for the hypercall_next_payload from vm before continuing
        v = self.control.recv(1)
        self.control.settimeout(5.0)
Exemple #5
0
    def __qemu_handshake(self):

        if self.config.argument_values['agent']:
            self.__set_agent()

        # self.__debug_recv_expect(qemu_protocol.RELEASE + qemu_protocol.PT_TRASHED)
        # self.__debug_recv_expect(qemu_protocol.ACQUIRE)
        # self.__debug_send(qemu_protocol.RELEASE)
        # log_qemu("Stage 1 handshake done [INIT]", self.qemu_id)

        # # TODO: notify user if target/VM loads really slow or not at all..
        # #ready = select.select([self.control], [], [], 0.5)
        # #while not ready[0]:
        # #    print("[Slave %d] Waiting for Qemu handshake..." % self.qemu_id)
        # #    ready = select.select([self.control], [], [], 1)

        # self.handshake_stage_1 = False
        # # self.__debug_recv_expect(qemu_protocol.ACQUIRE + qemu_protocol.PT_TRASHED)
        # self.__debug_recv_expect(qemu_protocol.ACQUIRE)
        # self.__debug_send(qemu_protocol.RELEASE)
        # log_qemu("Stage 2 handshake done [READY]", self.qemu_id)
        # self.handshake_stage_2 = False
        self.__debug_send(qemu_protocol.RELEASE)  # unlock
        while True:
            res = self.__debug_recv()
            if res == qemu_protocol.LOCK:
                break
            self.__debug_send(qemu_protocol.RELEASE)
        self.__debug_recv_expect(qemu_protocol.RELEASE)
        self.__debug_recv()
        log_qemu("Handshake done [INIT]", self.qemu_id)
Exemple #6
0
    def start(self, verbose=False, serout=None):
        if verbose:
            self.process = subprocess.Popen(filter(None, self.cmd.split(" ")),
                                            stdin=None,
                                            stdout=serout, #None,
                                            stderr=None)
        else:
            if serout is None :
                serout = subprocess.PIPE
            self.process = subprocess.Popen(filter(None, self.cmd.split(" ")),
                                            stdin=subprocess.PIPE,
                                            stdout=serout, #subprocess.PIPE,
                                            stderr=subprocess.PIPE)

        log_qemu("process pid %d" % self.process.pid, self.qemu_id)
        self.stat_fd = open("/proc/" + str(self.process.pid) + "/stat")
        self.init()
        try:
            self.set_init_state()
        except:
            log_exception()
            return False
        self.initial_mem_usage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
        #time.sleep(1)
        self.kafl_shm.seek(0x0)
        self.kafl_shm.write(self.virgin_bitmap)
        self.kafl_shm.flush()
        return True
Exemple #7
0
    def __debug_recv_expect(self, cmd):
        res = ''
        while True:

            res = self.__debug_recv()
            if res in cmd:
                break
            # TODO: the I/O handling here really sucks.
            # Below we are returning OK to set_init_state() in order to silence handshake error message during kafl_info.py.
            # We need to factor out the debug stuff and properly support required vs optional/intermediate control messages...
            elif res == qemu_protocol.INFO:
                break
            elif res is None:
                # Timeout is detected separately in debug_recv(), so we should never get here..
                assert False
            else:
                # Reaching this part typically means there is a bug in the agent or target setup which
                # messes up the expected interaction. Throw an error and exit.
                log_qemu(
                    "Fatal error in debug_recv(): Got " + str(res) +
                    ", Expected: " + str(cmd) + ")", self.qemu_id)
                print_fail(
                    "Slave %d: Error in debug_recv(): Got %s, Expected: %s" %
                    (self.qemu_id, str(res), str(cmd)))
                assert False
        if res == qemu_protocol.PT_TRASHED:
            log_qemu("PT_TRASHED", self.qemu_id)
            return False
        return True
Exemple #8
0
    def __debug_recv(self):
        while True:
            try:
                res = self.control.recv(1)
            except ConnectionResetError:
                if self.exiting:
                    sys.exit(0)
                raise

            if (len(res) == 0):
                # Another case of socket error, apparently on Qemu reset/crash
                # Default: assume Qemu exit is fatal bug in harness/setup
                log_qemu("Fatal error in __debug_recv()", self.qemu_id)
                sig = self.shutdown()
                if sig == 0:  # regular shutdown? still report as KASAN
                    return qemu_protocol.KASAN
                else:
                    raise BrokenPipeError("Qemu exited with signal: %s" %
                                          str(sig))

            if res == qemu_protocol.PRINTF:
                self.__debug_hprintf()
                self.hprintf_print_mode = False
            else:
                self.hprintf_print_mode = True

                if self.debug_mode:
                    try:
                        self.__dump_recv_res(res)
                    except:
                        pass

                return res
Exemple #9
0
 def finalize_iteration(self):
     try:
         self.__debug_send(qemu_protocol.FINALIZE)
         self.__debug_recv()
     except:
         log_qemu("finalize_iteration failed...", self.qemu_id)
         log_qemu("%s" % traceback.format_exc())
Exemple #10
0
    def verifiy_input(self,
                      payload,
                      bitmap,
                      payload_size,
                      runs=3,
                      apply_patches=True):
        crashed = self.crashed
        timeout = self.timeout
        kasan = self.kasan
        failed = False
        try:
            self.enable_sampling_mode()
            init = True
            tmp_bitmap1 = bitmap
            for i in range(runs):
                if not init:
                    tmp_bitmap1 = self.send_payload(
                        timeout_detection=False, apply_patches=apply_patches)
                    if (self.crashed or self.kasan or self.timeout):
                        break
                    else:
                        self.submit_sampling_run()

                tmp_bitmap2 = self.send_payload(timeout_detection=False,
                                                apply_patches=apply_patches)
                if (self.crashed or self.kasan or self.timeout):
                    break
                else:
                    self.submit_sampling_run()
                if tmp_bitmap1 == tmp_bitmap2:
                    break
                init = False

        except:
            log_qemu("verification phase failed %s" % traceback.format_exc(),
                     self.qemu_id)
            failed = True

        self.crashed = crashed or self.crashed
        self.timeout = timeout or self.timeout
        self.kasan = kasan or self.kasan

        try:
            #if not self.timeout:
            self.submit_sampling_run()
            self.disable_sampling_mode()
            if not failed:
                return tmp_bitmap2
            else:
                return bitmap
        except:
            log_qemu(
                "verification phase failed 2 (timeout?) %s" %
                traceback.format_exc(), self.qemu_id)
            #self.timeout = True
            return bitmap
Exemple #11
0
    def soft_reload(self):
        return
        self.__debug_send(qemu_protocol.RELOAD)
        self.__debug_recv_expect(qemu_protocol.RELOAD)
        success = self.__debug_recv_expect(qemu_protocol.ACQUIRE +
                                           qemu_protocol.PT_TRASHED)

        if not success:
            log_qemu("soft reload failed (ipt ovp quirk)", self.qemu_id)
            self.soft_reload()
Exemple #12
0
 def check_recv(self, timeout_detection=True):
     log_qemu("check recv", self.qemu_id)
     if timeout_detection:
         self.control.settimeout(1.25)
     try:
         result = self.control.recv(1)
     #except socket_error, e:
     except socket.timeout, e:
         log_exception()
         #raise Exception("XXX DEBUG TIMEOUT")
         return "TIMEOUT"
Exemple #13
0
    def __qemu_handshake(self):
        if self.config.argument_values['agent']:
            self.__set_agent()

        self.__debug_send(qemu_protocol.RELEASE) # unlock
        while True:
            res = self.__debug_recv()
            if res == qemu_protocol.LOCK:
                break
            self.__debug_send(qemu_protocol.RELEASE)
        self.__debug_recv_expect(qemu_protocol.RELEASE)
        self.__debug_recv()
        log_qemu("Handshake done [INIT]", self.qemu_id)
Exemple #14
0
    def __debug_recv(self):
        while True:
            res = self.control.recv(1)
            if (len(res) == 0):
                log_qemu("__debug_recv error?", self.qemu_id)
                break

            if res == qemu_protocol.PRINTF:
                self.__debug_hprintf()
                self.hprintf_print_mode = False
            else:
                self.hprintf_print_mode = True
                if self.debug_mode:
                    if res == qemu_protocol.ACQUIRE:
                        self.debug_counter = 0
                    #try:
                    info = ""
                    if self.handshake_stage_1 and res == qemu_protocol.RELEASE:
                        info = " (Loader Handshake)"
                    elif self.handshake_stage_2 and res == qemu_protocol.ACQUIRE:
                        info = " (Initial Handshake Iteration)"
                    elif res == qemu_protocol.INFO:
                        print("[RECV]  \t" + '\033[1m' + '\033[92m' +
                              self.CMDS[res] + info + '\033[0m')
                        print(
                            "------------------------------------------------------"
                        )
                        try:
                            for line in open("/tmp/kAFL_info.txt"):
                                print line,
                            os.remove("/tmp/kAFL_info.txt")
                        except:
                            pass
                        print(
                            "------------------------------------------------------"
                        )
                        os._exit(0)
                    elif res == qemu_protocol.ABORT:
                        print(common.color.FAIL + self.CMDS[res] +
                              common.color.ENDC)
                        #print("[RECV]  \t" + common.color.FAIL + self.CMDS[res] + common.color.ENDC)
                        os._exit(0)
                    if res == qemu_protocol.CRASH or res == qemu_protocol.KASAN:
                        print("[RECV]  \t" + '\033[1m' + '\033[91m' +
                              self.CMDS[res] + info + '\033[0m')
                    else:
                        print("[RECV]  \t" + '\033[1m' + '\033[92m' +
                              self.CMDS[res] + info + '\033[0m')
                    #except Exception as e:
                    #    print("[RECV]  \t" + "unknown cmd '" + res + "'" + str(e))
                return res
Exemple #15
0
    def shutdown(self):
        log_qemu("Shutting down Qemu after %d execs.." % self.persistent_runs, self.qemu_id)
        
        if not self.process:
            # start() has never been called, all files/shm are closed.
            return 0

        # If Qemu exists, try to graciously read its I/O and SIGTERM it.
        # If still alive, attempt SIGKILL or loop-wait on kill -9.
        output = "<no output received>\n"
        try:
            self.process.terminate()
            output = strdump(self.process.communicate(timeout=1)[0], verbatim=True)
        except:
            pass

        if self.process.returncode is None:
            try:
                self.process.kill()
            except:
                pass

        log_qemu("Qemu exit code: %s" % str(self.process.returncode), self.qemu_id)
        header = "\n=================<Qemu %s Console Output>==================\n" % self.qemu_id
        footer = "====================</Console Output>======================\n"
        log_qemu(header + output + footer, self.qemu_id)
        header = "\n=================<Qemu %s Serial Output>==================\n" % self.qemu_id
        footer = "====================</Serial Output>======================\n"
        serial_out = strdump(read_binary_file(self.qemu_serial_log), verbatim=True)
        log_qemu(header + serial_out + footer, self.qemu_id)


        try:
            self.kafl_shm.close()
        except:
            pass

        try:
            self.fs_shm.close()
        except:
            pass

        try:
            os.close(self.kafl_shm_f)
        except:
            pass

        try:
            os.close(self.fs_shm_f)
        except:
            pass

        try:
            if self.stat_fd:
                self.stat_fd.close()
        except:
            pass


        return self.process.returncode
Exemple #16
0
    def execute_in_trace_mode(self, timeout_detection):
        log_qemu("Performing trace iteration...", self.qemu_id)
        exec_res = None
        try:
            self.soft_reload()
            self.send_enable_trace()
            exec_res = self.send_payload(timeout_detection=timeout_detection)
            self.soft_reload()
            self.send_disable_trace()
        except Exception as e:
            log_qemu("Error during trace: %s" % str(e), self.qemu_id)
            return None

        return exec_res
Exemple #17
0
    def __del__(self):
        log_qemu("kill qemu pid %d" % self.process.pid, self.qemu_id)
        os.system("kill -9 " + str(self.process.pid))

        try:
            if self.process:
                try:
                    self.process.kill()
                except:
                    log_exception()

            if self.e:
                if self.control_fileno:
                    self.e.unregister(self.control_fileno)

            if self.intervm_tty_write:
                self.intervm_tty_write.close()
            if self.control:
                self.control.close()
        except OSError:
            log_exception()
            pass

        try:
            self.kafl_shm.close()
        except:
            log_exception()
            pass

        try:
            self.fs_shm.close() 
        except:
            log_exception()
            pass

        try:
            if self.stat_fd:
                self.stat_fd.close()
        except:
            log_exception()
            pass

        if self.global_bitmap is not None :
            self.global_bitmap.close()
            self.global_bitmap = None

        if self.global_bitmap_fd is not None :
            os.close(self.global_bitmap_fd)
            self.global_bitmap_fd = None
Exemple #18
0
    def soft_reload(self):
        return

        log_qemu("soft_reload()", self.qemu_id)
        self.crashed = False
        self.timeout = False
        self.kasan = False
        self.start_ticks = 0
        self.end_ticks = 0

        self.__debug_send(qemu_protocol.RELOAD)
        self.__debug_recv_expect(qemu_protocol.RELOAD)
        success = self.__debug_recv_expect(qemu_protocol.ACQUIRE + qemu_protocol.PT_TRASHED)

        if not success:
            log_qemu("soft reload failed (ipt ovp quirk)", self.qemu_id)
            self.soft_reload()
Exemple #19
0
    def set_payload(self, irp):
        if self.exiting:
            sys.exit(0)

        # actual payload is limited to payload_size - sizeof(uint32) - sizeof(uint8)
        try:
            self.fs_shm.seek(0)
            self.fs_shm.write(p32(irp.Command))
            self.fs_shm.write(p32(irp.IoControlCode))
            self.fs_shm.write(p32(irp.InBufferLength))
            self.fs_shm.write(p32(irp.OutBufferLength))
            self.fs_shm.write(bytes(irp.InBuffer))
            self.fs_shm.flush()
        except ValueError:
            if self.exiting:
                sys.exit(0)
            # Qemu crashed. Could be due to prior payload but more likely harness/config is broken..
            #print_fail("Failed to set new payload - Qemu crash?");
            log_qemu("Failed to set new payload - Qemu crash?", self.qemu_id)
            raise
Exemple #20
0
 def send_irp(self, irp, retry=0):
     try:
         #log(f"iocode: {hex(irp.IoControlCode)}, payload: {bytes(irp.InBuffer[:0x10])}.., len: {hex(irp.InBufferLength)}", label='IRP')
         self.set_payload(irp)
         return self.send_payload()
     except (ValueError, BrokenPipeError):
         if retry > 2:
             # TODO if it reliably kills qemu, perhaps log to master for harvesting..
             print_fail(
                 "Process aborting due to repeated SHM/socket error. Check logs."
             )
             log_qemu("Aborting due to repeated SHM/socket error",
                      self.qemu_id)
             raise
         print_warning("SHM/socket error on Process (retry %d)" % retry)
         log_qemu("SHM/socket error, trying to restart qemu...",
                  self.qemu_id)
         if not self.restart():
             raise
     return self.send_irp(irp, retry=retry + 1)
Exemple #21
0
    def execute_in_redqueen_mode(self, payload):
        log_qemu("Performing redqueen iteration...", self.qemu_id)
        try:
            self.soft_reload()
            self.send_rq_set_light_instrumentation()
            self.send_enable_redqueen()
            self.set_payload(payload)
            self.send_payload(timeout_detection=False)
            if self.exit_reason() != "regular":
                print_warning("RQ execution returned %s", self.exit_reason())
        except Exception as e:
            log_qemu("%s" % traceback.format_exc(), self.qemu_id)
            return False

        #log_qemu("Disabling redqueen mode...", self.qemu_id)
        try:
            self.send_disable_redqueen()
            self.set_payload(payload)
            self.send_payload(timeout_detection=False)
            self.soft_reload()
            if self.exit_reason() != "regular":
                print_warning("RQ execution returned %s", self.exit_reason())
        except Exception as e:
            log_qemu("%s" % traceback.format_exc(), self.qemu_id)
            return False
        return True
Exemple #22
0
    def start(self):

        if self.exiting:
            return False

        self.persistent_runs = 0
        self.handshake_stage_1 = True
        self.handshake_stage_2 = True

        if self.qemu_id == "0" or self.qemu_id == "1337": ## 1337 is debug instance!
            log_qemu("Launching virtual machine...CMD:\n" + ' '.join(self.cmd), self.qemu_id)
        else:
            log_qemu("Launching virtual machine...", self.qemu_id)


        # Launch Qemu. stderr to stdout, stdout is logged on VM exit
        # os.setpgrp() prevents signals from being propagated to Qemu, instead allowing an
        # organized shutdown via async_exit()
        self.process = subprocess.Popen(self.cmd,
                preexec_fn=os.setpgrp,
                stdin=subprocess.PIPE,
                #stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT)

        try:
            self.__qemu_connect()
            self.__qemu_handshake()
        except (OSError, BrokenPipeError) as e:
            if not self.exiting:
                print_fail("Failed to launch Qemu, please see logs. Error: " + str(e))
                log_qemu("Fatal error: Failed to launch Qemu: " + str(e), self.qemu_id)
                self.shutdown()
            return False

        return True
Exemple #23
0
    def send_payload(self, timeout_detection=True):
        self.start_ticks = self.__get_pid_guest_ticks()
        try:
            self.control.send("R")
        except OSError:
            log_qemu("Failed to send payload...", self.qemu_id)
            return None

        self.crashed = False
        self.timeout = False
        self.kasan = False

        if timeout_detection:
            counter = 0
            while True:
                value = self.check_recv()
                if value == 2:
                    self.end_ticks = self.__get_pid_guest_ticks()
                    if (self.end_ticks -
                            self.start_ticks) >= self.tick_timeout_treshold:
                        break
                    if counter >= 10:
                        break
                    counter += 1
                else:
                    break
            self.end_ticks = self.__get_pid_guest_ticks()
        else:
            value = self.check_recv(timeout_detection=False)
        if value == 1:
            self.crashed = True
            self.finalize_iteration()
        elif value == 2:
            self.timeout = True
            self.finalize_iteration()
        elif value == 3:
            self.kasan = True
            self.finalize_iteration()
        self.kafl_shm.seek(0x0)
        return self.kafl_shm.read(self.bitmap_size)
Exemple #24
0
    def __debug_recv(self):
        while True:
            try:
                res = self.control.recv(1)
            except ConnectionResetError:
                if self.exiting:
                    sys.exit(0)

            if (len(res) == 0):
                # Another case of socket error, apparently on Qemu reset/crash
                if self.catch_vm_reboots:
                    # Treat event as Qemu reset triggered by target, and log as KASAN
                    log_qemu(
                        "Qemu exit? - Assuming target crash/reset (KASAN)",
                        self.qemu_id)
                    return qemu_protocol.KASAN
                else:
                    # Default: assume Qemu exit is fatal bug in harness/setup
                    log_qemu("Fatal error in __debug_recv()", self.qemu_id)
                    sig = self.shutdown()
                    if sig == 0:  # regular shutdown? still report as KASAN
                        return qemu_protocol.KASAN
                    else:
                        raise EOFError("Qemu exited with signal: %s" %
                                       str(sig))

            if res == qemu_protocol.PRINTF:
                self.__debug_hprintf()
                self.hprintf_print_mode = False
            else:
                self.hprintf_print_mode = True

                if self.debug_mode:
                    try:
                        self.__dump_recv_res(res)
                    except:
                        pass

                return res
Exemple #25
0
    def set_init_state(self):
        self.start_ticks = 0
        self.end_ticks = 0

        if self.config.argument_values['agent']:
            self.__set_agent()


        self.__debug_recv_expect(qemu_protocol.RELEASE + qemu_protocol.PT_TRASHED)
        self.__debug_send(qemu_protocol.RELEASE)
        log_qemu("Stage 1 handshake done [INIT]", self.qemu_id)

        # notify user if harness loads slow or not at all..
        #ready = select.select([self.control], [], [], 0.5)
        #while not ready[0]:
        #    print("[Slave %d] Waiting for Qemu handshake..." % self.qemu_id)
        #    ready = select.select([self.control], [], [], 1)

        self.handshake_stage_1 = False
        self.__debug_recv_expect(qemu_protocol.ACQUIRE + qemu_protocol.PT_TRASHED)
        log_qemu("Stage 2 handshake done [READY]", self.qemu_id)
        self.handshake_stage_2 = False
Exemple #26
0
    def send_payload(self, timeout_detection=True):
        """Send a test case to qemu, wait for a response, and read back the coverage map"""
        log_qemu("send payload", self.qemu_id)
        self.start_ticks = self.__get_pid_guest_ticks()
        try:
            # vm was waiting for next payload, unlock them now that its been provided
            self.control.send("R")
        except OSError:
            log_exception()
            log_qemu("Failed to send payload...", self.qemu_id)
            return None

        self.crashed = False
        self.timeout = False
        self.kasan = False

        if timeout_detection:
            counter = 0
            while True:
                value = self.check_recv()
                if value == "TIMEOUT":
                    self.end_ticks = self.__get_pid_guest_ticks()
                    if (self.end_ticks-self.start_ticks) >= self.tick_timeout_treshold:
                        break
                    if counter >= 10:
                    	break
                    counter += 1
                else:
                    break
            self.end_ticks = self.__get_pid_guest_ticks()
        else:
            value = self.check_recv(timeout_detection=False)
        log_qemu("check_recv val %s" % value, self.qemu_id)
        if value == "CRASH":
            self.crashed = True
            self.finalize_iteration()
        elif value == "TIMEOUT":
            self.timeout = True
            self.finalize_iteration()
        elif value == "KASAN":
            self.kasan = True
            self.finalize_iteration()
        elif value == "EOF":
            log_qemu("QEMU control channel unexpectedly shut down!", self.qemu_id)
            self.timeout = True # XXX was really qemu shutting down!
            self.finalize_iteration()
        self.kafl_shm.seek(0x0)
        return self.kafl_shm.read(self.bitmap_size)
Exemple #27
0
    def set_payload(self, payload):
        if self.exiting:
            sys.exit(0)

        # actual payload is limited to payload_size - sizeof(uint32) - sizeof(uint8)
        if len(payload) > self.payload_size - 5:
            payload = payload[:self.payload_size - 5]
        try:
            self.fs_shm.seek(0)
            input_len = to_string_32(len(payload))
            self.fs_shm.write_byte(input_len[3])
            self.fs_shm.write_byte(input_len[2])
            self.fs_shm.write_byte(input_len[1])
            self.fs_shm.write_byte(input_len[0])
            self.fs_shm.write(payload)
            self.fs_shm.flush()
        except ValueError:
            if self.exiting:
                sys.exit(0)
            # Qemu crashed. Could be due to prior payload but more likely harness/config is broken..
            #print_fail("Failed to set new payload - Qemu crash?");
            log_qemu("Failed to set new payload - Qemu crash?", self.qemu_id)
            raise
Exemple #28
0
    def set_init_state(self):
        # since we've reloaded the VM - let's assume there is no panic state...
        self.crashed = False
        self.timeout = False
        self.kasan = False
        self.start_ticks = 0
        self.end_ticks = 0

        # wait for initial hypercall_acquire from vm
        self.control.settimeout(10.0)
        v = self.control.recv(1)
        log_qemu("Initial stage 1 handshake ["+ str(v) + "] done...", self.qemu_id)
        self.__set_binary(self.binary_filename, self.config.argument_values['executable'], (16 << 20))
        if v != 'D':
            raise Exception("this better not happen! v = %r" % v)
            #self.control.send('R')
            #v = self.control.recv(1)
            #log_qemu("Initial stage 2 handshake ["+ str(v) + "] done...", self.qemu_id)

        # now wait for the hypercall_next_payload from vm before continuing
        v = self.control.recv(1)
        log_qemu("Initial stage 3 handshake ["+ str(v) + "] done...", self.qemu_id)
        self.control.settimeout(5.0)
Exemple #29
0
    def start(self):

        if self.exiting:
            return False

        if self.qemu_id == "0" or self.qemu_id == "1337":  ## 1337 is debug instance!
            log_qemu("Launching virtual machine...CMD:\n" + ' '.join(self.cmd),
                     self.qemu_id)
        else:
            log_qemu("Launching virtual machine...CMD:\n" + ' '.join(self.cmd),
                     self.qemu_id)
            #log_qemu("Launching virtual machine...", self.qemu_id)

        self.persistent_runs = 0
        # Have not received+send first RELEASE (init handshake)
        self.handshake_stage_1 = True
        # Have not received first ACQUIRE (ready for payload execution)
        self.handshake_stage_2 = True

        # Launch Qemu. stderr to stdout, stdout is logged on VM exit
        # os.setpgrp() prevents signals from being propagated to Qemu, instead allowing an
        # organized shutdown via async_exit()
        if self.verbose:
            self.process = subprocess.Popen(self.cmd,
                                            preexec_fn=os.setpgrp,
                                            stdin=subprocess.PIPE,
                                            stdout=get_log_file(),
                                            stderr=get_log_file())
        else:
            self.process = subprocess.Popen(self.cmd,
                                            preexec_fn=os.setpgrp,
                                            stdin=subprocess.PIPE,
                                            stdout=subprocess.PIPE,
                                            stderr=subprocess.STDOUT)

        try:
            self.stat_fd = open("/proc/" + str(self.process.pid) + "/stat")
            self.init()
            self.set_init_state()
        except:
            if not self.exiting:
                print_fail("Failed to launch Qemu, please see logs.")
                log_qemu("Fatal error: Failed to launch Qemu.", self.qemu_id)
                self.shutdown()
            return False

        self.initial_mem_usage = resource.getrusage(
            resource.RUSAGE_SELF).ru_maxrss
        self.kafl_shm.seek(0x0)
        self.kafl_shm.write(self.virgin_bitmap)
        self.kafl_shm.flush()

        return True
Exemple #30
0
    def execute_in_trace_mode(self, debug_mode, timeout_detection):
        log_qemu("Performing trace iteration...", self.qemu_id)
        if debug_mode:
            print("Performing trace iteration...")
        try:
            self.soft_reload()
            self.send_enable_trace()
            self.send_payload(timeout_detection=timeout_detection)
        except Exception as e:
            if debug_mode:
                print("Fail 1...(" + str(e) + ")")
            log_qemu("Fail 1...(" + str(e) + ")", self.qemu_id)
            return False

        try:
            self.soft_reload()
            self.send_disable_trace()
        except Exception as e:
            log_qemu("Fail 3...(" + str(e) + ")", self.qemu_id)
            log_qemu("%s" % traceback.format_exc(), self.qemu_id)
            return False
        return True