Skip to content

Restore MinimumOSVersion in decrypted IPAs#21

Merged
londek merged 7 commits into
londek:mainfrom
NohamR:main
May 22, 2026
Merged

Restore MinimumOSVersion in decrypted IPAs#21
londek merged 7 commits into
londek:mainfrom
NohamR:main

Conversation

@NohamR
Copy link
Copy Markdown
Contributor

@NohamR NohamR commented May 11, 2026

Restore the original MinimumOSVersion in decrypted IPAs and wire the change through the decrypt flow. runDecryptOnBundle now accepts a restoreMinOS parameter and will call pipeline.RestoreMinimumOSVersion to rewrite the main Info.plist inside the output IPA. Added RestoreMinimumOSVersion implementation that updates MinimumOSVersion in-place by recreating the IPA with the modified plist and handles errors/cleanup. Also ignore .DS_Store in .gitignore.

Restore the original MinimumOSVersion in decrypted IPAs and wire the change through the decrypt flow. runDecryptOnBundle now accepts a restoreMinOS parameter and will call pipeline.RestoreMinimumOSVersion to rewrite the main Info.plist inside the output IPA. Added RestoreMinimumOSVersion implementation that updates MinimumOSVersion in-place by recreating the IPA with the modified plist and handles errors/cleanup. Also ignore .DS_Store in .gitignore.
@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 11, 2026

Fix: #19

@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 11, 2026

Here is a demo with the updated version:

./ipadecrypt decrypt "https://apps.apple.com/us/app/goodnotes-ai-notes-docs-pdf/id1444383602"
  ✓ ipadecrypt dev · mobile@192.168.1.51 iOS 16.7.15 arm64 iPhone10,1
  ✓ signed in as [REDACTED] (FR storefront)
  ✓ found com.goodnotesapp.x on App Store
  ✓ downloaded com.goodnotesapp.x_7.0.54.ipa
  ✓ MinimumOSVersion 17.5 → 16.7.15
  ✓ installed → /var/containers/Bundle/Application/29B0C2C4-6858-4D99-BA2D-1F1E13BE9380/Goodnotes.app
    · decrypted Goodnotes (192.9 MB)
    · event=dyld msgh_bits="0x80001112" msgh_size="356" msgh_remote="0x2913" msgh_local="0x2703" msgh_id="2403" phase="exc_msg"
    · decrypted Frameworks/GN6DesignSystemFont.framework/GN6DesignSystemFont (48.0 KB)
    · decrypted Frameworks/GN6DesignSystemColor.framework/GN6DesignSystemColor (256.0 KB)
    · decrypted Frameworks/Collections_47BB0D94F2814A8A_PackageProduct.framework/Collections_47BB0D94F2814A8A_PackageProduct (1.1 MB)
    · decrypted Frameworks/WebRTC.framework/WebRTC (7.2 MB)
    · decrypted Frameworks/RocksDB.framework/RocksDB (6.5 MB)
    · decrypted Frameworks/gnyjsFFI.framework/gnyjsFFI (448.0 KB)
    · decrypted Frameworks/Lottie.framework/Lottie (1.6 MB)
    · decrypted Frameworks/GNAILanguages_-52E250F1EA51613D_PackageProduct.framework/GNAILanguages_-52E250F1EA51613D_PackageProduct (32.0 KB)
    · decrypted Frameworks/MSAL.framework/MSAL (1.2 MB)
    · decrypted Frameworks/onnxruntime.framework/onnxruntime (9.0 MB)
    · decrypted Frameworks/Matft_CBC1DF2C021_PackageProduct.framework/Matft_CBC1DF2C021_PackageProduct (528.0 KB)
    · decrypted Frameworks/GNSVG2PDF.framework/GNSVG2PDF (2.6 MB)
    · decrypted Frameworks/BaselineEstimation_-F27185EAF8202AE_PackageProduct.framework/BaselineEstimation_-F27185EAF8202AE_PackageProduct (32.0 KB)
    · decrypted Frameworks/HandwritingSynthesis_1A9B76625A00955D_PackageProduct.framework/HandwritingSynthesis_1A9B76625A00955D_PackageProduct (32.0 KB)
    · decrypted Frameworks/GNHandwritingSynthesis.framework/GNHandwritingSynthesis (3.0 MB)
    · decrypted Frameworks/AmplitudeCore.framework/AmplitudeCore (240.0 KB)
    · decrypted Frameworks/OpenSSL.framework/OpenSSL (2.9 MB)
    · decrypted Frameworks/UserLeapKit.framework/UserLeapKit (384.0 KB)
    · decrypted Frameworks/IntuneMAMSwift.framework/IntuneMAMSwift (4.2 MB)
    · decrypted Frameworks/IntuneMAMSwiftStub.framework/IntuneMAMSwiftStub (16.0 KB)
    · bundle done (20 frameworks)
    · made ActionExtensionCopyToGoodnotes executable
    · spawned ActionExtensionCopyToGoodnotes via ptrace
    · decrypted ActionExtensionCopyToGoodnotes (64.0 KB)
    · event=dyld msgh_bits="0x80001112" msgh_size="356" msgh_remote="0x2007" msgh_local="0xe0b" msgh_id="2403" phase="exc_msg"
    · app halted during launch; recovering what was loaded
    · made WidgetExtension executable
    · spawned WidgetExtension via ptrace
    · decrypted WidgetExtension (128.0 KB)
    · event=dyld phase="exc_msg" msgh_bits="0x80001112" msgh_size="356" msgh_remote="0x2303" msgh_local="0x2503" msgh_id="2403"
    · app halted during launch; recovering what was loaded
    · made ActionExtensionCopyToGoodnotesHTML executable
    · spawned ActionExtensionCopyToGoodnotesHTML via ptrace
    · decrypted ActionExtensionCopyToGoodnotesHTML (64.0 KB)
    · event=dyld phase="exc_msg" msgh_bits="0x80001112" msgh_size="356" msgh_remote="0x2b03" msgh_local="0x3e03" msgh_id="2403"
    · app halted during launch; recovering what was loaded
    · made ShareExtensionOpenInGoodnotes executable
    · spawned ShareExtensionOpenInGoodnotes via ptrace
    · decrypted ShareExtensionOpenInGoodnotes (176.0 KB)
    · event=dyld phase="exc_msg" msgh_bits="0x80001112" msgh_size="356" msgh_remote="0x2c03" msgh_local="0x3a03" msgh_id="2403"
    · app halted during launch; recovering what was loaded
    · packaged → com.goodnotesapp.x_7.0.54.ipa
  ✓ decrypted 25 image(s): 5 main, 20 framework
  ✓ → ./ipadecrypt/com.goodnotesapp.x_7.0.54.decrypted.ipa
  ✓ 48 Mach-O(s) verified cryptid=0
  ✓ restored MinimumOSVersion to 17.5

Final Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		.......
		<key>LSRequiresIPhoneOS</key>
		<true/>
		<key>LSSupportsOpeningDocumentsInPlace</key>
		<false/>
		<key>MSALSettingsFileName</key>
		<string>MSALSettings</string>
		<key>MinimumOSVersion</key>
		<string>17.5</string>
		.......
	</dict>
</plist>

@londek
Copy link
Copy Markdown
Owner

londek commented May 11, 2026

Hello, thank you for your contribution. I will try to review it till the end of the week because of my finals right now.

@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 11, 2026

No problem, take your time! Good luck!

Propagate and restore original Info.plist fields when decrypting IPAs. The decrypt flow now passes previousDeviceFamily through runDecryptOnBundle, and the pipeline function RestoreOriginalPlistValues replaces RestoreMinimumOSVersion to handle both MinimumOSVersion and UIDeviceFamily.
@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 13, 2026

This commit now restore the UIDeviceFamily original value too.

Here is a demo:

./ipadecrypt decrypt "https://apps.apple.com/us/app/shapr-3d-cad-modeling/id1091675654?platform=iphone" --patch-device-type
  ✓ ipadecrypt dev · mobile@localhost iOS 16.7.15 arm64 iPhone10,1
  ✓ signed in as [REDACTED] (FR storefront)
  ✓ found com.shapr3d.shapr on App Store
  ✓ cached com.shapr3d.shapr_26.80.0.ipa
  ✓ no MinimumOSVersion change needed
  ✓ UIDeviceFamily [2] → [2 1]
  ✓ already installed → /var/containers/Bundle/Application/AF71949B-8F53-45B5-A424-EB98F1E123C7/Shapr3D.app
    · decrypted Shapr3D (130.9 MB)
    · event=dyld phase="exc_msg" msgh_bits="0x80001112" msgh_size="356" msgh_remote="0x1907" msgh_local="0x2803" msgh_id="2403"
    · app halted during launch; recovering what was loaded
    · decrypted Frameworks/Parasolid.framework/Parasolid (55.5 MB)
    · bundle done (1 framework)
    · packaged → com.shapr3d.shapr_26.80.0.ipa
  ✓ decrypted 2 image(s): 1 main, 1 framework
  ✓ → ./ipadecrypt/com.shapr3d.shapr_26.80.0.decrypted.ipa
  ✓ 2 Mach-O(s) verified cryptid=0
  ✓ restored UIDeviceFamily to [2]

Obfuscate the displayed Apple account email in the sign-in confirmation to avoid exposing the full address. If the local part contains more than 5 characters, show the first 5 characters, then '...' and the domain (e.g. first5...@Domain).
@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 13, 2026

^ Mask the full email address to prevent people from exposing themselves.

@londek londek self-requested a review May 22, 2026 01:28
@londek
Copy link
Copy Markdown
Owner

londek commented May 22, 2026

Thanks for the contribution! I will add sensitive info anonymization as a flag in 0.7.0

@londek londek merged commit 5a0d067 into londek:main May 22, 2026
@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 25, 2026

Hey! Thanks for merging. But you didn't include the MinimumOSVersion and UIDeviceFamily fixes.
Why?

@londek
Copy link
Copy Markdown
Owner

londek commented May 25, 2026

I caught it later, I must've misunderstood or misclicked, because I wanted to discard the masking commit, but having you remind me of that, this is a deadcode now, because we now stream only the decrypted binaries back to the host and patch the encrypted ipa with decrypted binaries - meaning it will always have the original Info.plist.

@NohamR
Copy link
Copy Markdown
Contributor Author

NohamR commented May 25, 2026

All right, thanks for the reply!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants