Esempio n. 1
0
class CmdXmitState(CmdLoadELF):
    keywords = ["xmitstate"]
    description = "Sets a hook on a function, emmits an executable state and add the dump to frankenstein"

    parser = argparse.ArgumentParser(prog=keywords[0], description=description)

    parser.add_argument("target", help="Target function", type=auto_int)

    """
    Receive state dump
    """
    def xmit_state_hci_callback(self, record):
        hcipkt = record[0]
        if not issubclass(hcipkt.__class__, hci.HCI_Event):
            return

        #State report
        if hcipkt.event_code == 0xfc:
            saved_regs, cont = struct.unpack("II", hcipkt.data[:8])
            if cont != 0:
                log.info("Receiving firmware state: regs@0x%x cont@0x%x" % (saved_regs, cont))
                self.segment_data = []
                self.segments = {}
                self.succsess = True
                self.saved_regs = saved_regs
                self.cont = cont

            else:
                if not self.succsess:
                    return
                log.info("Received fuill firmware state")

                groupName = datetime.now().strftime("internalBlue_%m.%d.%Y_%H.%M.%S")
                self.project = Project("projects/"+self.internalblue.fw.FW_NAME)
                self.project.add_group(groupName)
                self.project.deactivate_all_groups()
                self.project.set_active_group(groupName, True)
                self.project.save()
                self.project.add_symbol(groupName, "cont", self.cont|1)
                self.project.add_symbol(groupName, "get_int", symbols["get_int"])
                self.project.add_symbol(groupName, "set_int", symbols["set_int"])
                self.project.add_symbol(groupName, "saved_regs", self.saved_regs)
                for segment_addr in self.segments:
                    self.project.add_segment(groupName, "", segment_addr, "".join(self.segments[segment_addr]))

                self.project.save()

        if hcipkt.event_code == 0xfb:
            segment_addr,size,current = struct.unpack("III", hcipkt.data[:12])
            self.segment_data += [hcipkt.data[12:]]

            #Check if we have missed an HCI event
            if segment_addr + len(self.segment_data)*128 != current + 128:
                if self.succsess:
                    print( hex(segment_addr), hex(len(self.segment_data)*128), hex( current + 128))
                    log.info("Failed to receive state")
                self.succsess = False
                
            #Fully received memory dumo
            if len(self.segment_data)*128 == size:
                log.info("Received segment 0x%x - 0x%x" % (segment_addr, segment_addr+size))
                self.segments[segment_addr] = self.segment_data
                self.segment_data = []

    """
    Command implementation
    """
    def work(self):
        args = self.getArgs()
        if not args:
            return True

        # Initialize callbacks for xmitstate
        global CmdXmitStateInitialized

        if not CmdXmitStateInitialized:

            # disable uart_SetRTSMode if we know its location
            if self.internalblue.fw.FW_NAME == "CYW20735B1":
                self.internalblue.patchRom(0x3d32e, b"\x70\x47\x70\x47")
            elif self.internalblue.fw.FW_NAME == "CYW20819A1":
                self.internalblue.patchRom(0x2330e, b"\x70\x47\x70\x47")

            # and now let's enable the callbacks
            self.internalblue.registerHciCallback(self.debug_hci_callback)
            self.internalblue.registerHciCallback(self.xmit_state_hci_callback)
            CmdXmitStateInitialized = True


        patch = "projects/%s/gen/xmit_state.patch" % self.internalblue.fw.FW_NAME
        print(patch)
        if not os.path.exists(patch):
            log.warn("Could not find file %s" % patch)
            return False

        entry = self.load_ELF(patch)
        if entry == False:
            log.warn("Failed to load patch ELF %s" % patch)
            return False

        target = struct.pack("I", args.target | 1)
        self.writeMem(symbols["xmit_state_target"], target)

        self.launchRam(entry-1)

        return entry != False