コード例 #1
0
ファイル: hypercallfuzz.py プロジェクト: leojdh/chipsec
    def __init__(self):
        BaseModule.__init__(self)
        self.vmm = VMM(self.cs)

        self.random_order = True
        self.gprs = GPRS
        self.vector_reg = None
        self.iterations = DEFAULT_RANDOM_ITERATIONS
        self.maxval = DEFAULT_MAXVAL_RANDOM
コード例 #2
0
ファイル: vmbus.py プロジェクト: leojdh/chipsec
 def __init__(self):
     BaseModuleDebug.__init__(self)
     self.hypercall = VMM(self.cs)
     self.hypercall.init()
     self.membuf = self.cs.mem.alloc_physical_mem(4*0x1000, 0xFFFFFFFF)
     self.cs.mem.write_physical_mem(self.membuf[1], 4*0x1000, '\x00' * 4*0x1000)
     self.old_sint2 = []
     self.old_simp  = []
     self.old_siefp = []
     self.simp   = []
     self.siefp  = []
コード例 #3
0
    def run(self):
        t = time.time()

        try:
            self.vmm = VMM(self.cs)
        except VMMRuntimeError as msg:
            self.logger.error(msg)
            return

        self.vmm.init()

        self.func()

        self.logger.log("[CHIPSEC] (vmm) time elapsed {:.3f}".format(
            (time.time() - t)))
コード例 #4
0
ファイル: vmbus.py プロジェクト: abazhaniuk/chipsec
 def __init__(self):
     BaseModuleDebug.__init__(self)
     self.hypercall = VMM(self.cs)
     self.hypercall.init()
     self.membuf = self.cs.mem.alloc_physical_mem(4*0x1000, 0xFFFFFFFF)
     self.cs.mem.write_physical_mem(self.membuf[1], 4*0x1000, '\x00' * 4*0x1000)
     self.old_sint2 = []
     self.old_simp  = []
     self.old_siefp = []
     self.simp   = []
     self.siefp  = []
コード例 #5
0
ファイル: vmbus.py プロジェクト: abazhaniuk/chipsec
class HyperV(BaseModuleDebug):
    def __init__(self):
        BaseModuleDebug.__init__(self)
        self.hypercall = VMM(self.cs)
        self.hypercall.init()
        self.membuf = self.cs.mem.alloc_physical_mem(4*0x1000, 0xFFFFFFFF)
        self.cs.mem.write_physical_mem(self.membuf[1], 4*0x1000, '\x00' * 4*0x1000)
        self.old_sint2 = []
        self.old_simp  = []
        self.old_siefp = []
        self.simp   = []
        self.siefp  = []

    def __del__(self):
        BaseModuleDebug.__del__(self)
        self.dbg('Free kernel memory')
        #if self.membuf[0] <> 0:
        #    self.cs.mem.free_physical_mem(self.membuf[0])
        if len(self.old_sint2) == 2:
            self.cs.msr.write_msr(0, HV_X64_MSR_SINT2, self.old_sint2[0], self.old_sint2[1])
        if len(self.old_simp)  == 2:
            self.cs.msr.write_msr(0, HV_X64_MSR_SIMP,  self.old_simp[0],  self.old_simp[1])
        if len(self.old_siefp) == 2:
            self.cs.msr.write_msr(0, HV_X64_MSR_SIEFP, self.old_siefp[0], self.old_siefp[1])
        for i in [x for x in self.ringbuffers]:
            del self.ringbuffers[i]

    ##
    ##  hv_init
    ##
    def hv_init(self):
        self.old_sint2 = self.cs.msr.read_msr(0, HV_X64_MSR_SINT2)
        self.old_simp  = self.cs.msr.read_msr(0, HV_X64_MSR_SIMP)
        self.old_siefp = self.cs.msr.read_msr(0, HV_X64_MSR_SIEFP)
        pa = self.membuf[1]
        self.sint3 = self.cs.msr.read_msr(0, HV_X64_MSR_SINT3)
        self.cs.msr.write_msr(0, HV_X64_MSR_SINT2, self.sint3[0], self.sint3[1])
        self.cs.msr.write_msr(0, HV_X64_MSR_SIEFP, (pa & 0xFFFFFFFF) | 0x1, pa >> 32)
        #self.cs.msr.write_msr(0, HV_X64_MSR_SCONTROL, 0x1, 0x0)
        self.simp  = self.cs.msr.read_msr(0, HV_X64_MSR_SIMP)
        self.siefp = self.cs.msr.read_msr(0, HV_X64_MSR_SIEFP)
        self.simp  = (self.simp[0]  + (self.simp[1]  << 32)) & 0xFFFFFFFFFFFFF000
        self.siefp = (self.siefp[0] + (self.siefp[1] << 32)) & 0xFFFFFFFFFFFFF000
        return

    ##
    ##  hv_post_msg - Send a message
    ##
    def hv_post_msg(self, message):
        retries = 3
        hciv    = hv_hciv(0, 0, HV_POST_MESSAGE)
        while retries > 0:
            result = self.hypercall.hypercall64_memory_based(hciv, message[:0x100]) & 0xFFFF
            if result == HV_STATUS_INSUFFICIENT_BUFFERS:
                retries -= 1
                time.sleep(0.1)
            else:
                retries  = 0
        return result

    ##
    ##  hv_recv_msg - recieve message if exist otherwise empty string
    ##
    def hv_recv_msg(self, sint):
        buffer = self.cs.mem.read_physical_mem(self.simp + 0x100*sint, 0x100)
        message_type, payload_size, message_flags = unpack('<LBB', buffer[0:6])
        if message_type == HVMSG_NONE:
            buffer = ''
        else:
            self.cs.mem.write_physical_mem(self.simp + 0x100*sint, 0x4, DD(HVMSG_NONE))
            if message_flags & 0x1:
                self.cs.msr.write_msr(0, HV_X64_MSR_EOM, 0x0, 0x0)
        return buffer

    ##
    ##  hv_signal_event - send an event notification
    ##
    def hv_signal_event(self, connection_id, flag_number):
        hciv   = hv_hciv(0, 0, HV_SIGNAL_EVENT)
        buffer = pack('<LHH', connection_id, flag_number, 0x0)
        result = self.hypercall.hypercall64_memory_based(hciv, buffer) & 0xFFFF
        return result

    ##
    ##  hv_recv_events - recieve all current events
    ##
    def hv_recv_events(self, sint):
        events = set()
        buffer = self.cs.mem.read_physical_mem(self.siefp + 0x100*sint, 0x100)
        buffer = unpack('<64L', buffer)
        for i in xrange(64):
            if buffer[i]:
                for n in xrange(32):
                    if (buffer[i] >> n) & 0x1:
                        events.add(i*32 + n)
        return events
コード例 #6
0
class VMMCommand(BaseCommand):
    def requires_driver(self):
        parser = ArgumentParser(prog='chipsec_util vmm', usage=__doc__)
        subparsers = parser.add_subparsers()

        parser_hypercall = subparsers.add_parser('hypercall')
        parser_hypercall.add_argument('ax',
                                      type=lambda x: int(x, 16),
                                      help='rax/eax value (hex)')
        parser_hypercall.add_argument('bx',
                                      type=lambda x: int(x, 16),
                                      help='rbx/ebx value (hex)')
        parser_hypercall.add_argument('cx',
                                      type=lambda x: int(x, 16),
                                      help='rcx/ecx value (hex)')
        parser_hypercall.add_argument('dx',
                                      type=lambda x: int(x, 16),
                                      help='rdx/edx value (hex)')
        parser_hypercall.add_argument('di',
                                      type=lambda x: int(x, 16),
                                      help='rdi/edi value (hex)')
        parser_hypercall.add_argument('si',
                                      type=lambda x: int(x, 16),
                                      help='rsi/esi value (hex)')
        parser_hypercall.add_argument('r8',
                                      type=lambda x: int(x, 16),
                                      nargs='?',
                                      default=0,
                                      help='r8 value (hex)')
        parser_hypercall.add_argument('r9',
                                      type=lambda x: int(x, 16),
                                      nargs='?',
                                      default=0,
                                      help='r9 value (hex)')
        parser_hypercall.add_argument('r10',
                                      type=lambda x: int(x, 16),
                                      nargs='?',
                                      default=0,
                                      help='r10 value (hex)')
        parser_hypercall.add_argument('r11',
                                      type=lambda x: int(x, 16),
                                      nargs='?',
                                      default=0,
                                      help='r11 value (hex)')
        parser_hypercall.set_defaults(func=self.vmm_hypercall)

        parser_pt = subparsers.add_parser('pt')
        parser_pt.add_argument('eptp',
                               type=lambda x: int(x, 16),
                               help='Pointer (hex)')
        parser_pt.set_defaults(func=self.vmm_pt)

        parser_ept = subparsers.add_parser('ept')
        parser_ept.add_argument('eptp',
                                type=lambda x: int(x, 16),
                                help='Pointer (hex)')
        parser_ept.set_defaults(func=self.vmm_pt)

        parser_virtio = subparsers.add_parser('virtio')
        parser_virtio.add_argument('bdf',
                                   type=str,
                                   nargs='?',
                                   default=None,
                                   help='<bus>:<device>.<function>')
        parser_virtio.set_defaults(func=self.vmm_virtio)

        parser.parse_args(self.argv[2:], namespace=self)
        return True

    def vmm_virtio(self):
        if self.bdf is not None:
            match = re.search(
                r"^([0-9a-f]{1,2}):([0-1]?[0-9a-f]{1})\.([0-7]{1})$", self.bdf)
            if match:
                _bus = int(match.group(1), 16) & 0xFF
                _dev = int(match.group(2), 16) & 0x1F
                _fun = int(match.group(3), 16) & 0x07
                vid = self.cs.pci.read_word(_bus, _dev, _fun, 0)
                did = self.cs.pci.read_word(_bus, _dev, _fun, 2)
                dev = (_bus, _dev, _fun, vid, did)
                virt_dev = [dev]
            else:
                self.logger.error("Invalid B:D.F ({})".format(self.bdf))
                self.logger.log(VMMCommand.__doc__)
                return
        else:
            self.logger.log("[CHIPSEC] Enumerating VirtIO devices...")
            virt_dev = get_virtio_devices(self.cs.pci.enumerate_devices())

        if len(virt_dev) > 0:
            self.logger.log("[CHIPSEC] Available VirtIO devices:")
            print_pci_devices(virt_dev)
            for (b, d, f, vid, did) in virt_dev:
                VirtIO_Device(self.cs, b, d, f).dump_device()
        else:
            self.logger.log("[CHIPSEC] No VirtIO devices found")

    def vmm_hypercall(self):
        self.logger.log('')
        self.logger.log("[CHIPSEC] > hypercall")
        self.logger.log("[CHIPSEC]   RAX: 0x{:016X}".format(self.ax))
        self.logger.log("[CHIPSEC]   RBX: 0x{:016X}".format(self.bx))
        self.logger.log("[CHIPSEC]   RCX: 0x{:016X}".format(self.cx))
        self.logger.log("[CHIPSEC]   RDX: 0x{:016X}".format(self.dx))
        self.logger.log("[CHIPSEC]   RSI: 0x{:016X}".format(self.si))
        self.logger.log("[CHIPSEC]   RDI: 0x{:016X}".format(self.di))
        self.logger.log("[CHIPSEC]   R8 : 0x{:016X}".format(self.r8))
        self.logger.log("[CHIPSEC]   R9 : 0x{:016X}".format(self.r9))
        self.logger.log("[CHIPSEC]   R10: 0x{:016X}".format(self.r10))
        self.logger.log("[CHIPSEC]   R11: 0x{:016X}".format(self.r11))

        rax = self.vmm.hypercall(self.ax, self.bx, self.cx, self.dx, self.si,
                                 self.di, self.r8, self.r9, self.r10, self.r11)

        self.logger.log("[CHIPSEC] < RAX: 0x{:016X}".format(rax))

    def vmm_pt(self):
        if self.eptp is not None:
            pt_fname = 'ept_{:08X}'.format(self.eptp)
            self.logger.log("[CHIPSEC] EPT physical base: 0x{:016X}".format(
                self.eptp))
            self.logger.log(
                "[CHIPSEC] Dumping EPT to '{}'...".format(pt_fname))
            self.vmm.dump_EPT_page_tables(self.eptp, pt_fname)
        else:
            self.logger.log(
                "[CHIPSEC] Finding EPT hierarchy in memory is not implemented yet"
            )
            self.logger.error(VMMCommand.__doc__)
            return

    def run(self):
        t = time.time()

        try:
            self.vmm = VMM(self.cs)
        except VMMRuntimeError as msg:
            self.logger.error(msg)
            return

        self.vmm.init()

        self.func()

        self.logger.log("[CHIPSEC] (vmm) time elapsed {:.3f}".format(
            (time.time() - t)))
コード例 #7
0
ファイル: vmbus.py プロジェクト: mex20/chipsec_gui
class HyperV(BaseModuleDebug):
    def __init__(self):
        BaseModuleDebug.__init__(self)
        self.hypercall = VMM(self.cs)
        self.hypercall.init()
        self.membuf = self.cs.mem.alloc_physical_mem(4 * 0x1000, 0xFFFFFFFF)
        self.cs.mem.write_physical_mem(self.membuf[1], 4 * 0x1000,
                                       '\x00' * 4 * 0x1000)
        self.old_sint2 = []
        self.old_simp = []
        self.old_siefp = []
        self.simp = []
        self.siefp = []

    def __del__(self):
        BaseModuleDebug.__del__(self)
        self.dbg('Free kernel memory')
        #if self.membuf[0] <> 0:
        #    self.cs.mem.free_physical_mem(self.membuf[0])
        if len(self.old_sint2) == 2:
            self.cs.msr.write_msr(0, HV_X64_MSR_SINT2, self.old_sint2[0],
                                  self.old_sint2[1])
        if len(self.old_simp) == 2:
            self.cs.msr.write_msr(0, HV_X64_MSR_SIMP, self.old_simp[0],
                                  self.old_simp[1])
        if len(self.old_siefp) == 2:
            self.cs.msr.write_msr(0, HV_X64_MSR_SIEFP, self.old_siefp[0],
                                  self.old_siefp[1])
        for i in [x for x in self.ringbuffers]:
            del self.ringbuffers[i]

    ##
    ##  hv_init
    ##
    def hv_init(self):
        self.old_sint2 = self.cs.msr.read_msr(0, HV_X64_MSR_SINT2)
        self.old_simp = self.cs.msr.read_msr(0, HV_X64_MSR_SIMP)
        self.old_siefp = self.cs.msr.read_msr(0, HV_X64_MSR_SIEFP)
        pa = self.membuf[1]
        self.sint3 = self.cs.msr.read_msr(0, HV_X64_MSR_SINT3)
        self.cs.msr.write_msr(0, HV_X64_MSR_SINT2, self.sint3[0],
                              self.sint3[1])
        self.cs.msr.write_msr(0, HV_X64_MSR_SIEFP, (pa & 0xFFFFFFFF) | 0x1,
                              pa >> 32)
        #self.cs.msr.write_msr(0, HV_X64_MSR_SCONTROL, 0x1, 0x0)
        self.simp = self.cs.msr.read_msr(0, HV_X64_MSR_SIMP)
        self.siefp = self.cs.msr.read_msr(0, HV_X64_MSR_SIEFP)
        self.simp = (self.simp[0] + (self.simp[1] << 32)) & 0xFFFFFFFFFFFFF000
        self.siefp = (self.siefp[0] +
                      (self.siefp[1] << 32)) & 0xFFFFFFFFFFFFF000
        return

    ##
    ##  hv_post_msg - Send a message
    ##
    def hv_post_msg(self, message):
        retries = 3
        hciv = hv_hciv(0, 0, HV_POST_MESSAGE)
        while retries > 0:
            result = self.hypercall.hypercall64_memory_based(
                hciv, message[:0x100]) & 0xFFFF
            if result == HV_STATUS_INSUFFICIENT_BUFFERS:
                retries -= 1
                time.sleep(0.1)
            else:
                retries = 0
        return result

    ##
    ##  hv_recv_msg - recieve message if exist otherwise empty string
    ##
    def hv_recv_msg(self, sint):
        buffer = self.cs.mem.read_physical_mem(self.simp + 0x100 * sint, 0x100)
        message_type, payload_size, message_flags = unpack('<LBB', buffer[0:6])
        if message_type == HVMSG_NONE:
            buffer = ''
        else:
            self.cs.mem.write_physical_mem(self.simp + 0x100 * sint, 0x4,
                                           DD(HVMSG_NONE))
            if message_flags & 0x1:
                self.cs.msr.write_msr(0, HV_X64_MSR_EOM, 0x0, 0x0)
        return buffer

    ##
    ##  hv_signal_event - send an event notification
    ##
    def hv_signal_event(self, connection_id, flag_number):
        hciv = hv_hciv(0, 0, HV_SIGNAL_EVENT)
        buffer = pack('<LHH', connection_id, flag_number, 0x0)
        result = self.hypercall.hypercall64_memory_based(hciv, buffer) & 0xFFFF
        return result

    ##
    ##  hv_recv_events - recieve all current events
    ##
    def hv_recv_events(self, sint):
        events = set()
        buffer = self.cs.mem.read_physical_mem(self.siefp + 0x100 * sint,
                                               0x100)
        buffer = unpack('<64L', buffer)
        for i in xrange(64):
            if buffer[i]:
                for n in xrange(32):
                    if (buffer[i] >> n) & 0x1:
                        events.add(i * 32 + n)
        return events
コード例 #8
0
ファイル: hypercallfuzz.py プロジェクト: leojdh/chipsec
class hypercallfuzz(BaseModule):
    def __init__(self):
        BaseModule.__init__(self)
        self.vmm = VMM(self.cs)

        self.random_order = True
        self.gprs = GPRS
        self.vector_reg = None
        self.iterations = DEFAULT_RANDOM_ITERATIONS
        self.maxval = DEFAULT_MAXVAL_RANDOM

    def is_supported(self):
        return True

    def fuzz_generic_hypercalls(self):

        _fmt = '{:02X}' if self.maxval <= 0xFF else (
            '{:04X}' if self.maxval <= 0xFFFF else
            ('{:08X}' if self.maxval <= 0xFFFFFFFF else '{:016X}'))
        _str = "{} hcall rax={},rbx={},rcx={},rdx={},rdi={},rsi={},r8={},r9={},r10={},r11={}".format(
            '{:d}', _fmt, _fmt, _fmt, _fmt, _fmt, _fmt, _fmt, _fmt, _fmt, _fmt)

        t = time.time()
        if self.random_order:

            self.logger.log(
                "[*] Fuzzing {:d} random hypercalls with random arguments...".
                format(self.iterations))
            for it in range(self.iterations):
                rax = random.randint(0, self.gprs['rax'])
                rbx = random.randint(0, self.gprs['rbx'])
                rcx = random.randint(0, self.gprs['rcx'])
                rdx = random.randint(0, self.gprs['rdx'])
                rdi = random.randint(0, self.gprs['rdi'])
                rsi = random.randint(0, self.gprs['rsi'])
                r8 = random.randint(0, self.gprs['r8'])
                r9 = random.randint(0, self.gprs['r9'])
                r10 = random.randint(0, self.gprs['r10'])
                r11 = random.randint(0, self.gprs['r11'])
                if _LOG_ALL_GPRS:
                    self.logger.log(
                        _str.format(it, rax, rbx, rcx, rdx, rdi, rsi, r8, r9,
                                    r10, r11))
                else:
                    self.logger.log("{:d} hcall".format(it))
                if _FLUSH_LOG_EACH_ITER: self.logger.flush()
                try:
                    res = self.vmm.hypercall(rax, rbx, rcx, rdx, rdi, rsi, r8,
                                             r9, r10, r11)
                except:
                    pass

        else:

            it = 0
            self.logger.log(
                "[*] Fuzzing hypercalls with arguments exhaustively...")
            for rax in range(self.gprs['rax']):
                for rbx in range(self.gprs['rbx']):
                    for rcx in range(self.gprs['rcx']):
                        for rdx in range(self.gprs['rdx']):
                            for rdi in range(self.gprs['rdi']):
                                for rsi in range(self.gprs['rsi']):
                                    for r8 in range(self.gprs['r8']):
                                        for r9 in range(self.gprs['r9']):
                                            for r10 in range(self.gprs['r10']):
                                                for r11 in range(
                                                        self.gprs['r11']):
                                                    if _LOG_ALL_GPRS:
                                                        self.logger.log(
                                                            _str.format(
                                                                it, rax, rbx,
                                                                rcx, rdx, rdi,
                                                                rsi, r8, r9,
                                                                r10, r11))
                                                    else:
                                                        self.logger.log(
                                                            "{:d} hcall".
                                                            format(it))
                                                    if _FLUSH_LOG_EACH_ITER:
                                                        self.logger.flush()
                                                    try:
                                                        res = self.vmm.hypercall(
                                                            rax, rbx, rcx, rdx,
                                                            rdi, rsi, r8, r9,
                                                            r10, r11)
                                                        it += 1
                                                    except:
                                                        pass

        self.logger.log(
            "[*] finished fuzzing: time elapsed {:.3f}".format(time.time() -
                                                               t))
        return ModuleResult.PASSED

    def usage(self):
        self.logger.log(
            "Usage: chipsec_main -m tools.vmm.hypercallfuzz [ -a <mode>,<vector_reg>,<maxval>,<iterations> ]"
        )
        self.logger.log("  mode            hypercall fuzzing mode")
        self.logger.log(
            "    = exhaustive  fuzz all arguments exhaustively in range [0:<maxval>] (default)"
        )
        self.logger.log(
            "    = random      send random values in all registers in range [0:<maxval>]"
        )
        self.logger.log("  vector_reg      hypercall vector register")
        self.logger.log("  maxval          maximum value of each register")
        self.logger.log(
            "  iterations      number of iterations in random mode (default = {:d})"
            .format(DEFAULT_RANDOM_ITERATIONS))

    def run(self, module_argv):

        self.logger.start_test("Dumb VMM hypercall fuzzer")
        self.usage()

        if len(module_argv) > 0:
            self.random_order = (module_argv[0].lower() == 'random')
        self.maxval = DEFAULT_MAXVAL_RANDOM if self.random_order else DEFAULT_MAXVAL_EXHAUSTIVE
        if len(module_argv) > 1: self.vector_reg = module_argv[1]
        if len(module_argv) > 2: self.maxval = int(module_argv[2], 16)
        if len(module_argv) > 3: self.iterations = int(module_argv[3])

        for r in self.gprs:
            self.gprs[r] = self.maxval
        if self.vector_reg is not None:
            self.gprs[self.vector_reg] = DEFAULT_VECTOR_MAXVAL

        self.logger.log("\n[*] Configuration:")
        self.logger.log("    Mode               : {}".format(
            'random' if self.random_order else 'exhaustive'))
        self.logger.log("    Hypercall vector in: {}".format(self.vector_reg))
        self.logger.log("    Max register value : 0x{:X}".format(self.maxval))
        self.logger.log("    Iterations         : {:d}\n".format(
            self.iterations))

        return self.fuzz_generic_hypercalls()