1# Copyright (C) 2022 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import argparse 16import os 17import subprocess 18import sys 19import tempfile 20import zipfile 21 22def main(): 23 parser = argparse.ArgumentParser( 24 description="This program takes an apks file and outputs a text file containing the " + 25 "name of all the libcutils.so files it found in the apex, and their arches.") 26 parser.add_argument('--deapexer-path', required=True) 27 parser.add_argument('--readelf-path', required=True) 28 parser.add_argument('--debugfs-path', required=True) 29 parser.add_argument('--fsckerofs-path', required=True) 30 parser.add_argument('apks') 31 parser.add_argument('output') 32 args = parser.parse_args() 33 34 with tempfile.TemporaryDirectory() as d: 35 with zipfile.ZipFile(args.apks) as zip: 36 zip.extractall(d) 37 result = '' 38 for name in sorted(os.listdir(os.path.join(d, 'standalones'))): 39 extractedDir = os.path.join(d, 'standalones', name+'_extracted') 40 subprocess.run([ 41 args.deapexer_path, 42 '--debugfs_path', 43 args.debugfs_path, 44 '--fsckerofs_path', 45 args.fsckerofs_path, 46 'extract', 47 os.path.join(d, 'standalones', name), 48 extractedDir, 49 ], check=True) 50 51 result += name + ':\n' 52 all_files = [] 53 for root, _, files in os.walk(extractedDir): 54 for f in files: 55 if f == 'libcutils.so': 56 all_files.append(os.path.join(root, f)) 57 all_files.sort() 58 for f in all_files: 59 readOutput = subprocess.check_output([ 60 args.readelf_path, 61 '-h', 62 f, 63 ], text=True) 64 arch = [x.strip().removeprefix('Machine:').strip() for x in readOutput.split('\n') if x.strip().startswith('Machine:')] 65 if len(arch) != 1: 66 sys.exit(f"Expected 1 arch, got {arch}") 67 rel = os.path.relpath(f, extractedDir) 68 result += f' {rel}: {arch[0]}\n' 69 70 with open(args.output, 'w') as f: 71 f.write(result) 72 73if __name__ == "__main__": 74 main() 75