Example #1
0
def generate_r_file(new_package_name: str) -> bool:
    """
    use all new resources to generate the new R.java, and compile it ,then copy it to the target smali dir
    :param new_package_name:
    :param decompile_dir:
    :return:
    """
    decompile_dir = FPath.DECOMPILE_PATH
    if not check_value_resources(decompile_dir):
        return False

    temp_path = os.path.dirname(decompile_dir)
    temp_path = temp_path + "/temp"

    if os.path.exists(temp_path):
        fio.del_file_folder(temp_path)
    if not os.path.exists(temp_path):
        os.makedirs(temp_path)

    res_path = os.path.join(decompile_dir, "res")
    target_res_path = os.path.join(temp_path, "res")
    fio.copy_files(res_path, target_res_path)

    gen_path = os.path.join(temp_path, "gen")
    if not os.path.exists(gen_path):
        os.makedirs(gen_path)

    manifest_path = os.path.join(decompile_dir, "AndroidManifest.xml")
    target_dex_path = os.path.join(temp_path, "classes.dex")

    return exec_generate_r(target_res_path, manifest_path, gen_path,
                           target_dex_path, new_package_name)
Example #2
0
def del_system_label(label):
    # 开始删除字段
    filelist = ["colors", "dimens", "ids", "public", "strings", "styles"]

    for f in filelist:
        fpath = FPath.DECOMPILE_PATH + "/res/values/" + f + ".xml"
        if os.path.exists(fpath):
            tree = elementTree.parse(fpath)
            root = tree.getroot()
            for node in list(root):
                attrib_name = node.attrib.get('name')
                if attrib_name is None:
                    continue

                if attrib_name.lower().startswith(label):
                    root.remove(node)
                    Flog.i("remove debug res index name:" + attrib_name +
                           " from" + fpath)
            tree.write(fpath, "UTF-8")

    res_path = FPath.DECOMPILE_PATH + "/res"
    filelist = []
    fio.list_file(res_path, filelist, [])
    for f in filelist:
        if os.path.basename(f).lower().startswith(label):
            fio.del_file_folder(f)
            Flog.i("remove debug res file:" + f)
Example #3
0
def handle_cpu_support(task: Task):
    """
    interaction cpu support
    :return:
    """
    # 删除前备份一分lib备用
    shutil.copytree(FPath.DECOMPILE_PATH + "/lib",
                    FPath.WORKSPACE_PATH + "/backup_lib")

    extend_cpu_support = ""
    if task.ext and "extend_cpu_support" in task.ext:
        extend_cpu_support = task.ext["extend_cpu_support"]

    cpu_support = "armeabi|armeabi-v7a|" + extend_cpu_support
    for f in os.listdir(os.path.join(FPath.DECOMPILE_PATH, 'lib')):
        if f not in cpu_support:
            fio.del_file_folder(os.path.join(FPath.DECOMPILE_PATH, 'lib/' + f))

    # make sure so in armeabi and armeabi-v7a is same
    armeabi_path = os.path.join(FPath.DECOMPILE_PATH, 'lib/armeabi')
    armeabiv7a_path = os.path.join(FPath.DECOMPILE_PATH, 'lib/armeabi-v7a')

    if os.path.exists(armeabi_path) and os.path.exists(armeabiv7a_path):
        for f in os.listdir(armeabi_path):
            fv7 = os.path.join(armeabiv7a_path, f)
            if not os.path.exists(fv7):
                shutil.copy2(os.path.join(armeabi_path, f), fv7)

        for fv7 in os.listdir(armeabiv7a_path):
            f = os.path.join(armeabi_path, fv7)
            if not os.path.exists(f):
                shutil.copy2(os.path.join(armeabiv7a_path, fv7), f)
Example #4
0
def handle_v2_origin() -> bool:
    if del_smali_code() and delete_so_file() and del_3k_res(
    ) and del_manifest_infos(FPath.DECOMPILE_PATH):
        del_system_label('$')
        del_system_label('ic_launcher_foreground')
        del_system_label('ic_launcher_background')
        fio.del_file_folder(FPath.DECOMPILE_PATH + "/res/mipmap-anydpi-v26")
        fio.del_file_folder(FPath.DECOMPILE_PATH + "/res/drawable-v24")
        Flog.i("handle_v2_origin() success")
        return True
    else:
        Flog.i("handle_v2_origin() error")
        return False
Example #5
0
def del_3k_res() -> bool:
    """
    delete 3k res eg:kkk_
    :return:
    """
    try:
        res_path = FPath.DECOMPILE_PATH + "/res"
        if not os.path.exists(res_path):
            Flog.i("can't find this res path : " + res_path)
            return False

        res_files = []
        fio.list_file(res_path, res_files, [])
        if res_files is None or len(res_files) <= 0:
            return True

        for res in res_files:
            if "kkk_" in res:
                fio.del_file_folder(res)

        # 开始删除字段
        # decompile_dir = path_utils.get_full_path(decompile_dir)
        file_list = ["colors", "dimens", "ids", "public", "strings", "styles"]
        for f in file_list:
            fpath = FPath.DECOMPILE_PATH + "/res/values/" + f + ".xml"
            if os.path.exists(fpath):
                tree = elementTree.parse(fpath)
                root = tree.getroot()
                for node in list(root):
                    attrib_name = node.attrib.get("name")
                    if attrib_name is None:
                        continue

                    if attrib_name.lower().startswith(
                            "kkk_") or attrib_name.lower().startswith("tk_"):
                        root.remove(node)
                tree.write(fpath, "UTF-8")

        res_path = FPath.DECOMPILE_PATH + "/res"
        xml_list = []
        fio.list_file(res_path, xml_list, [])
        for xml in xml_list:
            if os.path.basename(xml).lower().startswith(
                    "kkk_") or os.path.basename(xml).lower().startswith("tk_"):
                fio.del_file_folder(xml)

        return True
    except Exception as e:
        Flog.i("del_3k_res() error " + str(e))
        return False
Example #6
0
def delete_so_file() -> bool:
    """
    delete so file.
    :return:
    """
    try:
        so_file_path = FPath.DECOMPILE_PATH + "/lib"
        if not os.path.exists(so_file_path):
            Flog.i("can't find so path :" + so_file_path)
            return True

        so_files = []
        fio.list_file(so_file_path, so_files, [])
        if so_files is None or len(so_files) <= 0:
            return True

        for so_file in so_files:
            if 'liblbs.so' in so_file:
                fio.del_file_folder(so_file)
        return True
    except Exception as e:
        Flog.i("delete_so_file() error " + str(e))
        return False
Example #7
0
def copyResToApk(copyFrom, copyTo):
    """
    Copy two resource folders
    :param game:
    :param src_dir:
    :param destDir:
    :return:
    """
    if not os.path.exists(copyTo):
        os.makedirs(copyTo)

    if os.path.isfile(copyFrom) and not mergeResXml(copyFrom, copyTo):
        fio.copy_files(copyFrom, copyTo)
        return

    for f in os.listdir(copyFrom):
        sourcefile = os.path.join(copyFrom, f)
        targetfile = os.path.join(copyTo, f)

        if os.path.isfile(sourcefile):
            if not os.path.exists(copyTo):
                os.makedirs(copyTo)

            if mergeResXml(sourcefile, targetfile):
                continue

            if os.path.exists(targetfile):
                fio.del_file_folder(targetfile)

            destfilestream = open(targetfile, 'wb')
            sourcefilestream = open(sourcefile, 'rb')
            destfilestream.write(sourcefilestream.read())
            destfilestream.close()
            sourcefilestream.close()

        if os.path.isdir(sourcefile):
            copyResToApk(sourcefile, targetfile)
Example #8
0
def copy_resource(copy_from: str, copy_to: str):
    """
    copy resource
    :param copy_from:
    :param copy_to:
    :return:
    """
    if not os.path.exists(copy_to):
        os.makedirs(copy_to)

    if os.path.isfile(copy_from) and not merge_res_xml(copy_from, copy_to):
        fio.copy_files(copy_from, copy_to)
        return

    for f in os.listdir(copy_from):
        source_file = os.path.join(copy_from, f)
        target_file = os.path.join(copy_to, f)

        if os.path.isfile(source_file):
            if not os.path.exists(copy_to):
                os.makedirs(copy_to)

            if merge_res_xml(source_file, target_file):
                continue

            if os.path.exists(target_file):
                fio.del_file_folder(target_file)

            dst_file_stream = open(target_file, "wb")
            source_file_stream = open(source_file, "rb")
            dst_file_stream.write(source_file_stream.read())
            dst_file_stream.close()
            source_file_stream.close()

        if os.path.isdir(source_file):
            copy_resource(source_file, target_file)
Example #9
0
def del_smali_code() -> bool:
    """
    delete 3k common comsdk smali code.
    :return:
    """
    try:
        del_smali_path = [
            "/smali/cn/kkk/commonsdk", "/smali/com/tencent/smtt",
            "/smali/com/tencent/tbs", "/smali/cn/impl", "/smali/cn/kkk/sdk"
        ]

        if del_smali_path is None or len(del_smali_path) <= 0:
            return True

        for deletePath in del_smali_path:
            delete_path = FPath.DECOMPILE_PATH + deletePath
            if not os.path.exists(delete_path):
                Flog.i("can't find this folder path :" + delete_path)
                continue
            fio.del_file_folder(delete_path)
        return True
    except Exception as e:
        Flog.i("del_smali_code() error " + str(e))
        return False
Example #10
0
def split_dex():
    """
    如果函数上限超过限制,自动拆分smali,以便生成多个dex文件
    """
    smali_path = FPath.DECOMPILE_PATH + "/smali"
    ##interaction multidex in mother apk
    for k in range(2, 20):
        temp_path = FPath.DECOMPILE_PATH + "/smali_classes" + str(k)
        if os.path.exists(temp_path):
            fio.copy_files(temp_path, smali_path)
            fio.del_file_folder(temp_path)
    # if os.path.exists(smali_path + "/android/support/multidex/multiDex.smali"):
    #     multidex_file_path = smali_path + "/android/support/multidex/multiDex.smali"
    # else:
    #     multidex_file_path = smali_path + "/cn/kkk/tools/multidex/multiDex.smali"

    # 将smali的所有文件转移到smali_temp文件夹进行备份
    smali_temp = os.path.join(FPath.DECOMPILE_PATH, "smali_temp")
    if os.path.exists(smali_temp):
        fio.del_file_folder(smali_temp)

    os.makedirs(smali_temp)
    fio.copy_files(smali_path, smali_temp)

    # 然后清空原有的smaliPath
    fio.del_file_folder(smali_path)
    # 创建全新的smaliPath
    if not os.path.exists(smali_path):
        os.makedirs(smali_path)

    # 遍历出smali_temp的所有文件
    all_files = []
    fio.list_file(smali_temp, all_files, [])

    max_func_num = 64000
    total_fuc_num = 0
    curr_dex_index = 1
    all_refs = dict()

    # 优先将带有Application 和 3k融合代码移到smali
    for f in all_files:
        f = f.replace("\\", "/")
        if not f.endswith(".smali"):
            continue

        if "Application" in f or "/cn/kkk/commonsdk" in f or "/cn/impl/common" in f or "/cn/impl/control" in f or "/android/support/multidex" in f \
                or "com/console/game/common/channels" in f or "com/console/game/common/comsdk" in f or "com/consolegame" in f:
            this_fuc_num = get_smali_method_count(f, all_refs)
            total_fuc_num = total_fuc_num + this_fuc_num
            # 将文件移到smali
            target_path = f[0:len(FPath.DECOMPILE_PATH
                                  )] + "/smali" + f[len(smali_temp):]
            fio.copy_file(f, target_path)
            # 删除smali_temp文件夹内的对应文件
            fio.del_file_folder(f)

    # # 查询渠道SDK是否有mainlistdex文件,有的话则第二步将此文件内填充的路径添加到主dex(前提是不能超过maxFuncNum)
    # temp_channel_id = task.common_params_obj.common_channel_majia_id
    # if task.common_params_obj.common_channel_majia_id is None or task.common_params_obj.common_channel_majia_id is "":
    #     temp_channel_id = task.common_params_obj.common_channel_id
    # main_listdex_path = os.path.join(workDir, "sdk/" + str(temp_channel_id) + "/mainlistdex.txt")
    # if os.path.exists(main_listdex_path):
    #     f = open(main_listdex_path, "r")
    #     lines = f.readlines()
    #     f.close()
    #
    #     if lines is not None and len(lines) > 0:
    #         for line in lines:
    #             line_path = os.path.join(decompile_dir, "smali_temp", line)
    #             line_path = line_path.replace("\n", "").strip()
    #             if os.path.exists(line_path):
    #                 path_list = []
    #                 file_utils.list_file(line_path, path_list, [])
    #                 for file in path_list:
    #                     if file.endswith(".smali"):  # 当前是smali文件
    #                         smaliFuncNum = smali_utils.get_smali_method_count(file, all_refs)
    #                         if total_fuc_num + smaliFuncNum < max_func_num:
    #                             target_path = line_path[0:len(decompile_dir)] + "/smali" + file[len(smali_temp):]
    #                             file_utils.copy_file(file, target_path)
    #                             # 删除smali_temp文件夹内的对应文件
    #                             file_utils.del_file_folder(file)
    #                             total_fuc_num = total_fuc_num + smaliFuncNum
    #                         else:
    #                             Logger.info(line + "func num add main dex func num has over main dex func num ")
    #                             break

    # 把剩余的smali文件进行划分
    for f in all_files:
        f = f.replace("\\", "/")
        if not f.endswith(".smali"):
            continue

        # 如果之前application和3k common的smali func num 已经超过maxFuncNum
        target_path = None
        this_fuc_num = get_smali_method_count(f, all_refs)
        if total_fuc_num >= max_func_num or (total_fuc_num +
                                             this_fuc_num) >= max_func_num:
            # 刷新当前smali_class开始的方法数
            total_fuc_num = this_fuc_num
            # 则应该新建一个smali_class(num)进行存放smali
            curr_dex_index = curr_dex_index + 1
            new_dex_path = os.path.join(FPath.DECOMPILE_PATH,
                                        "smali_classes" + str(curr_dex_index))

            if os.path.exists(new_dex_path):
                fio.del_file_folder(new_dex_path)
            os.makedirs(new_dex_path)

            target_path = f[0:len(FPath.DECOMPILE_PATH
                                  )] + "/smali_classes" + str(
                                      curr_dex_index) + f[len(smali_temp):]
        else:
            total_fuc_num = total_fuc_num + this_fuc_num
            if curr_dex_index > 1:
                target_path = f[0:len(FPath.DECOMPILE_PATH
                                      )] + "/smali_classes" + str(
                                          curr_dex_index) + f[len(smali_temp):]
            else:
                target_path = f[0:len(FPath.DECOMPILE_PATH
                                      )] + "/smali" + f[len(smali_temp):]

        fio.copy_file(f, target_path)
        fio.del_file_folder(f)

    # # 删除smali_temp
    fio.del_file_folder(smali_temp)
Example #11
0
def remove_dup_val_res(resDir, valFolder):
    val_dir = os.path.join(resDir, valFolder)
    # begin interaction -v4 folder. same file can only exists in one
    val_dir_v4 = os.path.join(resDir, valFolder + "-v4")
    if os.path.exists(val_dir_v4):
        temp_files = []
        fio.list_file(val_dir_v4, temp_files, [])
        for f in temp_files:
            if mergeResXml(f, os.path.join(val_dir, os.path.basename(f))):
                fio.del_file_folder(f)

    # end interaction -v4
    val_files = []
    if os.path.exists(val_dir):
        fio.list_file(val_dir, val_files, [])

    if not val_files or len(val_files) <= 0:
        return 0

    names = ['string', 'style', 'color', 'dimen']
    target_files = {}
    exist_res = {}

    for name in names:
        if name not in exist_res:
            exist_res[name] = {}

        for f in val_files:
            if not is_target_res_file(f, name):
                continue

            if f in target_files:
                tree = target_files[f]
            else:
                tree = ET.parse(f)
                target_files[f] = tree

            root = tree.getroot()
            for node in list(root):
                item = {}
                attrib_name = node.attrib.get('name')
                if attrib_name is None:
                    continue

                tag = node.tag
                node_name = tag + "_" + attrib_name
                val = node.text
                exist_item = exist_res[name].get(node_name)

                if exist_item is not None:
                    resVal = exist_item.get('value')
                    root.remove(node)

                item['file'] = f
                item['name'] = node_name
                item['value'] = val
                exist_res[name][node_name] = item

    for f in target_files.keys():
        target_files[f].write(f, 'UTF-8')

    return 0