Henry H Miao
Henry H Miao

Reputation: 3528

How to parse the Info.plist file from an ipa

I want to write a program to get app details, e.g. app name, version, bundle identifier, from an ipa file. However this file is not a plain text file, it's encoded in some way and my program cannot parse it.

Is there any way to decode this file?

UPDATE

To clarify the question, I'm writing a python program to get app details from ipa files that I exported from Xcode.

Upvotes: 11

Views: 18175

Answers (8)

crifan
crifan

Reputation: 14318

use this lib/code:

-> Demo:

    testIpadFullPath = "/xxx/WhatsApp_v23.25.85.ipa"
    # print("testIpadFullPath=%s" % testIpadFullPath)
    parse = IpaParse(testIpadFullPath)

    ipaAllInfo = parse.all_info()
    print("ipaAllInfo=%s" % ipaAllInfo)
    # print(json.dumps(ipaAllInfo, default = lambda o: o.__dict__))
    print("app_name=%s" % parse.app_name())
    print("bundle_identifier=%s" % parse.bundle_identifier())
    print("target_os_version=%s" % parse.target_os_version())
    print("minimum_os_version=%s" % parse.minimum_os_version())
    print("icon_file_name=%s" % parse.icon_file_name())
    print("icon_file_path=%s" % parse.icon_file_path())
    # print("mv_icon_to=%s" % parse.mv_icon_to('test.png'))

output:

ipaAllInfo={'MinimumOSVersion': '13.0', 'NSAppTransportSecurity': {'NSAllowsArbitraryLoads': True}, 'NSFaceIDUsageDescription': '\u200eUse Face ID to authenticate on WhatsApp.', 'NSLocalNetworkUsageDescription': '\u200eThis will let you use WhatsApp to place and receive calls through devices that are on the same Wi-Fi or local access networks.', 'DTXcodeBuild': '15A240d', 'NSMicrophoneUsageDescription': '\u200eThis lets you make calls, send voice messages, and record videos with sound.', 'UISupportedDevices': ['iPhone10,1', 'iPhone10,4', 'iPhone12,8', 'iPhone8,1', 'iPhone8,4', 'iPhone9,1', 'iPhone9,3', 'iPod9,1'], 'DTAppStoreToolsBuild': '15C5065a', 'CFBundleName': 'WhatsApp', 'CFBundleSupportedPlatforms': ['iPhoneOS'], 'FBBuildNumber': '548039364', 'NSCalendarsUsageDescription': '\u200eThis lets you create events on your calendar.', 'CFBundleDisplayName': '\u200eWhatsApp', 'NSSpeechRecognitionUsageDescription': 'WhatsApp does on-device recognition for Voice Messages. In this mode, no voice data is sent to Apple despite this alert, which is unexpected. Select "Don\'t Allow" and report to WhatsApp.', 'UISupportedInterfaceOrientations~ipad': ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight', 'UIInterfaceOrientationPortraitUpsideDown'], 'ITSDRMScheme': 'v2', 'DTPlatformBuild': '21A325', 'NSRemindersUsageDescription': '\u200eThis lets you set reminders to call your friends back.', 'CFBundleDocumentTypes': [{'CFBundleTypeName': 'WhatsApp Image', 'LSHandlerRank': 'Alternate', 'LSItemContentTypes': ['public.image'], 'CFBundleTypeIconFiles': ['Icon', 'Icon@2x']}, {'CFBundleTypeName': 'WhatsApp Image Exclusive', 'LSHandlerRank': 'Owner', 'LSItemContentTypes': ['net.whatsapp.image'], 'CFBundleTypeIconFiles': ['Icon', 'Icon@2x']}, {'CFBundleTypeName': 'WhatsApp Audio', 'LSHandlerRank': 'Alternate', 'LSItemContentTypes': ['public.mp3', 'public.mpeg-4-audio', 'public.aif-audio', 'public.aifc-audio', 'com.apple.coreaudio-format'], 'CFBundleTypeIconFiles': ['Icon', 'Icon@2x']}, {'CFBundleTypeName': 'WhatsApp Audio Exclusive', 'LSHandlerRank': 'Owner', 'LSItemContentTypes': ['net.whatsapp.audio'], 'CFBundleTypeIconFiles': ['Icon', 'Icon@2x']}, {'CFBundleTypeName': 'WhatsApp Movie', 'LSHandlerRank': 'Alternate', 'LSItemContentTypes': ['public.movie'], 'CFBundleTypeIconFiles': ['Icon', 'Icon@2x']}, {'CFBundleTypeName': 'WhatsApp Movie Exclusive', 'LSHandlerRank': 'Owner', 'LSItemContentTypes': ['net.whatsapp.movie'], 'CFBundleTypeIconFiles': ['Icon', 'Icon@2x']}], 'CFBundleSignature': '????', 'DTXcode': '1500', 'DTSDKName': 'iphoneos17.0', 'CFBundleVersion': '548039364', 'UIDeviceFamily': [1], 'UIBackgroundModes': ['bluetooth-peripheral', 'bluetooth-central', 'audio', 'fetch', 'location', 'processing', 'remote-notification', 'voip'], 'NSBonjourServices': ['_logger._tcp', '_stellabus._tcp', '_wa-fpm-i2i-transfer._tcp'], 'CFBundleIcons': {'CFBundlePrimaryIcon': {'CFBundleIconName': 'AppIcon', 'CFBundleIconFiles': ['AppIcon60x60']}}, 'NSLocationUsageDescription': '\u200eThis lets you send your current location or nearby places in chats.', 'DTPlatformName': 'iphoneos', 'CFBundleDevelopmentRegion': 'en', 'NSLocationWhenInUseUsageDescription': '\u200eThis lets you send your current location or nearby places in chats.', 'NSLocationAlwaysAndWhenInUseUsageDescription': "\u200eIf you always allow access to your location, you can choose to share your live location, and it will update even when you're not using the app. If you only allow access while using the app, you can only send your current location or a nearby place.", 'CFBundleURLTypes': [{'CFBundleURLSchemes': ['upi', 'whatsapp', 'whatsapp-consumer', 'fb306069495113'], 'CFBundleTypeRole': 'Editor', 'CFBundleURLName': 'net.whatsapp.WhatsApp'}], 'CFBundleIdentifier': 'net.whatsapp.WhatsApp', 'LSRequiresIPhoneOS': True, 'NSPhotoLibraryAddUsageDescription': '\u200eThis lets you save photos and videos to your library.', 'CFBundleExecutable': 'WhatsApp', 'NSPhotoLibraryUsageDescription': '\u200eThis lets you send photos and videos from your library and save the ones you capture.', 'ITSAppUsesNonExemptEncryption': False, 'BuildMachineOSBuild': '22G91', 'CFBundleIcons~ipad': {'CFBundlePrimaryIcon': {'CFBundleIconName': 'AppIcon', 'CFBundleIconFiles': ['AppIcon60x60', 'AppIcon76x76']}}, 'CFBundlePackageType': 'APPL', 'PHPhotoLibraryPreventAutomaticLimitedAccessAlert': True, 'LSApplicationQueriesSchemes': ['here-route', 'here-location', 'googlegmail', 'ms-outlook', 'inbox-gmail', 'comgooglemaps', 'yandexmaps', 'waze', 'googlechrome', 'googlechromes', 'googlechrome-x-callback', 'yandexnavi', 'comwainmaps', 'instagram', 'fb', 'whatsapp-smb', 'facebook-stories-list', 'novi', 'tez', 'phonepe', 'paytmmp', 'bhim', 'rblmobank'], 'NSContactsUsageDescription': "\u200eUpload your contacts to WhatsApp's servers to help you quickly get in touch with your friends and help us provide a better experience.", 'UTExportedTypeDeclarations': [{'UTTypeTagSpecification': {'public.mime-type': 'image/*', 'public.filename-extension': 'wai'}, 'UTTypeDescription': 'WhatsApp Image Exclusive', 'UTTypeIdentifier': 'net.whatsapp.image'}, {'UTTypeTagSpecification': {'public.mime-type': 'audio/*', 'public.filename-extension': 'waa'}, 'UTTypeDescription': 'WhatsApp Audio Exclusive', 'UTTypeIdentifier': 'net.whatsapp.audio'}, {'UTTypeTagSpecification': {'public.mime-type': 'video/*', 'public.filename-extension': 'wam'}, 'UTTypeDescription': 'WhatsApp Movie Exclusive', 'UTTypeIdentifier': 'net.whatsapp.movie'}], 'DTCompiler': 'com.apple.compilers.llvm.clang.1_0', 'UIRequiredDeviceCapabilities': {'telephony': True, 'arm64': True}, 'NSLocationAlwaysUsageDescription': "\u200eIf you always allow access to your location, you can choose to share your live location, and it will update even when you're not using the app. This also lets you send your current location or a nearby place.", 'NSSiriUsageDescription': '\u200eThis lets you use Siri to quickly send and read messages and make calls.', 'NSUserActivityTypes': ['INStartCallIntent', 'INSendMessageIntent', 'INSearchForMessagesIntent', 'INStartAudioCallIntent', 'INStartVideoCallIntent'], 'NSCameraUsageDescription': '\u200eThis lets you make video calls, take photos, and record videos.', 'NSBluetoothAlwaysUsageDescription': 'This lets you connect to supported Bluetooth devices', 'UISupportedInterfaceOrientations': ['UIInterfaceOrientationPortrait', 'UIInterfaceOrientationLandscapeLeft', 'UIInterfaceOrientationLandscapeRight'], 'AVUseSoftwareDecoderForAssetImageGenerator': True, 'CFBundleInfoDictionaryVersion': '6.0', 'UIAppFonts': ['WhatsAppPaymentsIcons.ttf', 'Optimistic_DisplayVF_A_Wght.ttf'], 'BGTaskSchedulerPermittedIdentifiers': ['com.whatsapp.background_fetch', 'com.whatsapp.message_search_engine_indexing', 'com.whatsapp.icloud_backup', 'com.whatsapp.db_maintenance', 'com.whatsapp.db_migration'], 'NSLocationTemporaryUsageDescriptionDictionary': {'ShareLiveLocation': '\u200eYour precise live location will be shared in the chat.', 'SendLiveLocation': '\u200eYour precise live location will be shared in the chat.', 'SendStaticLocation': '\u200eYour precise location will be sent to the chat.', 'MapButton': "\u200eYou'll be able to see your precise location and share it to the chat"}, 'DTSDKBuild': '21A325', 'UIStatusBarTintParameters': {'UINavigationBar': {'Style': 'UIBarStyleDefault', 'Translucent': False}}, 'UILaunchStoryboardName': 'LaunchScreen', 'NSBluetoothPeripheralUsageDescription': 'This lets you connect to supported Bluetooth devices', 'DTPlatformVersion': '17.0', 'LSSupportsOpeningDocumentsInPlace': 'NO', 'CFBundleShortVersionString': '23.25.85', 'UIRequiresPersistentWiFi': True}
app_name=WhatsApp
bundle_identifier=net.whatsapp.WhatsApp
target_os_version=17.0
minimum_os_version=13.0
icon_file_name=AppIcon60x60
icon_file_path=Payload/WhatsApp.app/[email protected]

Upvotes: 0

ccpizza
ccpizza

Reputation: 31666

plutil

On a mac you can do it with the ootb plutil:

# Convert a binary plist to XML
plutil -convert xml1 info.plist
 
## Convert XML back to binary
plutil -convert binary1 info.plist

For more details see man plutil in the terminal.

/usr/libexec/PlistBuddy

On macOS, for usage in shell scripts, for example, for reading/writing/deleting properties in plist files, there is also /usr/libexec/PlistBuddy

For example, to read the bundle identifier key for the TextEdit.app you'd use something like:

/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" /System/Applications/TextEdit.app/Contents/Info.plist
### OUTPUT: >>> com.apple.TextEdit

python's plistlib

If you want to parse a text or a binary .plist file programatically, for example with python, then you can use plistlib — a standard library module:

import plistlib

with open ('/etc/bootpd.plist', 'rb') as plist:
    conf = plistlib.load(plist)
    print(conf['dhcp_enabled'])

Upvotes: 2

QamarAbbas
QamarAbbas

Reputation: 11

Here is the solution i found out in python : Since .plist files are binary-encoded so, you will need a python libary that could read files with binary format. For this particular example i use plistlib. NOTE: You get .app file when you unzip .ipa file.

from zipfile import ZipFile 
import plistlib 
with ZipFile("/content/sample_data/Experience Abu Dhabi.app.zip", 'r') as zObject: 
zObject.extractall( 
    path="/content/sample_data/temp") 
path = "/content/sample_data/temp/Experience Abu Dhabi.app/Info.plist"
with open(path, 'rb') as f:
    data = plistlib.load(f)
print(data)

Upvotes: 0

Guilherme Campos Hazan
Guilherme Campos Hazan

Reputation: 1031

A double click on the plist will open from XCode.

Upvotes: 2

Shin-chan
Shin-chan

Reputation: 899

It's easy if you have a macbook.
Then follow this guideline: http://osxdaily.com/2011/04/07/extract-and-explore-an-ios-app-in-mac-os-x/

  1. Rename from file.ipa -> file.zip
  2. Unzip file.zip
  3. Go to Payload folder
  4. Right click Application file -> Show Package Contents
  5. See Info.plist

Upvotes: 12

Henry H Miao
Henry H Miao

Reputation: 3528

Got the answer from the Apple's developer forum:

PlistBuddy is what you're looking for:

/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" yourBinaryOrXmlPlist.plist

Upvotes: 1

manroe
manroe

Reputation: 1775

For those without Apple Developer logins, here's the two answers from the accepted answer's link (you have to login to see it):

  • use PlistBuddy
    • /usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" yourBinaryOrXmlPlist.plist
  • There are also many other ways to parse binary plist files. For example, I'm using Python and there is a library called biplist, which is exactly used to read and write binary plist files and support both Python 2 and 3. Also, the 'plistlib' in Python 3.4 supports binary plist manipulation with new APIs.

Upvotes: 5

noamtm
noamtm

Reputation: 12953

My Python version: https://gist.github.com/noamtm/a8ddb994df41583b64f8

In my research, the tricky bit was parsing a binary plist, since python's PlistLib can't read it:

from Foundation import NSData, NSPropertyListSerialization 
# Use PyObjC, pre-installed in Apple's Python dist.
def parse_plist(info_plist_string):
  data = NSData.dataWithBytes_length_(info_plist_string, len(info_plist_string))
  return NSPropertyListSerialization.propertyListWithData_options_format_error_(data, 0, None, None)

Upvotes: 2

Related Questions