Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
Dead end unless we could somehow bypass this...

Screenshot 2025-01-26 at 3.47.23 AM.png
 
Given that you're using Frida, if you've disabled SIP you should be able to inject into MASAgent (or whatever does that verification) and bypass signature check.
 
Unless we can bypass this with Frida, dead end... EDIT: Sorry, didn't see your previous post, my browser didn't show that this posted.
Screenshot 2025-01-26 at 3.47.23 AM.png
 
Last edited:
Given that you're using Frida, if you've disabled SIP you should be able to inject into MASAgent (or whatever does that verification) and bypass signature check.
Not entirely sure how to write that script though sadly, the Frida code I've been using is from github.
 
Currently learning to work with frida and hopper, I believe I found the trouble function (-[PreparePurchaseTask completeWithError:]) but I'm not entirely sure. Working on finding a way to make it do nothing when called.
 
Sadly, no luck. I've figured out that it is def in the appstoreagent process but as to patching it out I have no clue. I believe I know what assembly code has to be removed but actually going about that I'm not sure because I am not willing to pay $100 for hopper dissassembler on a hunch. For all we know the app store doesn't have the key to decrypt it and apple changes the key.
 
@WaterOtter78 Have you used method swizzling before?

I typically use the ZKSwizzle library, I find the syntax much easier to work with than other options.

If I wanted to make the method do nothing, I would write code that goes something like this:

Objective-C:
#import <AppKit/AppKit.h>
#import "ZKSwizzle.h"




@interface myPreparePurchaseTask : NSObject
@end

@implementation myPreparePurchaseTask

- (void)completeWithError:(NSError *)error {
    NSLog(@"Hello from -[PreparePurchaseTask completeWithError:]."
    //ZKOrig(void, error) //uncomment to call the original implementation of this method.
}

@end




@implementation NSObject (main)

+ (void)load {
    ZKSwizzle(myPreparePurchaseTask, PreparePurchaseTask);
}

@end


Compile this into a dylib and inject it with the DYLD_INSERT_LIBRARIES environment variable, SIMBL, or any other method of code injection.

If you already know how to do all of this and the problem is more complicated in a way I don't understand, I apologize. Conversely, let me know if you need more detailed instructions. I am somewhat limited in that I basically haven't used modern macOS since 2020 so I can't tell you exactly how to inject code on those systems.
 
Last edited:
Ill try this when I have time, thank you so much! I don't know how to code in C and frankly I didn't even think of this, so this is incredibly helpful. I'll let yall know the results!
@WaterOtter78 Have you used method swizzling before?

I typically use the ZKSwizzle library, I find the syntax much easier to work with than other options.

If I wanted to make the method do nothing, I would write code that goes something like this:

Objective-C:
#import <AppKit/AppKit.h>
#import "ZKSwizzle.h"




@interface myPreparePurchaseTask : NSObject
@end

@implementation myPreparePurchaseTask

- (void)completeWithError:(NSError *)error {
    NSLog(@"Hello from -[PreparePurchaseTask completeWithError:]."
    //ZKOrig(void, error) //uncomment to call the original implementation of this method.
}

@end




@implementation NSObject (main)

+ (void)load {
    ZKSwizzle(myPreparePurchaseTask, PreparePurchaseTask);
}

@end


Compile this into a dylib and inject it with the DYLD_INSERT_LIBRARIES environment variable, SIMBL, or any other method of code injection.

If you already know how to do all of this and the problem is more complicated in a way I don't understand, I apologize. Conversely, let me know if you need more detailed instructions. I am somewhat limited in that I basically haven't used modern macOS since 2020 so I can't tell you exactly how to inject code on those systems.
 
Little update, I ended up not having to use the dylib (so far, this may change) as I changed something and made progress. I wish I could remember exactly what I changed, but I was working on this very late last night and was too tired to remember. The important thing is that I can reproduce it, which I can. So far, I have had to intercept another file that seemingly declares things like the preflight package url, the actual app pkg, and other info on the requests app, and I'm currently trying to get around what seems to be hash checking. The expected hashes are defined in the same file, I just have to find a way to get the correct hashes. I'll have to work on it later, I don't have much time right now, but just a minor update. Also, I've ended up remaking the app store page just for simplicity at the moment as I was having issues with the old one, it's now a clone of another page with some IDs swapped. Probably not important, but it doesn't hurt to have extra information. Also, if anyone has purchased Mavericks please lmk, I'd like to cross reference the file I intercepted with one from an actual request for Mavericks. I'm aware this update is quite vague on many details, when I have more time I'll give a more detailed explanation of what I'm doing so I can get more thoughts. Apologies for the wording of this, I'm quite tired lol.
 
Little update, I ended up not having to use the dylib (so far, this may change) as I changed something and made progress. I wish I could remember exactly what I changed, but I was working on this very late last night and was too tired to remember. The important thing is that I can reproduce it, which I can. So far, I have had to intercept another file that seemingly declares things like the preflight package url, the actual app pkg, and other info on the requests app, and I'm currently trying to get around what seems to be hash checking. The expected hashes are defined in the same file, I just have to find a way to get the correct hashes. I'll have to work on it later, I don't have much time right now, but just a minor update. Also, I've ended up remaking the app store page just for simplicity at the moment as I was having issues with the old one, it's now a clone of another page with some IDs swapped. Probably not important, but it doesn't hurt to have extra information. Also, if anyone has purchased Mavericks please lmk, I'd like to cross reference the file I intercepted with one from an actual request for Mavericks. I'm aware this update is quite vague on many details, when I have more time I'll give a more detailed explanation of what I'm doing so I can get more thoughts. Apologies for the wording of this, I'm quite tired lol.
https://itunes.apple.com/app/os-x-mavericks/id675248567?mt=12
 
I have, but again, I'm on ancient macOS, I don't know if the app store works differently.
This is a bit of a task to ask, and no pressure at all, but if possible could you do this?

(I made these steps on sonoma, but theoredically they should work on any macOS version)
1) Set up mitmproxy and frida (SIP would have to be disabled)
1a) After mitmproxy is set up, you need to run sudo security add-trusted-cert -d -p ssl -p basic -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem in order to get the certificate working
2) Download "https://gist.github.com/azenla/37f941de24c5dfe46f3b8e93d94ce909#file-disable-ssl-pin-js"
3) Open Terminal and start mitmproxy with this command: mitmproxy --mode local --set tls_version_client_min=SSL3
4) Open the App Store (It shouldn't be able to connect)
5) Open two more terminal windows and run these commands (one in each window) to bypass SSL pinning
5a) frida -n "appstoreagent" -l ~/Downloads/disable-ssl-pin.js
5b) frida -n "App Store" -l ~/Downloads/disable-ssl-pin.js
6) Open the mavericks page and download mavericks, keep an eye on the mitmproxy window!
7) In the mitmproxy window, look for these get requests:
7a) Something similar to "/WebObjects/MZBuy.woa/wa/buyProduct?"
7b) Something similar to "/v1/catalog/us/apps/"
8) For each aforementioned get request, either click on the request or navigate to it with the arrow keys and press enter. Then navigate to response, press x, and select raw_response. Name it to whatever you like
9) In finder, go to your home directory (or wherever you ran the commnds from in terminal) and see if the files you just exported are there

Those are the files that I need, I would like to use the original store page (technically it isn't required tho) and I would really like to use the buyProduct page because it should have the hashes and other info already set. I don't believe there is any information about your mac there, but you're welcome to check if you'd like. I at least didn't find any when I checked the buyProduct page I've been modifying. I understand if you're uncomfortable with this, it's certainly quite a request and hassle to do, seriously no pressure at all.
 
@WaterOtter78 I've used mitmproxy before (that's partly how I was able to make the existing Mavericks download script) and I'm very familiar with setting that up. However, Frida doesn't install on Mavericks (at least not out of the box), so I'd have to spend time getting that to build properly. I could also use a VM with a newer version of macOS, but that's also a pain...

I'm not sure when I would have time to try this, I would like to but it might not be for a while. I'm sorry!
 
@WaterOtter78 I've used mitmproxy before (that's partly how I was able to make the existing Mavericks download script) and I'm very familiar with setting that up. However, Frida doesn't install on Mavericks (at least not out of the box), so I'd have to spend time getting that to build properly. I could also use a VM with a newer version of macOS, but that's also a pain...

I'm not sure when I would have time to try this, I would like to but it might not be for a while. I'm sorry!
That's okay! Seriously no worries, ik it's a bit annoying to do, didn't even know frida wasn't on mavericks oops.
 
I don't think 10.9 has ssl pinning for app store?
I can't download Mavericks when connected to mitmproxy, I get an error. I tried this back in December. (I can't remember if I tried other apps too, I think I did but don't quote me, it's theoretically possible that operating systems are special.)

It works fine when I use Squid but one of the Apple subdomains I excluded from ssl_bump might be letting it work.
 
I can't download Mavericks when connected to mitmproxy, I get an error. I tried this back in December. (I can't remember if I tried other apps too, I think I did but don't quote me, it's theoretically possible that operating systems are special.)

It works fine when I use Squid but one of the Apple subdomains I excluded from ssl_bump might be letting it work
Yeah I had the same issue initially.
I don't think 10.9 has ssl pinning for app store?
The app store throws an error when downloading items with mitmproxy enabled from SSL pinning. This is where the frida script comes it, it bypasses SSL pinning on the appstoreagent and the app store itself, both are required for downloading things.
 
The app store throws an error when downloading items with mitmproxy enabled from SSL pinning. This is where the frida script comes it, it bypasses SSL pinning on the appstoreagent and the app store itself, both are required for downloading things.
Mavericks (10.9) doesn't have SSL pinning for lots of things which modern macOS does, which would mean we wouldn't need Frida. I don't think the App Store is one of them, though.
 
Haven't had much time to work on this lately, but on a random side note, is there a way to convert the downloaded installESD into a functional .app installer?
 
Haven't had much time to work on this lately, but on a random side note, is there a way to convert the downloaded installESD into a functional .app installer?

Code:
#!/usr/bin/env bash
set -e

# Create_Mavericks_App.sh
# This script creates a writable copy of "Install OS X Mavericks.app" from InstallESD.dmg,
# and then copies the original InstallESD.dmg into its Shared Support folder.
#
# Steps:
#   1. Mount InstallESD.dmg.
#   2. Mount BaseSystem.dmg from within the mounted InstallESD.
#   3. Locate "Install OS X Mavericks.app" in BaseSystem.dmg.
#   4. Copy the app to a writable location (e.g. Desktop).
#   5. Create (if needed) the Shared Support folder in the copied app.
#   6. Copy InstallESD.dmg into that Shared Support folder.
#   7. Unmount all volumes.
#
# Usage:
#   Place this script in the same folder as InstallESD.dmg.
#   Make it executable:
#       chmod +x Create_Mavericks_App.sh
#   Run it:
#       ./Create_Mavericks_App.sh
#
# The final modified installer app will be available on your Desktop.

# Adjust the following path if necessary
INSTALL_ESD_DMG="$(pwd)/InstallESD.dmg"

# Mount points for the disk images
MOUNT_INSTALL_ESD="/Volumes/InstallESD"
MOUNT_BASESYSTEM="/Volumes/BaseSystem"

# Name of the Mavericks installer app as found in BaseSystem.dmg
APP_NAME="Install OS X Mavericks.app"

# Destination for the writable copy of the installer app (adjust as needed)
DESTINATION="$HOME/Desktop/${APP_NAME}"

# Cleanup function to unmount volumes on exit
cleanup() {
    echo "Cleaning up mounted volumes..."
    hdiutil detach "$MOUNT_BASESYSTEM" -quiet || true
    hdiutil detach "$MOUNT_INSTALL_ESD" -quiet || true
}
trap cleanup EXIT

echo "Step 1: Mounting InstallESD.dmg from: ${INSTALL_ESD_DMG}..."
hdiutil attach "$INSTALL_ESD_DMG" -mountpoint "$MOUNT_INSTALL_ESD" -nobrowse -quiet
echo "InstallESD.dmg mounted at ${MOUNT_INSTALL_ESD}."

# For Mavericks, BaseSystem.dmg is located directly in the InstallESD volume.
BASESYSTEM_DMG="${MOUNT_INSTALL_ESD}/BaseSystem.dmg"
if [ ! -f "$BASESYSTEM_DMG" ]; then
    echo "Error: BaseSystem.dmg not found at ${MOUNT_INSTALL_ESD}/BaseSystem.dmg"
    exit 1
fi

echo "Step 2: Mounting BaseSystem.dmg from: ${BASESYSTEM_DMG}..."
hdiutil attach "$BASESYSTEM_DMG" -mountpoint "$MOUNT_BASESYSTEM" -nobrowse -quiet
echo "BaseSystem.dmg mounted at ${MOUNT_BASESYSTEM}."

echo "Step 3: Locating '${APP_NAME}' in ${MOUNT_BASESYSTEM}..."
SOURCE_APP_PATH="${MOUNT_BASESYSTEM}/${APP_NAME}"
if [ ! -d "${SOURCE_APP_PATH}" ]; then
    echo "Error: ${APP_NAME} not found in ${MOUNT_BASESYSTEM}"
    exit 1
fi
echo "Found ${APP_NAME}."

echo "Step 4: Copying '${APP_NAME}' to a writable location at ${DESTINATION}..."
# Remove any previous copy at destination
rm -rf "${DESTINATION}"
# Copy the entire app. This may take a few minutes.
cp -R "${SOURCE_APP_PATH}" "${DESTINATION}"
echo "Copy complete."

# Define the Shared Support folder in the destination installer app.
SHARED_SUPPORT_DIR="${DESTINATION}/Contents/SharedSupport"

echo "Step 5: Creating Shared Support folder at ${SHARED_SUPPORT_DIR} (if it doesn't exist)..."
if [ ! -d "${SHARED_SUPPORT_DIR}" ]; then
    mkdir -p "${SHARED_SUPPORT_DIR}"
    echo "Created Shared Support folder."
else
    echo "Shared Support folder already exists."
fi

echo "Step 6: Copying InstallESD.dmg into the Shared Support folder..."
cp "$INSTALL_ESD_DMG" "${SHARED_SUPPORT_DIR}/"
echo "Copy complete."

echo "Process complete."
echo "The modified '${APP_NAME}' is available at ${DESTINATION} with InstallESD.dmg in its Shared Support folder."
 
Last edited:
  • Like
Reactions: Patrice Brousseau

Code:
#!/usr/bin/env bash
set -e

# Create_Mavericks_App.sh
# This script creates a writable copy of "Install OS X Mavericks.app" from InstallESD.dmg,
# and then copies the original InstallESD.dmg into its Shared Support folder.
#
# Steps:
#   1. Mount InstallESD.dmg.
#   2. Mount BaseSystem.dmg from within the mounted InstallESD.
#   3. Locate "Install OS X Mavericks.app" in BaseSystem.dmg.
#   4. Copy the app to a writable location (e.g. Desktop).
#   5. Create (if needed) the Shared Support folder in the copied app.
#   6. Copy InstallESD.dmg into that Shared Support folder.
#   7. Unmount all volumes.
#
# Usage:
#   Place this script in the same folder as InstallESD.dmg.
#   Make it executable:
#       chmod +x Create_Mavericks_App.sh
#   Run it:
#       ./Create_Mavericks_App.sh
#
# The final modified installer app will be available on your Desktop.

# Adjust the following path if necessary
INSTALL_ESD_DMG="$(pwd)/InstallESD.dmg"

# Mount points for the disk images
MOUNT_INSTALL_ESD="/Volumes/InstallESD"
MOUNT_BASESYSTEM="/Volumes/BaseSystem"

# Name of the Mavericks installer app as found in BaseSystem.dmg
APP_NAME="Install OS X Mavericks.app"

# Destination for the writable copy of the installer app (adjust as needed)
DESTINATION="$HOME/Desktop/${APP_NAME}"

# Cleanup function to unmount volumes on exit
cleanup() {
    echo "Cleaning up mounted volumes..."
    hdiutil detach "$MOUNT_BASESYSTEM" -quiet || true
    hdiutil detach "$MOUNT_INSTALL_ESD" -quiet || true
}
trap cleanup EXIT

echo "Step 1: Mounting InstallESD.dmg from: ${INSTALL_ESD_DMG}..."
hdiutil attach "$INSTALL_ESD_DMG" -mountpoint "$MOUNT_INSTALL_ESD" -nobrowse -quiet
echo "InstallESD.dmg mounted at ${MOUNT_INSTALL_ESD}."

# For Mavericks, BaseSystem.dmg is located directly in the InstallESD volume.
BASESYSTEM_DMG="${MOUNT_INSTALL_ESD}/BaseSystem.dmg"
if [ ! -f "$BASESYSTEM_DMG" ]; then
    echo "Error: BaseSystem.dmg not found at ${MOUNT_INSTALL_ESD}/BaseSystem.dmg"
    exit 1
fi

echo "Step 2: Mounting BaseSystem.dmg from: ${BASESYSTEM_DMG}..."
hdiutil attach "$BASESYSTEM_DMG" -mountpoint "$MOUNT_BASESYSTEM" -nobrowse -quiet
echo "BaseSystem.dmg mounted at ${MOUNT_BASESYSTEM}."

echo "Step 3: Locating '${APP_NAME}' in ${MOUNT_BASESYSTEM}..."
SOURCE_APP_PATH="${MOUNT_BASESYSTEM}/${APP_NAME}"
if [ ! -d "${SOURCE_APP_PATH}" ]; then
    echo "Error: ${APP_NAME} not found in ${MOUNT_BASESYSTEM}"
    exit 1
fi
echo "Found ${APP_NAME}."

echo "Step 4: Copying '${APP_NAME}' to a writable location at ${DESTINATION}..."
# Remove any previous copy at destination
rm -rf "${DESTINATION}"
# Copy the entire app. This may take a few minutes.
cp -R "${SOURCE_APP_PATH}" "${DESTINATION}"
echo "Copy complete."

# Define the Shared Support folder in the destination installer app.
SHARED_SUPPORT_DIR="${DESTINATION}/Contents/SharedSupport"

echo "Step 5: Creating Shared Support folder at ${SHARED_SUPPORT_DIR} (if it doesn't exist)..."
if [ ! -d "${SHARED_SUPPORT_DIR}" ]; then
    mkdir -p "${SHARED_SUPPORT_DIR}"
    echo "Created Shared Support folder."
else
    echo "Shared Support folder already exists."
fi

echo "Step 6: Copying InstallESD.dmg into the Shared Support folder..."
cp "$INSTALL_ESD_DMG" "${SHARED_SUPPORT_DIR}/"
echo "Copy complete."

echo "Process complete."
echo "The modified '${APP_NAME}' is available at ${DESTINATION} with InstallESD.dmg in its Shared Support folder."
Does it not the the OSInstall.mpkg?
 
Update: It does, but upon copying that as well and doing createinstallmedia (yes, I am aware the script already makes a bootable iso, but I'm trying to get a .app installer that works with createinstallmedia), it says that the copy of install os x mavericks is damaged.
 
Tried an OSInstall.mpkg from an archive.org MAS .app and it seems to work, ig the only roadblock right now is getting a valid OSInstall.mpkg
 
I believe that I got it, I was able to download it but I don't have time to test it right now. I will update later and post a modified version of the script that bundles it into a .app
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.