コード例 #1
0
def init_loader_db():
    loaderdb = {}
    for (dirpath, dirnames, filenames) in os.walk("Loaders"):
        for filename in filenames:
            file_name = os.path.join(dirpath, filename)
            found = False
            for ext in [".bin", ".mbn", ".elf"]:
                if ext in filename[-4:]:
                    found = True
                    break
            if not found:
                continue
            try:
                hwid = filename.split("_")[0].lower()
                msmid = hwid[:8]
                devid = hwid[8:]
                pkhash = filename.split("_")[1].lower()
                msmid = convertmsmid(msmid)
                mhwid = convertmsmid(msmid) + devid
                if mhwid not in loaderdb:
                    loaderdb[mhwid] = {}
                if pkhash not in loaderdb[mhwid]:
                    loaderdb[mhwid][pkhash] = file_name
                else:
                    loaderdb[mhwid][pkhash].append(file_name)
            except:
                continue
    return loaderdb
コード例 #2
0
def is_duplicate(loaderdb, sign_info):
    lhash = sign_info.pk_hash[:16].lower()
    msmid = sign_info.hw_id[:8].lower()
    devid = sign_info.hw_id[8:].lower()
    hwid = sign_info.hw_id.lower()
    rid = (convertmsmid(msmid) + devid).lower()
    if hwid in loaderdb:
        loader = loaderdb[hwid]
        if lhash in loader:
            return True
    if rid in loaderdb:
        loader = loaderdb[rid]
        if lhash in loader:
            return True
    return False
コード例 #3
0
def main(argv):
    file_list = []
    path = ""
    if len(argv) < 3:
        print("Usage: ./fhloaderparse.py [FHLoaderDir] [OutputDir]")
        exit(0)
    else:
        path = argv[1]
        outputdir = argv[2]
        if not os.path.exists(outputdir):
            os.mkdir(outputdir)

    # First hash all loaders in Loader directory
    hashes = {}
    loaderdb = init_loader_db()
    for mhwid in loaderdb:
        for pkhash in loaderdb[mhwid]:
            fname = loaderdb[mhwid][pkhash]
            with open(fname, 'rb') as rhandle:
                data = rhandle.read()
                sha256 = hashlib.sha256()
                sha256.update(data)
                hashes[sha256.digest()] = fname

    # Now lets hash all files in the output directory
    for (dirpath, dirnames, filenames) in walk(outputdir):
        for filename in filenames:
            fname = os.path.join(dirpath, filename)
            with open(fname, 'rb') as rhandle:
                data = rhandle.read()
                sha256 = hashlib.sha256()
                sha256.update(data)
                hashes[sha256.digest()] = fname

    # Now lets search the input path for loaders
    extensions = ["elf", "mbn", "bin", "hex"]
    for (dirpath, dirnames, filenames) in walk(path):
        for filename in filenames:
            basename = os.path.basename(filename).lower()
            ext = basename[basename.rfind(".") + 1:]
            if ext in extensions:
                file_list.append(os.path.join(dirpath, filename))

    if not os.path.exists(os.path.join(outputdir, "Unknown")):
        os.makedirs(os.path.join(outputdir, "Unknown"))
    if not os.path.exists(os.path.join(outputdir, "Duplicate")):
        os.mkdir(os.path.join(outputdir, "Duplicate"))

    # Lets hash all the input files and extract the signature
    filelist = []
    rt = open(os.path.join(outputdir, argv[1] + ".log"), "w")
    for filename in file_list:
        with open(filename, 'rb') as rhandle:
            mem_section = rhandle.read()
            sha256 = hashlib.sha256()
            sha256.update(mem_section)

            signinfo = Signed()
            signinfo.hash = sha256.digest()
            signinfo.filename = filename
            signinfo.filesize = os.stat(filename).st_size
            if len(mem_section) < 4:
                continue
            hdr = unpack("<I", mem_section[0:4])[0]

            if hdr == 0x464C457F:
                elfheader = elf(mem_section, signinfo.filename)
                if 'memorylayout' in dir(elfheader):
                    memsection = elfheader.memorylayout[1]
                    try:
                        version = unpack(
                            "<I", mem_section[memsection.file_start_addr +
                                              0x04:memsection.file_start_addr +
                                              0x04 + 0x4])[0]
                        code_size = \
                            unpack("<I", mem_section[
                                         memsection.file_start_addr + 0x14:memsection.file_start_addr + 0x14 + 0x4])[
                                0]
                        signature_size = \
                            unpack("<I", mem_section[
                                         memsection.file_start_addr + 0x1C:memsection.file_start_addr + 0x1C + 0x4])[
                                0]
                        # cert_chain_size=unpack("<I", mem_section[memsection.file_start_addr + 0x24:memsection.file_start_addr + 0x24 + 0x4])[0]
                    except:
                        continue
                    if signature_size == 0:
                        print("%s has no signature." % filename)
                        copyfile(
                            filename,
                            os.path.join(
                                outputdir, "Unknown",
                                filename[filename.rfind("/") + 1:].lower()))
                        continue
                    if version < 6:  # MSM,MDM
                        signatureoffset = memsection.file_start_addr + 0x28 + code_size + signature_size
                        signinfo = extract_old_hdr(signatureoffset, signinfo,
                                                   mem_section, code_size,
                                                   signature_size)
                        if signinfo is None:
                            continue
                        filelist.append(signinfo)
                    elif version >= 6:  # SDM
                        signinfo = extract_hdr(memsection, signinfo,
                                               mem_section, code_size,
                                               signature_size)
                        if signinfo is None:
                            continue
                        filelist.append(signinfo)
                    else:
                        print("Unknown version for " + filename)
                        continue
            elif hdr == 0x844BDCD1:
                mbn = MBN(mem_section)
                if mbn.sigsz == 0:
                    print("%s has no signature." % filename)
                    copyfile(
                        filename,
                        os.path.join(
                            outputdir, "Unknown",
                            filename[filename.rfind("/") + 1:].lower()))
                    continue
                signatureoffset = mbn.imagesrc + mbn.codesz + mbn.sigsz
                signinfo = extract_old_hdr(signatureoffset, signinfo,
                                           mem_section, mbn.codesz, mbn.sigsz)
                if signinfo is None:
                    continue
                filelist.append(signinfo)
            else:
                print("Error on " + filename)
                continue

    sorted_x = sorted(filelist, key=lambda x: (x.hw_id, -x.filesize))

    class loaderinfo:
        hw_id = ''
        item = ''

    loaderlists = {}
    for item in sorted_x:
        if item.oem_id != '':
            oemid = int(item.oem_id, 16)
            if oemid in vendor:
                oeminfo = vendor[oemid]
            else:
                oeminfo = item.oem_id
            if len(item.sw_id) < 16:
                item.sw_id = "0" * (16 - len(item.sw_id)) + item.sw_id
            info = f"OEM:{oeminfo}\tMODEL:{item.model_id}\tHWID:{item.hw_id}\tSWID:{item.sw_id}\tSWSIZE:{item.sw_size}\tPK_HASH:{item.pk_hash}\t{item.filename}\t{str(item.filesize)}"
            if item.oem_version != '':
                info += "\tOEMVER:" + item.oem_version + "\tQCVER:" + item.qc_version + "\tVAR:" + item.image_variant
            loader_info = loaderinfo()
            loader_info.hw_id = item.hw_id
            loader_info.pk_hash = item.pk_hash
            if item.hash not in hashes:
                if loader_info not in loaderlists:
                    if not is_duplicate(loaderdb, item):
                        loaderlists[loader_info] = item.filename
                        print(info)
                        msmid = loader_info.hw_id[:8]
                        devid = loader_info.hw_id[8:]
                        for msmid in convertmsmid(msmid):
                            hwid = (msmid + devid).lower()
                            auth = ""
                            with open(item.filename, "rb") as rf:
                                data = rf.read()
                                if b"sig tag can" in data:
                                    auth = "_EDLAuth"
                                if b"peek\x00" in data:
                                    auth += "_peek"
                            fna = os.path.join(
                                outputdir,
                                (hwid + "_" + loader_info.pk_hash[0:16] +
                                 "_FHPRG" + auth + ".bin").lower())
                            if not os.path.exists(fna):
                                copyfile(
                                    item.filename,
                                    os.path.join(
                                        outputdir, hwid + "_" +
                                        (loader_info.pk_hash[0:16] + "_FHPRG" +
                                         auth + ".bin").lower()))
                            elif item.filesize > os.stat(fna).st_size:
                                copyfile(
                                    item.filename,
                                    os.path.join(
                                        outputdir,
                                        (hwid + "_" +
                                         loader_info.pk_hash[0:16] + "_FHPRG" +
                                         auth + ".bin").lower()))
                    else:
                        print("Duplicate: " + info)
                        copyfile(
                            item.filename,
                            os.path.join(outputdir, "Duplicate",
                                         (loader_info.hw_id + "_" +
                                          loader_info.pk_hash[0:16] +
                                          "_FHPRG.bin").lower()))
                else:
                    copyfile(
                        item.filename,
                        os.path.join(outputdir, "Unknown",
                                     os.path.basename(item.filename).lower()))
            else:
                copyfile(
                    item.filename,
                    os.path.join(outputdir, "Duplicate",
                                 (loader_info.hw_id + "_" +
                                  loader_info.pk_hash[0:16] +
                                  "_FHPRG.bin").lower()))
                print(item.filename + " does already exist. Skipping")
            try:
                rt.write(info + "\n")
            except:
                continue
        else:
            print("Unknown :" + item.filename)
            copyfile(
                item.filename,
                os.path.join(outputdir, "Unknown",
                             os.path.basename(item.filename).lower()))

    for item in filelist:
        if item.oem_id == '' and (".bin" in item.filename or ".mbn"
                                  in item.filename or ".hex" in item.filename):
            info = "Unsigned:" + item.filename + "\t" + str(item.filesize)
            if item.oem_version != '':
                info += "\tOEMVER:" + item.oem_version + "\tQCVER:" + item.qc_version + "\tVAR:" + item.image_variant
            print(info)
            rt.write(info + "\n")
            if not os.path.exists(
                    os.path.join(outputdir, "Unknown", item.filename)):
                copyfile(
                    item.filename,
                    os.path.join(outputdir, "Unknown",
                                 os.path.basename(item.filename).lower()))

    rt.close()
コード例 #4
0
def main(argv):
    file_list = []
    path = ""
    if len(argv) < 3:
        print("Usage: ./fhloaderparse.py [FHLoaderDir] [OutputDir]")
        exit(0)
    else:
        path = argv[1]
        outputdir = argv[2]
        if not os.path.exists(outputdir):
            os.mkdir(outputdir)

    loaderdb = init_loader_db()
    for (dirpath, dirnames, filenames) in walk(path):
        for filename in filenames:
            file_list.append(os.path.join(dirpath, filename))

    hashes = {}
    for (dirpath, dirnames, filenames) in walk(outputdir):
        for filename in filenames:
            fname = os.path.join(dirpath, filename)
            with open(fname, 'rb') as rhandle:
                data = rhandle.read()
                sha256 = hashlib.sha256()
                sha256.update(data)
                hashes[sha256.digest()] = fname

    filelist = []
    rt = open(os.path.join(outputdir, argv[1] + ".log"), "w")
    extensions = ["elf", "mbn", "bin"]
    if not os.path.exists(os.path.join(outputdir, "unknown")):
        os.makedirs(os.path.join(outputdir, "unknown"))
    for filename in file_list:
        found = False
        for ext in extensions:
            if "." + ext in filename:
                found = True
                break
        if found != True:
            continue
        with open(filename, 'rb') as rhandle:
            mem_section = rhandle.read()
            sha256 = hashlib.sha256()
            sha256.update(mem_section)

            signinfo = Signed()
            signinfo.hash = sha256.digest()
            signinfo.filename = filename
            signinfo.filesize = os.stat(filename).st_size
            if len(mem_section) < 4:
                continue
            hdr = struct.unpack("<I", mem_section[0:4])[0]
            '''
            if  hdr == 0x844BDCD1:  # mbn
                signatureoffset = struct.unpack("<I", mem_section[0x14:0x18])[0] + struct.unpack("<I", mem_section[0x20:0x24])[0] + \
                                  struct.unpack("<I", mem_section[0x28:0x2C])[0]
                if struct.unpack("<I", mem_section[0x28:0x2C])[0] == 0:
                    signatureoffset = -1
            '''
            if hdr == 0x464C457F:
                elfheader = elf(mem_section, signinfo.filename)
                if 'memorylayout' in dir(elfheader):
                    memsection = elfheader.memorylayout[1]
                    try:
                        version = struct.unpack(
                            "<I", mem_section[memsection.file_start_addr +
                                              0x04:memsection.file_start_addr +
                                              0x04 + 0x4])[0]
                        code_size = \
                            struct.unpack("<I", mem_section[
                                                memsection.file_start_addr + 0x14:memsection.file_start_addr + 0x14 + 0x4])[
                                0]
                        signature_size = \
                            struct.unpack("<I", mem_section[
                                                memsection.file_start_addr + 0x1C:memsection.file_start_addr + 0x1C + 0x4])[
                                0]
                        # cert_chain_size=struct.unpack("<I", mem_section[memsection.file_start_addr + 0x24:memsection.file_start_addr + 0x24 + 0x4])[0]
                    except:
                        continue
                    if signature_size == 0:
                        print("%s has no signature." % filename)
                        continue
                    if version < 6:  # MSM,MDM
                        signinfo = extract_old_hdr(memsection, signinfo,
                                                   mem_section, code_size,
                                                   signature_size)
                        if signinfo is None:
                            continue
                        filelist.append(signinfo)
                    elif version >= 6:  # SDM
                        signinfo = extract_hdr(memsection, signinfo,
                                               mem_section, code_size,
                                               signature_size)
                        if signinfo is None:
                            continue
                        filelist.append(signinfo)
                    else:
                        print("Unknown version for " + filename)
                        continue
            else:
                print("Error on " + filename)
                continue

    sorted_x = sorted(filelist, key=lambda x: (x.hw_id, -x.filesize))

    class loaderinfo:
        hw_id = ''
        item = ''

    if not os.path.exists(os.path.join(outputdir, "Duplicate")):
        os.mkdir(os.path.join(outputdir, "Duplicate"))
    loaderlists = {}
    for item in sorted_x:
        if item.oem_id != '':
            info = f"OEM:{item.oem_id}\tMODEL:{item.model_id}\tHWID:{item.hw_id}\tSWID:{item.sw_id}\tSWSIZE:{item.sw_size}\tPK_HASH:{item.pk_hash}\t{item.filename}\t{str(item.filesize)}"
            if item.oem_version != '':
                info += "\tOEMVER:" + item.oem_version + "\tQCVER:" + item.qc_version + "\tVAR:" + item.image_variant
            loader_info = loaderinfo()
            loader_info.hw_id = item.hw_id
            loader_info.pk_hash = item.pk_hash
            if item.hash not in hashes:
                if loader_info not in loaderlists:
                    if not is_duplicate(loaderdb, item):
                        loaderlists[loader_info] = item.filename
                        print(info)
                        msmid = loader_info.hw_id[:8]
                        devid = loader_info.hw_id[8:]
                        hwid = convertmsmid(msmid) + devid
                        copyfile(
                            item.filename,
                            os.path.join(
                                outputdir, hwid + "_" +
                                loader_info.pk_hash[0:16] + "_FHPRG.bin"))
                    else:
                        print("Duplicate: " + info)
                        copyfile(
                            item.filename,
                            os.path.join(
                                outputdir, "Duplicate",
                                loader_info.hw_id + "_" +
                                loader_info.pk_hash[0:16] + "_FHPRG.bin"))
                else:
                    copyfile(
                        item.filename,
                        os.path.join(
                            outputdir, "unknown",
                            item.filename[item.filename.rfind("\\") + 1:] +
                            "_" + loader_info.pk_hash[0:16] + "_FHPRG.bin"))
            else:
                print(item.filename + " does already exist. Skipping")
            try:
                rt.write(info + "\n")
            except:
                continue

    for item in filelist:
        if item.oem_id == '' and (".bin" in item.filename or ".mbn"
                                  in item.filename or ".hex" in item.filename):
            info = "Unsigned:" + item.filename + "\t" + str(item.filesize)
            if item.oem_version != '':
                info += "\tOEMVER:" + item.oem_version + "\tQCVER:" + item.qc_version + "\tVAR:" + item.image_variant
            print(info)
            rt.write(info + "\n")
            copyfile(
                item.filename,
                os.path.join(outputdir, "unknown",
                             item.filename[item.filename.rfind("\\") + 1:]))

    rt.close()