Skip to content

Instantly share code, notes, and snippets.

@roosto
Created October 18, 2018 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roosto/92efe69b9fd0b1f1758d3c828d2be5d4 to your computer and use it in GitHub Desktop.
Save roosto/92efe69b9fd0b1f1758d3c828d2be5d4 to your computer and use it in GitHub Desktop.
Some python to pull Info.plist values out of a .ipa file
# This has to be run on macOS, because it relies on `plutil(1)` to convert binary Info.plist files
# into ASCII xml plist files. If you know the Info.plist will not be binary, you should be able to
# run this on other systems with minimal modification
# we pass the file path of the .ipa and array of plist keys to retrieve
# returns: a dict of the plist keys and their values as found in the app’s Info.plist
def get_attritubes_from_ipa(ipa_file, attributes):
retval = {}
zip_archive = zipfile.ZipFile(ipa_file, 'r')
# we want Payload/{filename}.app/Info.plist, but we have to find the value for {filename}.app
app_filename = ''
p = re.compile('Payload/[^/]+\\.app/$')
for file_info in zip_archive.infolist():
if p.match(file_info.filename):
# TODO: regex saved subpattern match may be clearer than this basename/dirname nonsense
app_filename = os.path.basename(os.path.dirname(file_info.filename))
break
if app_filename == '':
raise ValueError('Supplied zip file (`%s`) did not contain an entry matching `Payload/*.app`' % ipa_file)
plist_relpath = 'Payload/%s/Info.plist' % app_filename
temp_dir = tempfile.mkdtemp() # extract the plist to here
# wrap this all in a try, so that we can clean up the temp dir we made in case of failure
try:
zip_archive.extract(plist_relpath, temp_dir)
extracted_plist_abspath = '%s/%s' % (temp_dir, plist_relpath)
# convert what may be a binary plist to an xml plist so that python’s plistlib can use it
# see the man page for plutil(1) for more on plutil
retcode = subprocess.check_call(['/usr/bin/plutil', '-convert', 'xml1', extracted_plist_abspath])
plistObj = plistlib.readPlist(extracted_plist_abspath)
for attr in attributes:
retval[attr] = plistObj[attr]
except:
shutil.rmtree(temp_dir)
raise
shutil.rmtree(temp_dir)
return retval
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment