def testObfuscateProfile(self): with build_utils.TempDir() as temp_dir: # The dex dump is used as the dexfile, by passing /bin/cat as the dexdump # program. dex_path = os.path.join(temp_dir, 'dexdump') with open(dex_path, 'w') as dex_file: dex_file.write(DEX_DUMP_2) mapping_path = os.path.join(temp_dir, 'mapping') with open(mapping_path, 'w') as mapping_file: mapping_file.write(PROGUARD_MAPPING_2) unobfuscated_path = os.path.join(temp_dir, 'unobfuscated') with open(unobfuscated_path, 'w') as unobfuscated_file: unobfuscated_file.write(UNOBFUSCATED_PROFILE) obfuscated_path = os.path.join(temp_dir, 'obfuscated') cp.ObfuscateProfile(unobfuscated_path, dex_path, mapping_path, '/bin/cat', obfuscated_path) with open(obfuscated_path) as obfuscated_file: obfuscated_profile = sorted(obfuscated_file.readlines()) for a, b in zip(sorted(OBFUSCATED_PROFILE_2.splitlines()), obfuscated_profile): self.assertEqual(a.strip(), b.strip())
def _PerformDexlayout(tmp_dir, tmp_dex_output, options): if options.proguard_mapping_path is not None: matching_profile = os.path.join(tmp_dir, 'obfuscated_profile') convert_dex_profile.ObfuscateProfile( options.dexlayout_profile, tmp_dex_output, options.proguard_mapping_path, options.dexdump_path, matching_profile) else: logging.warning('No obfuscation for %s', options.dexlayout_profile) matching_profile = options.dexlayout_profile binary_profile = _CreateBinaryProfile(matching_profile, tmp_dex_output, options.profman_path, tmp_dir) output_files = _LayoutDex(binary_profile, tmp_dex_output, options.dexlayout_path, tmp_dir) if len(output_files) > 1: return _ZipMultidex(tmp_dir, output_files) if zipfile.is_zipfile(output_files[0]): return output_files[0] final_output = os.path.join(tmp_dir, 'dex_classes.zip') _ZipAligned(output_files, final_output) return final_output
def main(args): options, paths = _ParseArgs(args) if ((options.proguard_enabled == 'true' and options.configuration_name == 'Release') or (options.debug_build_proguard_enabled == 'true' and options.configuration_name == 'Debug')): paths = [options.proguard_enabled_input_path] if options.inputs: paths += options.inputs if options.excluded_paths: # Excluded paths are relative to the output directory. exclude_paths = options.excluded_paths paths = [ p for p in paths if not os.path.relpath(p, options.output_directory) in exclude_paths ] input_paths = list(paths) if options.multi_dex: input_paths.append(options.main_dex_list_path) dex_cmd = ['java', '-jar', options.d8_jar_path] options.sdk_jars = build_utils.ParseGnList(options.sdk_jars) options.classpath = build_utils.ParseGnList(options.classpath) for path in options.classpath: dex_cmd += ['--classpath', path] for path in options.sdk_jars: dex_cmd += ['--lib', path] if options.multi_dex: dex_cmd += ['--main-dex-list', options.main_dex_list_path] if options.release: dex_cmd += ['--release'] if options.min_api: dex_cmd += ['--min-api', options.min_api] is_dex = options.dex_path.endswith('.dex') is_jar = options.dex_path.endswith('.jar') with build_utils.TempDir() as tmp_dir: tmp_dex_dir = os.path.join(tmp_dir, 'tmp_dex_dir') os.mkdir(tmp_dex_dir) if is_jar and _NoClassFiles(paths): # Handle case where no classfiles are specified in inputs # by creating an empty JAR with zipfile.ZipFile(options.dex_path, 'w') as outfile: outfile.comment = 'empty' else: # .dex files can't specify a name for D8. Instead, we output them to a # temp directory then move them after the command has finished running # (see _MoveTempDexFile). For other files, tmp_dex_dir is None. _RunD8(dex_cmd, paths, tmp_dex_dir) tmp_dex_output = os.path.join(tmp_dir, 'tmp_dex_output') if is_dex: _MoveTempDexFile(tmp_dex_dir, tmp_dex_output) else: # d8 supports outputting to a .zip, but does not have deterministic file # ordering: https://issuetracker.google.com/issues/119945929 build_utils.ZipDir(tmp_dex_output, tmp_dex_dir) if options.dexlayout_profile: if options.proguard_mapping_path is not None: matching_profile = os.path.join(tmp_dir, 'obfuscated_profile') convert_dex_profile.ObfuscateProfile( options.dexlayout_profile, tmp_dex_output, options.proguard_mapping_path, options.dexdump_path, matching_profile) else: logging.warning('No obfuscation for %s', options.dexlayout_profile) matching_profile = options.dexlayout_profile binary_profile = _CreateBinaryProfile(matching_profile, tmp_dex_output, options.profman_path, tmp_dir) output_files = _LayoutDex(binary_profile, tmp_dex_output, options.dexlayout_path, tmp_dir) target = None if len(output_files) > 1: target = _ZipMultidex(tmp_dir, output_files) else: output = output_files[0] if not zipfile.is_zipfile(output): target = os.path.join(tmp_dir, 'dex_classes.zip') _ZipSingleDex(output, target) else: target = output shutil.move(os.path.join(tmp_dir, target), tmp_dex_output) # The dex file is complete and can be moved out of tmp_dir. shutil.move(tmp_dex_output, options.dex_path) build_utils.WriteDepfile(options.depfile, options.dex_path, input_paths, add_pydeps=False)