示例#1
0
    def run(self):
        self.dev.init()
        self.clear_txmbufs()
        self.clear_txbds()

        self.tap = TapDriver(self.dev)
        self.tap.__enter__()
        self.tap._link_detect()
        self.test_send(self.tap)
示例#2
0
    def run(self):
        self.dev.init()
        self.clear_txmbufs()
        self.clear_txbds()

        self.tap = TapDriver(self.dev)
        self.tap.__enter__()
        self.tap._link_detect()
        self.test_send(self.tap)
        #self.gate_send()
        #self.test_dmar()
        #self.test_rdmar()
        #self.test_dmaw()
        #self.reg_finder()
        #self.msi_wr()
        #self.asfdiff()
        #self.pxediff()
        #self.pxeidiff()
        #self.read_oprom()
        return 0
示例#3
0
class TestDriver(object):
    def __init__(self, dev):
        self.dev = dev

    def __enter__(self):
        return self

    def __exit__(self, t, v, traceback):
        pass

    def run(self):
        self.dev.init()
        self.clear_txmbufs()
        self.clear_txbds()

        self.tap = TapDriver(self.dev)
        self.tap.__enter__()
        self.tap._link_detect()
        self.test_send(self.tap)
        #self.gate_send()
        #self.test_dmar()
        #self.test_rdmar()
        #self.test_dmaw()
        #self.reg_finder()
        #self.msi_wr()
        #self.asfdiff()
        #self.pxediff()
        #self.pxeidiff()
        #self.read_oprom()
        return 0

    def gate_send(self):
        dev = self.dev

        print "[+] constructing buffer:",
        buf_vaddr = dev.interface.mm.alloc(1024)
        buf = cast(buf_vaddr, POINTER(c_char))
        for b in range(0, 1024, 4):
            buf[b] = '\xde'
            buf[b+1] = '\xad'
            buf[b+2] = '\xbe'
            buf[b+3] = '\xef'
        buf_paddr = dev.interface.mm.get_paddr(buf_vaddr)
        print "vaddr %x, paddr %x" % (buf_vaddr, buf_paddr)

        print "[+] resetting device"
        dev.mem.write_dword(0xe00, 0)
	self.clear_txmbufs()
	self.clear_txbds()
        dev.reset()

        if dev.mem.gencomm.dword[0xac] >> 16 != 0x88b5:
            raise Exception("thundergate firmware does not appear to be runing.")

        print "[+] posting command to local thundergate command window"
        dev.mem.write_dword(0xe04, buf_paddr >> 32)
        dev.mem.write_dword(0xe08, buf_paddr & 0xffffffff)
        dev.mem.write_dword(0xe0c, 0x400)
        dev.mem.write_dword(0xe00, 0x88b5000e)

        print "[+] saving state"
        initial = reutils.state_save(dev)

        print "[+] setting sw event 0"
        dev.grc.rxcpu_event.sw_event_0 = 1

        cntr = 0
        while (dev.grc.rxcpu_event.sw_event_0):
            cntr += 1
            if cntr > 100:
                print "[!] timed out waiting for command completion"
                break
            usleep(100)

        if cntr <= 100:
            print "[+] command completed after usleeping for %d" % (cntr * 100)

        if dev.mem.gencomm.dword[0xac] != 0x88b5000e:
            print "[!] unexpected response: %08x" % dev.mem.gencomm.dword[0xac]

        intermediate = reutils.state_diff(dev, initial)

        for b in range(0, 1024, 4):
            buf[b] = '\xba'
            buf[b+1] = '\xad'
            buf[b+2] = '\xd0'
            buf[b+3] = '\x0d'

        print "[+] setting sw event 0 again"
        dev.grc.rxcpu_event.sw_event_0 = 1

        cntr = 0
        while (dev.grc.rxcpu_event.sw_event_0):
            cntr += 1
            if cntr > 100:
                print "[!] timed out waiting for command completion"
                break
            usleep(100)

        if cntr <= 100:
            print "[+] command completed after usleeping for %d" % (cntr * 100)

        if dev.mem.gencomm.dword[0xac] != 0x88b5000e:
            print "[!] unexpected response: %08x" % dev.mem.gencomm.dword[0xac]

        inter2 = reutils.state_diff(dev, intermediate)
    
        print "[+] constructing new buffer:",
        buf_vaddr = dev.interface.mm.alloc(1024)
        buf = cast(buf_vaddr, POINTER(c_char))
        for b in range(0, 1024, 4):
            buf[b] = '\xab'
            buf[b+1] = '\xcd'
            buf[b+2] = '\xdc'
            buf[b+3] = '\xba'
        buf_paddr = dev.interface.mm.get_paddr(buf_vaddr)
        print "vaddr %x, paddr %x" % (buf_vaddr, buf_paddr)

        dev.mem.write_dword(0xe04, buf_paddr >> 32)
        dev.mem.write_dword(0xe08, buf_paddr & 0xffffffff)

        print "[+] setting sw event 0 again"
        dev.grc.rxcpu_event.sw_event_0 = 1

        cntr = 0
        while (dev.grc.rxcpu_event.sw_event_0):
            cntr += 1
            if cntr > 100:
                print "[!] timed out waiting for command completion"
                break
            usleep(100)

        if cntr <= 100:
            print "[+] command completed after usleeping for %d" % (cntr * 100)

        if dev.mem.gencomm.dword[0xac] != 0x88b5000e:
            print "[!] unexpected response: %08x" % dev.mem.gencomm.dword[0xac]

        final = reutils.state_diff(dev, inter2)
    def pxeidiff(self):
	dev = self.dev
	cpu = dev.rxcpu

	dev.nvram.init(wr=1)
	if dev.nvram.getpxe():
		was_enabled = True
		dev.nvram.setpxe(1)
	else:
		was_enabled = False

        dev.reset(quick=True)
        cpu.mode.halt = 1
        
        nr_is = {}
        for i in range(1000000):
            try: nr_is[cpu.pc] += 1
            except: nr_is[cpu.pc] = 1
            cpu.mode.single_step = 1

        self.norom_insns = nr_is

        dev.reset()
	usleep(1000)
	dev.reset(cold = False)
	usleep(1000)

	dev.nvram.init(wr=1)
	dev.nvram.setpxe()
        dev.reset(quick=True)
        cpu.mode.halt = 1

        print
        print "[!] read rom now"
        print

        r_is = {}
        for i in range(1000000):
            try: r_is[cpu.pc] += 1
            except: r_is[cpu.pc] = 1
            cpu.mode.single_step = 1

        self.rom_insns = r_is

        uniq = []
        more = []

        for i in r_is.keys():
            try:
                diff = r_is[i] - nr_is[i]
                if diff > 0:
                    more += [(i, diff)]
            except:
                uniq += [(i, r_is[i])]

        print "[+] rom-unique insns:"
        for i in uniq:
            print "\t%08x: %d" % (i[0], i[1])

    def read_oprom(self, count = 4):
        dev = self.dev
        bdf = dev.interface.bdf
        words = []
        print "[+] reading oprom..."
        with file("/sys/bus/pci/devices/%s/rom" % bdf, "rb+") as rom:
            try:
                x = rom.read(4)
            except:
                print "[+] enabling oprom"
                rom.write("1")
                x = rom.read(4)

            words += [unpack(">I", x)[0]]

            for ofs in range(4, count, 4):
                x = rom.read(4)

                words += [unpack(">I", x)[0]]

        print "[+] last word read: %08x" % unpack(">I", x)[0]
        return words

    def pxediff(self):
	dev = self.dev
	cpu = dev.rxcpu

	dev.nvram.init(wr=1)
	if dev.nvram.getpxe():
		was_enabled = True
		dev.nvram.setpxe(1)
	else:
		was_enabled = False

	dev.reset()
	sleep(5)
	
	initial = reutils.state_save(dev)

	dev.reset()
	usleep(1000)

	dev.nvram.init(wr=1)
	dev.nvram.setpxe()
        dev.reset()

        print "[+] press any key to continue..."
        raw_input()
        dev.interface.reattach()
        dev.init()

        self.read_oprom()
	wpxe = reutils.state_diff(dev, initial)

        dev.reset(quick=True)
        cpu.mode.halt = 1
        wpxei = reutils.state_diff(dev, wpxe)

	if not was_enabled:
                dev.reset()
		dev.nvram.init(wr=1)
		dev.nvram.setpxe(1)
		dev.reset()

    def asfdiff(self):
	dev = self.dev
	cpu = dev.rxcpu

	dev.nvram.init(wr=1)
	if dev.nvram.getasf():
		was_enabled = True
		dev.nvram.setasf(1)
	else:
		was_enabled = False

	self.clear_txmbufs()
	self.clear_txbds()
	dev.reset()
	sleep(5)
	
	cpu.halt()
	initial = reutils.state_save(dev)

	dev.reset()
	usleep(1000)
	dev.reset(cold = False)
	usleep(1000)

	dev.nvram.init(wr=1)
	dev.nvram.setasf()
	self.clear_txmbufs()
	self.clear_txbds()
	
	dev.reset()
	sleep(5)
	
	cpu.halt()
	wasf = reutils.state_diff(dev, initial)

	if not was_enabled:
		dev.nvram.init(wr=1)
		dev.nvram.setasf(1)
		dev.reset()

    def clear_txmbufs(self):
        for i in range(0x8000, 0x10000, 4):
            self.dev.mem.write_dword(i, 0)

    def clear_txbds(self):
        for i in range(0x4000, 0x4800, 4):
            self.dev.mem.write_dword(i, 0)

    def block_pump(self, block):
        bn = block.block_name
        if bn.endswith("_x"):
            bn = bn[:-2]
        if bn.endswith("_regs"):
            bn = bn[:-5]
        print "[+] pumping %s" % bn
        block.block_enable(quiet = 1)
        usleep(10)
        block.block_disable(quiet = 1)

    def msi_wr(self):
        dev = self.dev
        dev.rxcpu.halt()
        dev.bufman.block_enable()
        dev.wdma.block_enable()

        test_buf_v = dev.interface.mm.alloc(8)
        cast(test_buf_v, POINTER(c_uint64))[0] = ~0
        test_buf_p = dev.interface.mm.get_paddr(test_buf_v)
        print "test buf is at %x" % test_buf_p
        print "test buf starts %s" % repr(cast(test_buf_v, POINTER(c_char * 8)).contents.raw)

        dev.pci.msi_lower_address = test_buf_p & 0xffffffff
        dev.pci.msi_upper_address = test_buf_p >> 32
        dev.pci.msi_data = 0xaaaa
        dev.msi.mode.msi_message = 0x7 
        dev.pci.msi_cap_hdr.msi_enable = 1
        dev.msi.status.msi_pci_request = 1
        usleep(1000)
        print "test buf is now %s" % repr(cast(test_buf_v, POINTER(c_char * 8)).contents.raw)

        
        for tl in (False, True):
            for pl in (False, True):
                for hi in (False, True):
                    dev.grc.mode.pcie_tl_sel = 1 if tl else 0
                    dev.grc.mode.pcie_pl_sel = 1 if pl else 0
                    dev.grc.mode.pcie_hi1k_en = 1 if hi else 0

                    for i in range(0x7c00, 0x8000, 4):
                        if 0 == i % 32:
                            print
                            print "%04x'%d%d%d: " % (i, 1 if hi else 0, 1 if pl else 0, 1 if tl else 0),
                        elif 0 == i % 16:
                            print "\t",
                        print "%08x" % dev.reg[i >> 2],

    def spy_read(self, tap):
        dev = self.dev
        dev.sbdi.block_disable()
        dev.sbdc.block_disable()
        dev.sbds.block_disable()
        dev.sdi.block_disable()
        dev.sdc.block_disable()
        dev.rxcpu.halt()

        state = reutils.state_save(dev)

        test_buf_v = dev.interface.mm.alloc(128)
        test_buf_p = dev.interface.mm.get_paddr(test_buf_v)
        print "[+] allocated test buffer at vaddr %x, paddr %x" % (test_buf_v, test_buf_p)
        for i in range(128):
            cast(test_buf_v, POINTER(c_char))[i] = '\xb4'

        dev.mem.txbd[0].addr_hi = test_buf_p >> 32
        dev.mem.txbd[0].addr_low = test_buf_p & 0xffffffff
        
        dev.mem.txbd[0].flags.l4_cksum_offload = 0
        dev.mem.txbd[0].flags.ip_cksum_offload = 0
        dev.mem.txbd[0].flags.jumbo_frame = 0
        dev.mem.txbd[0].flags.hdrlen_2 = 0
        dev.mem.txbd[0].flags.snap = 0
        dev.mem.txbd[0].flags.vlan_tag = 0
        dev.mem.txbd[0].flags.coalesce_now = 0
        dev.mem.txbd[0].flags.cpu_pre_dma = 0
        dev.mem.txbd[0].flags.cpu_post_dma = 0
        dev.mem.txbd[0].flags.hdrlen_3 = 0
        dev.mem.txbd[0].flags.hdrlen_4 = 0
        dev.mem.txbd[0].flags.hdrlen_5 = 0
        dev.mem.txbd[0].flags.hdrlen_6 = 0
        dev.mem.txbd[0].flags.hdrlen_7 = 0
        dev.mem.txbd[0].flags.no_crc = 0
        dev.mem.txbd[0].flags.packet_end = 1

        dev.mem.txbd[0].length = 64
        dev.mem.txbd[0].vlan_tag = 0
        dev.mem.txbd[0].reserved = 0

        print "[+] txbd[0] forged"
        state = reutils.state_diff(dev, state)

        dev.sbdi.ofs_48 = 0x210
        print "[+] sbdi mailbox msg delivered"
        state = reutils.state_diff(dev, state)


        self.block_pump(dev.sdi)
        state = reutils.state_diff(dev, state)

    def test_send(self, tap):
        dev = self.dev
        tap._link_detect()
        dev.rxcpu.halt()
        
        #dev.sbds.block_disable()
        #dev.sdi.block_disable()
        #dev.sdc.block_disable()
        #dev.sbds.reset()
        #dev.sdi.reset()
        #dev.sdc.reset()


        print "[+] saving initial state"
        state = reutils.state_save(dev)
        
        print "[+] submitting test packet to tap driver"
        tap.send('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x88\xb5' + ('\xaa\x55' * 25)) #, flags=("cpu_post_dma"))
        usleep(10)
        state = reutils.state_diff(dev, state)

	    #dev.sdc.block_enable()
        #dev.sdi.block_enable()
        #dev.sbds.block_enable()
        #usleep(10)

        #state = reutils.state_diff(dev, state)

    def test_rdmar(self, init=1, reset=0):
        dev = self.dev
        dev.reset()

        print "[+] testing remote dma read"

        vaddr = dev.interface.mm.alloc(8)
        paddr = dev.interface.mm.get_paddr(vaddr)
        buf = ctypes.cast(vaddr, ctypes.POINTER(ctypes.c_uint32))

        buf[0] = 0xdeadbeee
        buf[1] = 0xdeadbeef

        cnt = 0

        while dev.mem.read_dword(0xb50) >> 16 != 0x88b5:
            cnt += 1
            if cnt > 10000:
                print "[-] fw signature not found in gencomm"
                return
            usleep(10)

        dev.mem.write_dword(0xb54, paddr >> 32)
        dev.mem.write_dword(0xb58, paddr & 0xffffffff)
        dev.mem.write_dword(0xb50, 0x88b50007)

        while dev.mem.read_dword(0xb50) & 0xff:
            pass

        if buf[0] != dev.mem.read_dword(0xb54) or buf[1] != dev.mem.read_dword(0xb58):
            print "[-] remote dma read test failed"
        else:
            print "[+] remote dma read test complete"

        dev.interface.mm.free(vaddr)

    def test_dmar(self, size=0x80, init=1, reset=0):
        dev = self.dev
        dev.rxcpu.halt()
        dev.bufman.block_enable()
        dev.grc.mode.pcie_tl_sel = 0
        dev.grc.mode.pcie_pl_sel = 1
        dev.grc.mode.pcie_hi1k_en = 1
        dev.hpmb.box[tg.mb_rbd_standard_producer].low = 0
        
        end = 0x6000 + (size * 4)
        print "[+] clearing device memory from 0x6000 to 0x%04x" % end
        for i in range(0x6000, end, 4):
                dev.mem.write_dword(i, 0)

        for i in range(0x6000, end, 4):
                if dev.mem.read_dword(i) != 0:
                        raise Exception("buffer not clear")
        
        print "[+] zapping rdi std rcb"
        dev.rdi.std_rcb.host_addr_hi = 0
        dev.rdi.std_rcb.host_addr_low = 0
        dev.rdi.std_rcb.ring_size = 0
        dev.rdi.std_rcb.max_frame_len = 0
        dev.rdi.std_rcb.disable_ring = 0
        dev.rdi.std_rcb.nic_addr = 0

        vaddr = dev.interface.mm.alloc(4 * size)
        paddr = dev.interface.mm.get_paddr(vaddr)
        buf = ctypes.cast(vaddr, ctypes.POINTER(ctypes.c_uint32))

        for i in range(size):
                buf[i] = 0xaabbccdd;
        
        state = reutils.state_save(dev)

        print "[+] setting up standard rcb"

        dev.rdi.std_rcb.host_addr_hi = (paddr >> 32)
        dev.rdi.std_rcb.host_addr_low = (paddr & 0xffffffff)
        dev.rdi.std_rcb.ring_size = 0x200
        dev.rdi.std_rcb.max_frame_len = 0
        dev.rdi.std_rcb.disable_ring = 0
        dev.rdi.std_rcb.nic_addr = 0x6000
        
        state = reutils.state_diff(dev, state)

        print "[+] initiating dma read of sz %x to buffer at vaddr %x, paddr %x" % (size, vaddr, paddr)
        dev.hpmb.box[tg.mb_rbd_standard_producer].low = size >> 3

        blocks = ["rbdi", "rdma"]
        for b in blocks:
                o = getattr(dev, b)
                o.block_enable(reset=reset)
                state = reutils.state_diff(dev, state)
        
        for i in range(0x6000, end, 4):
                if dev.mem.read_dword(i) != buf[(i - 0x6000) >> 2]:
                        raise Exception("dma read test failed")

        print "[+] dma read test complete"

        dev.interface.mm.free(vaddr)

    def test_dmaw(self):
        dev = self.dev
        dev.rxcpu.halt()
        dev.bufman.block_enable()
        dev.grc.mode.pcie_tl_sel = 1
        dev.grc.mode.pcie_pl_sel = 0
        dev.grc.mode.pcie_hi1k_en = 0

        buf_v = dev.interface.mm.alloc(0x80)
        buf_p = dev.interface.mm.get_paddr(buf_v)
        sbuf = cast(buf_v, POINTER(c_char * 0x80))

        dev.wdma.block_disable()
        dev.wdma.reset()

        dev.hc.block_disable()
        dev.hc.reset()

        state = reutils.state_save(dev)

        dev.hc.nic_diag_sbd_ci[0] = 4
        dev.hc.status_block_host_addr_hi = buf_p >> 32
        dev.hc.status_block_host_addr_low = buf_p & 0xffffffff
        dev.hc.mode.no_int_on_force_update = 1

        for i in range(0x3d00, 0x3e00, 4):
            dev.reg[i >> 2] = 0xffffffff
        dev.reg[0x3f04 >> 2] = 0xffffffff

        state = reutils.state_diff(dev, state) 

        print "[*] coalescing"
        dev.hc.mode.coalesce_now = 1
        state = reutils.state_diff(dev, state)

        print "[*] status block is now"
        print "    %s" % repr(sbuf.contents.raw)
        print


        dev.wdma.block_enable()
        state = reutils.state_diff(dev, state)

        print "[*] status block is now"
        print "    %s" % repr(sbuf.contents.raw)
        print
       
        print "[*] coalescing"
        dev.hc.mode.coalesce_now = 1
        state = reutils.state_diff(dev, state)

        print "[*] status block is now"
        print "    %s" % repr(sbuf.contents.raw)
        print

    def reg_finder(self):
        dev = self.dev
        regs = {}
        with open('regs.csv', 'wb') as csvfile:
            fns = ['offset', 'block', 'name', 'rw', 'mod_mask', 'o', 't1', 't2']
            w = csv.DictWriter(csvfile, fieldnames=fns)
            w.writeheader()

            for dl in (True, False):
                for pl in (True, False):
                    for hi1k in (True, False):
                        dev.grc.mode.pcie_dl_sel = 1 if dl else 0
                        dev.grc.mode.pcie_pl_sel = 1 if pl else 0
                        dev.grc.mode.pcie_hi1k_en = 1 if hi1k else 0
                        ss = "%s%s%s" % ("d" if dl else "",
                                         "p" if pl else "",
                                         "h" if hi1k else "")

                        for i in range(0x7c00, 0x8000, 4):
                            ofs = "%04x%s" % (i, ss)
                            bn = reutils.whats_at(i)
                            regs[ofs] = {'block': 'pcie_win',
                                       'name': 'ofs_%03x' % (i - 0x7c00),
                                       'offset': ofs,
                                       'rw': '',
                                       'mod_mask': '',
                                       'o': '', 't1': '', 't2': ''}

                            o = dev.reg[i >> 2]
                            if o == 0xffffffff:
                                if dev.reg[0] == 0xffffffff:
                                    raise Exception("device quit bus")

                            if False:
                                dev.reg[i >> 2] = 0xffffffff
                                t1 = dev.reg[i >> 2]
                                dev.reg[i >> 2] = 0
                                t2 = dev.reg[i >> 2]
                                dev.reg[i >> 2] = o
                                regs[ofs]['t1'] = "%08x" % t1
                                regs[ofs]['t2'] = "%08x" % t2
                                if (o ^ t1) or (o ^ t2):
                                    regs[ofs]['rw'] = True
                                    regs[ofs]['mod_mask'] = "%08x" % (~(t2 | ~t1))
                            
                            regs[ofs]['o'] = "%08x" % o
                            
                            w.writerow(regs[ofs])
                            csvfile.flush()

            for i in range(0x100, 0x7c00, 4):
                if i % 0x400 == 0:
                    print "now at %04x" % i
                if 0 == os.system("dmesg -c | grep -q dmar"):
                    raise Exception("noticed dmar freaking out at %04x" % i)

                bn = reutils.whats_at(i)
                regs[i] = {'block': bn[0],
                           'name': bn[1],
                           'offset': "%04x" % i,
                           'rw': False,
                           'mod_mask': '',
                           'o': '', 't1': '', 't2': ''}

                o = dev.reg[i >> 2]
                if o == 0xffffffff:
                    if dev.reg[0] == 0xffffffff:
                        raise Exception("device quit bus")

                if (i < 0x3600 or i > 0x36e8) and (i < 0x6800 or i > 0x68fc):
                    dev.reg[i >> 2] = 0xffffffff
                    t1 = dev.reg[i >> 2]
                    dev.reg[i >> 2] = 0
                    t2 = dev.reg[i >> 2]
                    dev.reg[i >> 2] = o

                regs[i]['o'] = "%08x" % o
                try:
                    regs[i]['t1'] = "%08x" % t1
                    regs[i]['t2'] = "%08x" % t2
                    if (o ^ t1) or (o ^ t2):
                        regs[i]['rw'] = True
                        regs[i]['mod_mask'] = "%08x" % (~(t2 | ~t1))
                except:
                    pass

                if regs[i]['name'].startswith('ofs') and regs[i]['rw']:
                    print "Unknown rw register at %04x" % i

                w.writerow(regs[i])


        return regs
示例#4
0
                         )[0] in "yY":
                args.backup = True

    with Device(dev_interface) as dev:
        if args.backup:
            dev.nvram.init()
            dev.nvram.dump_eeprom("eeprom.bak")
            print "[+] eeprom backup saved as 'eeprom.bak'"

        if args.install:
            with TgInstaller(dev) as i:
                i.run()
        elif args.shell:
            with ShellDriver(dev) as shell:
                if args.driver:
                    with TapDriver(dev) as tap:
                        shell.run(loc=locals())
                elif args.tests:
                    with TestDriver(dev) as test:
                        test.run()
                        shell.run(loc=locals())
                else:
                    shell.run(loc=locals())
        else:
            if args.driver:
                with TapDriver(dev) as tap:
                    tap.run()
            elif args.tests:
                with TestDriver(dev) as test:
                    test.run()