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)
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)
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)
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
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
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
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)
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)
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
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)
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