- Jailbreak in 2024
- Get decrypted IPA off Jailbroken device
- Strings
- Get App Store iPAs
- Quick-start run-time introspection
- Objection
- Inspect files inside ipa
- Inspect sandbox data on Jailbroken device
- Logs
- Build information
- Applesign
- Sideload iOS app
- Frida-Server
- Frida-Gadget
- Frida basics
- Frida's --eval flag
- Frida Intercepter
- Frida-Trace
- Bypass anti-Frida checks
- Cookies
- Change iOS Version
- LLVM Instrumentation
Please read if you have a Jailbreak - checkra1n
, unc0ver
, TrollInstallerX
or dopamine
- and want to get it working.
There is no magic "download and it works". Forget Cydia Impactor
.
Warning
If you just download a jailbreak ipa
- even if it is TrollInstallerX it won't be code-signed. It won't install.
Preparing an old iOS device for Jailbreak takes time and effort:
- Find jailbreak
- Prepare iOS Device
- Prepare XCode for older iOS versions
- Create Provisioning Profile in XCode
- Sign and deploy Jailbreak IPA
- Verify you can SSH onto iOS device
- CheckRa1n great option when you have an older iOS device.
- PaleRa1n iOS 15+. Requires older iOS device.
- Electra iOS 11. But iOS 11 was now old. Most apps dropped support.
- [Dopamine]https://github.com/opa334/Dopamine/releases/tag/2.2.2 16.x
- Unc0ver iOS 14.2 device Unc0ver seems ok.
- Trust the
Profile
of the Developer. - Ensure the device
Trusts
the machine it connects with. - On newer iOS version this includes turning on Developer Settings; iOS 16.0 to 16.6.1
Settings -> Privacy & Security
and then scroll down until you see Developer Mode, tap that option.
Open XCode/Window/Devices and Simulators
. Let XCode see the device. If you are trying to use an older device with an older OS, keep reading; for example, with Unc0ver, the latest XCode doesn't support iOS 14. You can still update XCode Device Support. Why ? This is required so you can create a provisioning profile
for iOS 14.2 [ or deploy any iOS to that old device ].
- Grab the Device Support files here.
- Open
Applications
. Right-click on Xcode, in Finder, and select“package contents”
. - Navigate to
contents/Developer/platform/iPhoneOS.platform/DeviceSupport
. - Unzip the downloaded file and copy the folder to above location.
- Restart XCode.
- The older iOS device should now be a possible build target.
We need to get a Provisioning Profile ( called the embedded.mobileprovision
file).
- Open
Xcode
and selectFile/New/Project/Swift
and call it anything. You don't need tests or any CoreData pieces. Just a basic "HelloWorld" app. - Select
build
for your connected device.
[!INFO] You don’t need to
Run
the app on the device.
- Right click on the
/Product/HelloWorld.app
- in the left hand view pane - and selectshow in Finder
.
If you look inside the folder ( remember HelloWorld.app
is a folder ) you will find a fresh embedded.mobileprovision
. This contains the uniques IDs and an expiry date for the developer profile associated to the app.
# find your "Apple Development" ID
security find-identity -v -p codesigning
# tools to inspect device ( works on jailed and jailbroken devices )
brew install libimobiledevice
# check if you can see attached iOS device
idevice_id
0000FFFF-0011111111122222 (USB)
# sign Jailbreak ipa
applesign -p -7 \
-i ${CODESIGNID} \
-b rm.helloworld \
--clone-entitlements \
-m embedded.mobileprovision \
TrollInstallerX.ipa
-o $SIGNED_IPA
# Deploy to the device over USB
ios-deploy -b $SIGNED_IPA
# macOS - install iProxy
brew install libusbmuxd
# For SSH over USB access
iproxy 2222 22 &
# most jailbreaks: Password is well known
ssh -p 2222 root@localhost
# dopamine uses the `mobile` user not root
# user sets password when invoking the jailbreak
ssh -p 2222 mobile@localhost
Decrypting the app binary is essential. You cannot skip this step if you want to find good strings, debug the app or repackage the iPA.
# Get script to decrypt iPA
https://github.com/AloneMonkey/frida-ios-dump
# Attach a jailbroken iPhone and create tunnel over USB
iproxy 2222 22 &
# Ensure Frida is running on iOS device. Then run frida-ios-dump
./dump.py foo.bar.bundleid
# Check AppStore binary is now decrypted ( cryptid 0 decrypted vs cryptid 1 encrypted )
otool -l Payload/foo.app/foo | grep -i LC_ENCRYPTION -B1 -A4
Load command 12
cmd LC_ENCRYPTION_INFO_64
cryptid 0
--
If you didn't decrypt the app you won't find good strings.
strings $APP_BINARY | grep -E 'session|https|pinning|secret'
- Install Apple's utility Apple Configurator 2 from macOS store
- Install the target iOS app on the target device
- Then open
Apple Configurator 2
and "sign in" with the same Apple account used on the target device - Sign-out and sign-in to refresh the known app list
- Right click on device and select
Add/Apps
- Select the app you want to copy
At this point Apple Configurator 2
will download a copy of the app to:
~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Caches/Assets/TemporaryItems/MobileApps/
When you hit the "Skip App / Replace / Stop"
modal, select nothing. Go to Finder and grab the IPA.
Tools like Frida and Objection can work with apps straight from the app store. To work on a jailed
device, the app needs to be re-signed as it adds a dynamic library ( gadget
) to the app's list of frameworks.
# Install Objection
pip3 install objection
# jailed device
objection --gadget $BUNDLE_ID explore
# jailbroken device
objection -g $BUNDLE_ID explore
#### Objection commands ####
# sandbox location on device
env
# search for useful methods
ios hooking search methods pincode
[MySwiftApp.Services - validatePinCode:error:]
[MySwiftApp.Services - disablePinCode]
# search for useful classes
ios hooking search classes pincode
# watch method calls inside a Class
ios hooking watch class MySwiftApp.Services
# verify Objection can see Class
ios hooking search classes MySwiftApp.Services
# list Class Methods of a Class
ios hooking list class_methods MySwiftApp.Services
# read info.plist
ios plist cat Info.plist
# download file
file download Info.plist
# dump memory
memory dump all myapp_memory.dump
Will dump 111 rw- images, totalling 718.5 MiB
Dumping 512.0 MiB from base: 0x280000000 [####################################] 100%
# search memory for strings
strings myapp_memory.dump | grep -i session
# KeyChain dump
ios keychain dump --json output.json
# list bundles used by app
ios bundles list_bundles
# list classes
ios hooking list classes
# list frameworks used by app
ios bundles list_frameworks
# list modules
memory list modules
# print UI hierarchy of view controllers, labels, buttons, etc
ios ui dump
# Unzip the IPA file to reveal the Payload folder
unzip myApp.ipa
# big files inside ipa file
find Payload -size +2M
# Files that were mistakingly shipped inside of App Bundle
find . -name '*.json' -or -name '*.txt'
# Check for ReactNative
find . -name main.jsbundle
# Check for Certificates
find . -name '*.crt' -or -name '*.cer' -or -name '*.der'
# Property lists inside Payload folder. Recursive search.
find Payload/ -name '*.plist'
# Provisioning Profiles
find . -name '*.mobileprovision'
# Dynamically linked frameworks
find . -name '*.framework'
# Locally linked javascript
find Payload -name '*.js'
# Search all plist files for a value
find . -name '*.plist' | xargs grep "LSApplicationQueriesSchemes"
# Search all plist files for Device Permissions or App Transport Security
find . -name '*.plist' | xargs grep "NS"
# Search all files using only grep
grep "LSApplicationQueriesSchemes" . -R
# Recursive search all files using grep inside Payload folder
grep "Requires" Payload -R
# foobar.app/Info.plist: <key>UIRequiresFullScreen</key>
# foobar.app/Info.plist: <key>LSRequiresIPhoneOS</key>
# Sandbox. Look here for Cookies, json files, etc
/var/mobile/Containers/Data/Application/[GUID given at install time]/
# Folder of App Bundle that was installed. Executables, frameworks, fonts, CSS, html. NIB files.
/private/var/containers/Bundle/Application/[GUID given at app install]/foo.app
# App executable
/private/var/containers/Bundle/Application/[GUID given at app install]/foo.app/foo
# freshly installed IPA is at the bottom of list
cd /private/var/mobile/Containers/Data/Application/ && ls -lrt
cd [app guid]/Documents/
cd [app guid]/Library/
# Databases to pull off a device
/private/var/Keychains
TrustStore.sqlite3
keychain-2.db
pinningrules.sqlite3
# Extract IPA (whether App Store encrypted or not)
scp -r -P 2222 root@localhost:/var/containers/Bundle/Application/<app GUID>/hitme.app ~/hitme.app
# Different to SSH, the uppercase P for Port with SCP. Order important.
scp -P 2222 root@localhost:/var/root/overflow.c localfilename.c
# from Jailbroken device to local machine
# Caution:no space after the root@localhost: Otherwise you copy the entire filesystem!
scp -P 2222 root@localhost:/private/var/mobile/Containers/Data/Application/<App GUID>/Library/Caches/Snapshots/com.my.app
# from local machine to remote Jailbroken device
scp -P 2222 hello.txt root@localhost:/var/root/
# physical device
idevicesyslog -u <DeviceID> | myPipedProgram
# Get logs from iOS Simulator
xcrun simctl spawn booted log stream --level=debug
# Get logs from iOS Simulator by App Name
xcrun simctl spawn booted log stream --predicate 'processImagePath endswith "MyAppName"'
# Check platform
lipo -info libprogressbar.a
# Check for build errors
jtool -arch arm64 -L <binary inside app bundle>
# Check minimum iOS version & restrict linker flag
jtool -arch arm64 -l <binary inside app bundle
# Check Load Commands
rabin2 -H playground
# Sections of the Binary
objdump -macho -section-headers Payload/myApp.app/myApp
# iOS app entitlements
codesign -d --entitlements :- Payload/MyApp.app
jtool -arch arm64 --ent <binary inside app bundle>
# Check binary was stripped
rabin2 -I -a arm_64 <binary inside app bundle> | grep -E 'stripped|canary'
# Check Position Independent Code set
rabin2 -I -a arm_64 <binary inside app bundle> | grep -E 'pic|bits
# Check for Bitcode enabled
# [!] this command won't work on a locally built Simulator / iPhone app. Bitcode happens after setting `Archive`
otool -l libprogressbar.a | grep __LLVM
otool -arch arm64 -l tinyDynamicFramework | grep __LLVM
Applesign
is a wrapper around Codesigning
tools from Apple.
npm install -g applesign
First, you want to get hold of an embedded.mobileprovision
file:
- Open
Xcode
and selectFile/New/Project/Swift
and call it anything. You don't need tests or any CoreData pieces. Just a basic "HelloWorld" app. - Select
build
for your connected device.
[!INFO] You don’t need to
Run
the app on the device.
- Right click on the
/Product/HelloWorld.app
- in the left hand view pane - and selectshow in Finder
.
If you look inside the folder ( remember HelloWorld.app
is a folder ) you will find a fresh embedded.mobileprovision
. This contains the uniques IDs and an expiry date for the developer profile associated to the app.
# Read the Provisioning Profile
# ensure your device ID is in the profile and the profile is fresh.
security cms -D -i embedded.mobileprovision
# find code signing key
security find-identity -v -p codesigning
export CODESIGNID=<GUID>
# tell Applesign to use your Provisioning Profile
applesign -7 -i ${CODESIGNID} -m embedded.mobileprovision $UNSIGNED_IPA -o $SIGNED_IPA
# Speed up repackaging
rm -v $UNSIGNED_IPA | rm -v $SIGNED_IPA | 7z a $UNSIGNED_IPA Payload
# Re-sign IPA and set new Bundle ID
# caution,changing the Bundle ID can cause ios-deploy issues
// applesign -7 -i ${CODESIGNID} -b funky-chicken.resigned -m embedded.mobileprovision $UNSIGNED_IPA -o $SIGNED_IPA
Caution
You can't resign an encrypted app store app. Remember to decrypt that app !
Title | Detail |
---|---|
Missing Device ID | Check Provisioning Profile (embedded.mobileprovision ) included device's UUID |
Code signing key expired | Timeframe for paid iOS Developer license is one-year versus one-week for free developer signing key. |
Wrong Code-Signing Key | check the Code Signing Key was NOT an iPhone Distribution key |
Mismatched bundle ID | Error 0xe8008001 . When you create the Provisioning Profile it knows of the Bundle ID. So when you resign an IPA, it must match this value. |
identity is no longer valid | Error 0xe8008018: The identity used to sign the executable is no longer valid. Make sure that the Apple Development key was selected when running security find-identity -v -p codesigning , I hit this error when I selected a Developer ID Application . I should have selected the ID associated to Apple Development credential. |
Code Signing Keys Match | check the Code Signing Key used when creating the Provisioning Profile matched the Code Signing Key selected when repackaging and code signing. |
XCode check | When generating an app - to get hold of embedded.mobileprovision file - remember the Code signing options are different for each Project Target and ProjectTests. |
Delete Old Apps | check no old app is installed on the phone [ that was signed with a different key ] but has the same Bundle ID. |
Entitlements overload | You can have a Provisioning Profile (embedded.mobileprovision) that contained more Capabilities than the app you are re-signing. |
Clone Entitlements | When the app is complicated, with many entitlements, sometimes it is easier just to --clone-entitlements with Applesign . |
Wrong Bundle ID | When you add specific Entitlments you need a unique Bundle ID. Check whether you need to change Bundle ID when re-signing. |
Network settings | Settings\General\Profiles and Device Management to trust the Developer Profile and App. This won't happen if you are manually proxying or setting a local DNS server., when installing with iOS-deploy . |
Watch Extensions | iOS-deploy spits out lots of messages if you change the bundle ID when resigning an app ( Error 0xe800009e: This app contains an app extension with an illegal bundle identifier . If you use the free developer account, changing the Bundle ID is the only to repackage another party's app. I ended up deleting the Watch.app from the Payload bundle as I wasn't interested in testing. That worked. |
If none of the above work open Console.app
on macOS. Select your device and set process:mobile_installation_proxy
in the Search Bar
. This will give details behind the sideloaded IPA error message.
ios-deploy -b $SIGNED_IPA // defaults to send over wifi
ios-deploy -b -W $SIGNED_IPA // uses USB
ios-deploy -B | grep -i funky // list Bundle IDs
#### update host machine
pip3 install --upgrade frida
# list available devices
frida-ls-devices
# list processes and bundle ID from USB connected device
frida-ps -Uai
# Force open Calender on USB attached device
frida -U -f com.apple.mobilecal
# open foobar over usb and force start. starts app running
frida -U -f com.apple.mobilecal --no-pause
# get the target app's process ID from USB connected device
frida-ps -U | grep -i myapp
# Run script and quit Frida
frida -U -f foobar --no-pause -q --eval 'console.log("Hi Frida");'
Since Frida version ~12.7
, it was quick and simple to Frida on a Jailed device:
# Get Frida-Gadget
<https://github.com/frida/frida/releases>
# Unzip
gunzip frida-gadget-12.xx.xx-ios-universal.dylib.gz
# Create directory for Frida-Gadget
mkdir -p ~/.cache/frida
# Move Frida-Gadget
cp frida-gadget-12.xx.xx-ios-universal.dylib ~/.cache/frida/gadget-ios.dylib
# Invoke Frida-Gadget on Clean device
frida -U -f funky-chicken.debugger-challenge
frida -U "My App" // Attach Frida to app over USB
Process.id
419
Process.getCurrentThreadId()
3843
var b = "hello frida"
console.log(b)
"hello frida"
c = Memory.allocUtf8String(b)
"0x1067ec510"
Memory.readUtf8String(c)
"hello frida"
console.log(c)
0x1067ec510
console.log(c.readUtf8String(5))
hello
console.log(c.readUtf8String(11))
hello frida
ptrToC = new NativePointer(c);
"0x1067ec510"
console.log(ptrToC)
0x1067ec510
console.log(ptrToC.readCString(8))
hello fr
Memory.readUtf8String(ptrToC)
"hello frida"
Objective-C's syntax includes the :
and @
characters. These characters were not used in the Frida Javascript API
.
// Attach to playground process ID
frida -p $(ps -ax | grep -i -m1 playground |awk '{print $1}')
ObjC.available
true
ObjC.classes.UIDevice.currentDevice().systemVersion().toString()
"11.1"
ObjC.classes.NSBundle.mainBundle().executablePath().UTF8String()
ObjC.classes.UIWindow.keyWindow().toString()
RET: <WKNavigation: 0x106e165c0>
// shows Static Methods and Instance Methods
ObjC.classes.NSString.$ownMethods
ObjC.classes.NSString.$ivars
var myDate = ObjC.classes.NSDate.alloc().init()
console.log(myDate)
2019-04-19 19:03:46 +0000
myDate.timeIntervalSince1970()
1555700626.021566
myDate.description().toString()
"2019-04-19 19:03:46 +0000"
var a = ObjC.classes.NSUUID.alloc().init()
console.log(a)
4645BFD2-94EE-413D-9CE5-8982D41ED6AE
a.UUIDString()
{
"handle": "0x7ff3b2403b20"
}
a.UUIDString().toString()
"4645BFD2-94EE-413D-9CE5-8982D41ED6AE"
var b = ObjC.classes.NSString.stringWithString_("foo");
b.isKindOfClass_(ObjC.classes.NSString)
true
b.isKindOfClass_(ObjC.classes.NSUUID)
false
b.isEqualToString_("foo")
true
b.description().toString()
"foo"
var c = ObjC.classes.NSString.stringWithFormat_('foo ' + 'bar ' + 'lives');
console.log(c)
foo bar lives
var url = ObjC.classes.NSURL.URLWithString_('www.foobar.com')
console.log(url)
www.foobar.com
url.isKindOfClass_(ObjC.classes.NSURL)
true
console.log(url.$class)
NSURL
var b = ObjC.classes.NSString.stringWithString_("foo");
var d = ObjC.classes.NSData
d = b.dataUsingEncoding_(1) // NSASCIIStringEncoding = 1, NSUTF8StringEncoding = 4,
console.log(d)
<666f6f> // This prints the Hex value "666f6f = foo"
d.$className
"NSConcreteMutableData"
var x = d.CKHexString() // get you the Byte array as a Hex string
console.log(x)
666f6f
x.$className
"NSTaggedPointerString"
var newStr = ObjC.classes.NSString.stringWithUTF8String_[d.bytes]
// demoapp is the iOS app name
myapp=$(ps x | grep -i -m1 demoapp | awk '{print $1}')
frida-trace -i "getfsent*" -p $myapp
// Connect to process with Frida script
frida --codeshare mrmacete/objc-method-observer -p 85974
Process.enumerateModules()
// this will print all loaded Modules
Process.findModuleByName("libboringssl.dylib")
{
"base": "0x1861e2000",
"name": "libboringssl.dylib",
"path": "/usr/lib/libboringssl.dylib",
"size": 712704
}
Process.findModuleByAddress("0x1c1c4645c")
{
"base": "0x1c1c2a000",
"name": "libsystem_kernel.dylib",
"path": "/usr/lib/system/libsystem_kernel.dylib",
"size": 200704
}
DebugSymbol.fromAddress(Module.findExportByName(null, 'strstr'))
{
"address": "0x183cb81e8",
"fileName": "",
"lineNumber": 0,
"moduleName": "libsystem_c.dylib",
"name": "strstr"
}
Module.findExportByName(null, 'strstr')
"0x183cb81e8"
Module.getExportByName(null,'strstr')
"0x183cb81e8"
Process.findModuleByAddress("0x183cb81e8")
{
"base": "0x183cb6000",
"name": "libsystem_c.dylib",
"path": "/usr/lib/system/libsystem_c.dylib",
"size": 516096
}
a = Process.findModuleByName("Reachability")
a.enumerateExports()
....
{
"address": "0x102fab020",
"name": "ReachabilityVersionString",
"type": "variable"
},
{
"address": "0x102fab058",
"name": "ReachabilityVersionNumber",
"type": "variable"
}
....
...
..
frida -U -f funky-chicken.debugger-challenge --no-pause -q --eval 'var x={};Process.enumerateModulesSync().forEach(function(m){x[m.name] = Module.enumerateExportsSync(m.name)});' | grep -B 1 -A 1 task_threads
"address": "0x1c1c4645c",
"name": "task_threads",
"type": "function"
frida -U -f funky-chicken.debugger-challenge --no-pause -q --eval 'var x={};Process.findModuleByAddress("0x1c1c4645c");'
{
"base": "0x1c1c2a000",
"name": "libsystem_kernel.dylib",
"path": "/usr/lib/system/libsystem_kernel.dylib",
"size": 200704
}
[objc_playground]-> var a = ObjC.classes.NSString.stringWithString_("foo");
[objc_playground]-> a.superclass().toString()
"NSString"
[objc_playground]-> a.class().toString()
"NSTaggedPointerString"
// PASTE THIS CODE INTO THE FRIDA INTERFACE...
Interceptor.attach(ObjC.classes.NSTaggedPointerString['- isEqualToString:'].implementation, {
onEnter: function (args) {
var str = new ObjC.Object(ptr(args[2])).toString()
console.log('[+] Hooked NSTaggedPointerString[- isEqualToString:] ->' , str);
}
});
// TRIGGER YOUR INTERCEPTOR
[objc_playground_2]-> a.isEqualToString_("foo")
[+] Hooked NSTaggedPointerString[- isEqualToString:] -> foo
1 // TRUE
[objc_playground_2]-> a.isEqualToString_("bar")
[+] Hooked NSTaggedPointerString[- isEqualToString:] -> bar
0 // FALSE
// frida -U -l open.js --no-pause -f com.yd.demoapp
// the below javascript code is the contents of open.js
var targetFunction = Module.findExportByName("libsystem_kernel.dylib", "open");
Interceptor.attach(targetFunction, {
onEnter: function (args) {
const path = Memory.readUtf8String(this.context.x0);
console.log("[+] " + path)
}
});
try {
var targetFunctPtr = Module.findExportByName("YDAppModule", "$s9YDAppModule17ConfigC33publicKeyVerifyCertsSayypGvpfi");
if (targetFunctPtr == null) {
throw "[*] Target function not found";
}
Interceptor.attach(targetFunctPtr, {
onLeave: function(retval) {
var array = new ObjC.Object(retval);
console.log('[*]ObjC Class Type:\t' + array.$className);
return retval;
}
});
console.log("[*] publicKeyVerifyCertificates called ");
}
catch(err){
console.log("[!] Exception: " + err.message);
}
frida-trace --v // check it works
frida-trace --help // excellent place to read about Flags
frida-trace -f objc_playground // spawn and NO trace
frida-trace -m "+[NSUUID UUID]" -U "Debug CrackMe" // trace ObjC UUID static Class Method
frida-trace -m "*[ComVendorDebugger* *]" -U -f com.robot.demo.app // ObjC wildcard trace on Classes
frida-trace -m "*[YDDummyApp.UserProfileMngr *]" -U -f com.robot.demo.app // Trace mangled Swift functions
Instrumenting functions...
/* TID 0x403 */
1128 ms -[YDDummyApp.UserProfileMngr init]
1130 ms -[YDDummyApp.UserProfileMngr .cxx_destruct]
frida-trace -i "getaddrinfo" -i "SSLSetSessionOption" -U -f com.robot.demo // trace C function on iOS
frida-trace -m "*[*URLProtection* *]" -U -f com.robot.demo // for https challenge information
frida-trace -m "*[NSURLSession* *didReceiveChallenge*]" -U -f com.robot.demo // check whether https check delegate used
frida-trace -U -f com.robot.demo.app -I libsystem_c.dylib // Trace entire Module. Bad idea!
frida-trace -p $myapp -I UIKit // Trace UIKit Module. Bad idea.
frida-trace -f objc_playground -I CoreFoundation // Trace CoreFoundation Module. Terrible idea.
frida-trace -I YDRustyKit -U -f com.yd.mobile // Trace my own module.
frida-trace -m "-[NSURLRequest initWithURL:]" -U -f com.robot.demo // Get app files and APIs
frida-trace -m "-[NSURL initWithString:]" -U -f com.robot.demo // find the API endpoints
frida-trace -m "*[NSURL absoluteString]" -U -f com.robot.demo // my favorite of these
Edit the Frida-Trace auto-generated, template file.
onEnter: function (log, args, state) {
log("-[NSURLRequest initWithURL:" + args[2] + "]");
var str = new ObjC.Object(ptr(args[2])).toString()
console.log('[*] ' , str);
},
// results
[*] https://secretserver.nl/SignIn
frida-trace -i "*strcpy" -f hitme aaaa bbbb
Instrumenting functions...
_platform_strcpy: Loaded handler at "/.../__handlers__/libSystem.B.dylib/_platform_strcpy.js"
Started tracing 1 function. Press Ctrl+C to stop.
Edit the auto-generated, template Javascript file.
-----------
onEnter: function (log, args, state) {
// strcpy() arg1 is the Source. arg0 is the Destination.
console.log('\n[+] _platform_strcpy()');
var src_ptr = args[1].toString()
var src_string = Memory.readCString(args[1]);
var src_byte_array = Memory.readByteArray(args[1],4);
var textDecoder = new TextDecoder("utf-8");
var decoded = textDecoder.decode(src_byte_array);
console.log('[+] src_ptr\t-> ' , src_ptr);
console.log('[+] src_string\t-> ' + src_string);
console.log('[+] src_byte_array\t-> ' + src_byte_array);
console.log('[+] src_byte_array size\t-> ' + src_byte_array.byteLength);
console.log('[+] src_byte_array decoded\t-> ' + decoded);
},
The results:
[+] _platform_strcpy()
[+] src_ptr -> 0x7ffeefbffaa6
[+] src_string -> aaaa
[+] src_byte_array -> [object ArrayBuffer]
[+] src_byte_array size -> 4
[+] decoded -> aaaa
[+] _platform_strcpy()
[+] src_ptr -> 0x7ffeefbffaab
[+] src_string -> bbbb
[+] src_byte_array -> [object ArrayBuffer]
[+] src_byte_array size -> 4
[+] decoded -> bbbb
frida-ps -Uai // get your bundle ID
frida --codeshare mrmacete/objc-method-observer -U -f $BUNDLE_ID
[+] At the Frida prompt...
// Method isJailbroken
observeSomething('*[* isJail*]')
// Observe String compares
observeSomething('*[* isEqualToString*]');
// A Class ( ObjC ) or Module (Symbol ). The first asterix indicates it can be eith Instance or Class method
observeSomething('*[ABC* *]');
// Watch Cookies
observeSomething('-[WKWebsiteDataStore httpCookieStore]');
observeSomething('-[WKWebAllowDenyPolicyListener *]');
// dump the URL to hit
observeSomething('-[WKWebView loadRequest:]');
// you get all HTML, js, css, etc
observeSomething('-[WKWebView load*]');
// Read the entire request
observeSomething('-[WKWebView loadHTMLString:baseURL:]')
// Check for a custom UserAgent
observeSomething('-[WKWebView *Agent]');
# Rename Frida process
bash -c "exec -a YDFooBar ./frida-server &"
# Set Frida-Server on host to a specific interface and port
frida-server -l 0.0.0.0:19999 &
# Call Frida-server from Host
frida-ps -ai -H 192.168.0.38:19999
# Trace on custom port
frida-trace -m "*[NSURLSession* *didReceiveChallenge*]" -H 192.168.0.38:19999 -f $BUNDLE_ID
/private/var/mobile/Containers/Data/Application/<app guid, given at install time>/Library/Cookies/Cookies.binarycookies
scp -P 2222 root@localhost:/private/var/mobile/Containers/Data/Application/<App GUID>/Library/Cookies/Cookies.binarycookies cookies.bin
The original BinaryCookieReader
script out of date ( still Python 2 only ):
# install cookie file parser
pip3 install binary-cookies-parser
# read file
bcparser cookies.bin
# script from https://github.com/interference-security/frida-scripts/blob/master/iOS/show_binarycookies.js
frida -U -p 1990 -l show_binarycookies.js
$) ps -ax | grep -i WebKit.Networking
29163 ?? <longPath>/.../com.apple.WebKit.Networking
$) frida --codeshare mrmacete/objc-method-observer -p 29163
[PID::29163]-> %resume
[PID::29163]-> observeSomething('*[* cookiesWithResponseHeaderFields:forURL:]');
######################################
+[NSHTTPCookie cookiesWithResponseHeaderFields:forURL:]
cookiesWithResponseHeaderFields: {
"Set-Cookie" = "EuConsent=<removed for brevity>; path=/; expires=Sat, 16 Nov 2019 14:51:01 GMT;";
} (__NSSingleEntryDictionaryI)
forURL: https://uk.yahoo.com/?p=us&guccounter=1 (NSURL)
RET: (
"<NSHTTPCookie
version:0
name:EuConsent
value:<removed for brevity>
expiresDate:'2019-11-16 14:51:01 +0000'
created:'2019-11-15 14:51:01 +0000'
sessionOnly:FALSE
domain:yahoo.com
partition:none
sameSite:none
path:/
isSecure:FALSE
path:"/" isSecure:FALSE>"
)
WARNING: only change the minimum iOS version of a specific app's plist and not for the entire device. Things start to break - like calls into C libraries - when you change the device's read-only iOS version.
ssh onto device
root# cd /System/Library/CoreServices/
root# cat SystemVersion.plist
root# nano SystemVersion.plist
EDIT THE VALUE. KEEP THE OLD VALUE!
https://developer.apple.com/library/archive/qa/qa1964/_index.html
otool -l -arch all my_framework | grep __llvm_prf
nm -m -arch all my_app | grep gcov