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('--blkid-path', required=True) 30 parser.add_argument('--fsckerofs-path', required=True) 31 parser.add_argument('apks') 32 parser.add_argument('output') 33 args = parser.parse_args() 34 35 with tempfile.TemporaryDirectory() as d: 36 with zipfile.ZipFile(args.apks) as zip: 37 zip.extractall(d) 38 result = '' 39 for name in sorted(os.listdir(os.path.join(d, 'standalones'))): 40 extractedDir = os.path.join(d, 'standalones', name+'_extracted') 41 subprocess.run([ 42 args.deapexer_path, 43 '--debugfs_path', 44 args.debugfs_path, 45 '--blkid_path', 46 args.blkid_path, 47 '--fsckerofs_path', 48 args.fsckerofs_path, 49 'extract', 50 os.path.join(d, 'standalones', name), 51 extractedDir, 52 ], check=True) 53 54 result += name + ':\n' 55 all_files = [] 56 for root, _, files in os.walk(extractedDir): 57 for f in files: 58 if f == 'libcutils.so': 59 all_files.append(os.path.join(root, f)) 60 all_files.sort() 61 for f in all_files: 62 readOutput = subprocess.check_output([ 63 args.readelf_path, 64 '-h', 65 f, 66 ], text=True) 67 arch = [x.strip().removeprefix('Machine:').strip() for x in readOutput.split('\n') if x.strip().startswith('Machine:')] 68 if len(arch) != 1: 69 sys.exit(f"Expected 1 arch, got {arch}") 70 rel = os.path.relpath(f, extractedDir) 71 result += f' {rel}: {arch[0]}\n' 72 73 with open(args.output, 'w') as f: 74 f.write(result) 75 76if __name__ == "__main__": 77 main() 78