Created
May 3, 2019 14:55
-
-
Save jjrscott/348b8765913d083c33d13964f24f4214 to your computer and use it in GitHub Desktop.
Script to resign an IPA file (packaged iOS application)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use Data::Dumper; | |
use Getopt::Long; | |
use File::Temp 'tempdir'; | |
use DirHandle; | |
use File::Slurp; | |
my $tempdir = tempdir(CLEANUP => 1); | |
print "chdir temporary directory\n"; | |
print "^^^^^^^^^^^^^\n\n"; | |
print "chdir $tempdir\n"; | |
chdir $tempdir; | |
my $mobileprovision_path; | |
my $encode_mobileprovision; | |
my $ipa_path; | |
my $command_result = 0; | |
my $version_suffix = 'a'; | |
my $append_mobileprovision_name = 1; | |
GetOptions | |
( | |
'version_suffix=s' => \$version_suffix, | |
'mobileprovision_path=s' => \$mobileprovision_path, | |
'encode_mobileprovision!' => \$encode_mobileprovision, | |
'append_mobileprovision_name!' => \$append_mobileprovision_name, | |
'ipa_path=s' => \$ipa_path, | |
); | |
if (!-e $mobileprovision_path) | |
{ | |
die "Could not find the mobileprovision:\n $mobileprovision_path\n"; | |
} | |
my ($codesign_allocate) = qx(xcrun -find codesign_allocate); | |
if ($?) | |
{ | |
die "Could not xcrun or codesign_allocate\n"; | |
} | |
chomp $codesign_allocate; | |
$ENV{'CODESIGN_ALLOCATE'} = $codesign_allocate; | |
my $mobileprovision_content = read_file($mobileprovision_path); | |
if ($encode_mobileprovision) | |
{ | |
my $mobileprovision_content_hex = unpack "H*", $mobileprovision_content; | |
print join "\n", $mobileprovision_content_hex =~ /(.{0,64})/g; | |
exit 0; | |
} | |
if (!-e $ipa_path) | |
{ | |
die "Could not find the IPA:\n $ipa_path\n"; | |
} | |
print "unzip the IPA\n"; | |
print "^^^^^^^^^^^^^\n\n"; | |
$command_result = system 'unzip', '-qo', $ipa_path; | |
if ($command_result != 0) | |
{ | |
die "Could not unzip the IPA file\n"; | |
} | |
my $application_name; | |
my $payload_dir_handle = DirHandle->new('Payload'); | |
foreach my $leaf ($payload_dir_handle->read) | |
{ | |
if ($leaf !~ /^\.{1,2}$/) | |
{ | |
$application_name = $leaf; | |
last; | |
} | |
} | |
print "extract entitlements\n"; | |
print "^^^^^^^^^^^^^^^^^^^^\n\n"; | |
# $command_result = system 'xcrun', 'codesign', '-d', '-vv', '--entitlements', ':entitlements.plist', 'Payload/'.$application_name; | |
# | |
# if ($command_result != 0) | |
# { | |
# die "Could not get the entitlements\n"; | |
# } | |
my ($application_identifier) = $mobileprovision_content =~ m!<key>application-identifier</key>\s*<string>([^<]+)</string>!s; | |
my ($team_name) = $mobileprovision_content =~ m!<key>TeamName</key> | |
\s*<string>([^<]+)</string>!s; | |
my ($mobileprovision_name) = $mobileprovision_content =~ m!<key>Name</key> | |
\s*<string>([^<]+)</string>!s; | |
my $entitlements_content = read_file('Payload/'.$application_name.'/entitlements.plist'); | |
$entitlements_content =~ s!(<key>application-identifier</key>\s*<string>)([^<]+)(</string>)!$1$application_identifier$3!s; | |
my $previous_application_identifier = quotemeta $2; | |
$entitlements_content =~ s!(<key>com.apple.developer.team-identifier</key>\s*<string>)([^<]+)(</string>)!!s; | |
$entitlements_content =~ s!(<key>com.apple.external-accessory.wireless-configuration</key>\s*<(true|false)/>)!!s; | |
$entitlements_content =~ s~$previous_application_identifier~$application_identifier~s; | |
write_file('Payload/'.$application_name.'/entitlements.plist', $entitlements_content); | |
print "\ninsert updated entitlements\n"; | |
print "^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"; | |
$command_result = system 'cp', '-vf', $mobileprovision_path, 'Payload/'.$application_name.'/embedded.mobileprovision'; | |
if ($command_result != 0) | |
{ | |
die "Could not copy the mobileprovision\n"; | |
} | |
print "\nupdate info plist\n"; | |
print "^^^^^^^^^^^^^^^^^^^\n\n"; | |
my $info_path = 'Payload/'.$application_name.'/Info.plist'; | |
my $bundleShortVersion = plist($info_path, ":CFBundleShortVersionString"); | |
plist($info_path, ":CFBundleShortVersionString", $bundleShortVersion.$version_suffix); | |
my $bundleVersion = plist($info_path, ":CFBundleVersion"); | |
plist($info_path, ":CFBundleVersion", $bundleVersion.$version_suffix); | |
print "\nresign the app\n"; | |
print "^^^^^^^^^^^^^^\n\n"; | |
$command_result = system 'xcrun', 'codesign', '-f', '-s', 'iPhone Distribution: '.$team_name, '--entitlements=Payload/'.$application_name.'/entitlements.plist', '-vv', 'Payload/'.$application_name; | |
if ($command_result != 0) | |
{ | |
die "Could not codesign the app\n"; | |
} | |
print "\nverify the app\n"; | |
print "^^^^^^^^^^^^^^\n\n"; | |
$command_result = system 'xcrun', 'codesign', '-dvvv', 'Payload/'.$application_name; | |
if ($command_result != 0) | |
{ | |
die "Could not verify the codesign\n"; | |
} | |
my $resigned_ipa_path = $ipa_path; | |
$mobileprovision_name =~ s|[^a-zA-Z0-9]|_|g; | |
$mobileprovision_name =~ s|_+|_|g; | |
$mobileprovision_name = lc $mobileprovision_name; | |
if ($append_mobileprovision_name) | |
{ | |
$resigned_ipa_path =~ s!\.ipa!.${mobileprovision_name}.ipa!; | |
} | |
print "\nzip the resigned IPA\n"; | |
print "^^^^^^^^^^^^^^^^^^^^\n\n"; | |
$command_result = system 'zip', '-qr', $resigned_ipa_path, 'Payload'; | |
if ($command_result != 0) | |
{ | |
die "Could not zip up the new IPA\n"; | |
} | |
print "the new IPA is at $resigned_ipa_path\n\n"; | |
chdir '/'; | |
sub plist | |
{ | |
my ($path, $key, $value) = @_; | |
if (defined $value) | |
{ | |
return qx(/usr/libexec/PlistBuddy -c "Set $key $value" $path); | |
} | |
else | |
{ | |
my $value = qx(/usr/libexec/PlistBuddy -c "Print $key" $path); | |
$value =~ s/[\n\l\r]//g; | |
return $value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment