|
@@ -25,6 +25,7 @@
|
|
|
#include "topangadetect.h"
|
|
|
#include "unliberios.h"
|
|
|
#include "removeElectrabeta.h"
|
|
|
+#include "fun_objc.h"
|
|
|
|
|
|
mach_port_t tfpzero;
|
|
|
|
|
@@ -60,7 +61,7 @@ int begin_fun(mach_port_t tfp0, mach_port_t user_client, bool enable_tweaks) {
|
|
|
uint64_t kernel_base_electra = find_kernel_base();
|
|
|
uint64_t slide = kernel_base_electra - 0xFFFFFFF007004000;
|
|
|
printf("slide: 0x%016llx\n", slide);
|
|
|
-
|
|
|
+ writeMessagePlain("slide: 0x%016llx\n", slide);
|
|
|
// From v0rtex - get the IOSurfaceRootUserClient port, and then the address of the actual client, and vtable
|
|
|
uint64_t IOSurfaceRootUserClient_port = find_port_address_electra(user_client, MACH_MSG_TYPE_MAKE_SEND); // UserClients are just mach_ports, so we find its address
|
|
|
uint64_t IOSurfaceRootUserClient_addr = rk64_electra(IOSurfaceRootUserClient_port + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT)); // The UserClient itself (the C++ object) is at the kobject field
|
|
@@ -71,23 +72,23 @@ int begin_fun(mach_port_t tfp0, mach_port_t user_client, bool enable_tweaks) {
|
|
|
|
|
|
// Create the vtable in the kernel memory, then copy the existing vtable into there
|
|
|
uint64_t fake_vtable = kalloc(0x1000);
|
|
|
- printf("Created fake_vtable at %016llx\n", fake_vtable);
|
|
|
+ writeMessagePlain("Created fake_vtable at %016llx\n", fake_vtable);
|
|
|
|
|
|
for (int i = 0; i < 0x200; i++) {
|
|
|
wk64_electra(fake_vtable+i*8, rk64_electra(IOSurfaceRootUserClient_vtab+i*8));
|
|
|
}
|
|
|
|
|
|
- printf("Copied some of the vtable over\n");
|
|
|
+ writeMessagePlain("Copied some of the vtable over\n");
|
|
|
|
|
|
// Create the fake user client
|
|
|
uint64_t fake_client = kalloc(0x1000);
|
|
|
- printf("Created fake_client at %016llx\n", fake_client);
|
|
|
+ writeMessagePlain("Created fake_client at %016llx\n", fake_client);
|
|
|
|
|
|
for (int i = 0; i < 0x200; i++) {
|
|
|
wk64_electra(fake_client+i*8, rk64_electra(IOSurfaceRootUserClient_addr+i*8));
|
|
|
}
|
|
|
|
|
|
- printf("Copied the user client over\n");
|
|
|
+ writeMessagePlain("Copied the user client over\n");
|
|
|
|
|
|
// Write our fake vtable into the fake user client
|
|
|
wk64_electra(fake_client, fake_vtable);
|
|
@@ -100,7 +101,7 @@ int begin_fun(mach_port_t tfp0, mach_port_t user_client, bool enable_tweaks) {
|
|
|
// Replace IOUserClient::getExternalTrapForIndex with our ROP gadget (add x0, x0, #0x40; ret;)
|
|
|
wk64_electra(fake_vtable+8*0xB7, find_add_x0_x0_0x40_ret());
|
|
|
|
|
|
- printf("Wrote the `add x0, x0, #0x40; ret;` gadget over getExternalTrapForIndex\n");
|
|
|
+ writeMessagePlain("Wrote the `add x0, x0, #0x40; ret;` gadget over getExternalTrapForIndex\n");
|
|
|
|
|
|
// When calling IOConnectTrapX, this makes a call to iokit_user_client_trap, which is the user->kernel call (MIG). This then calls IOUserClient::getTargetAndTrapForIndex
|
|
|
// 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.
|
|
@@ -143,25 +144,25 @@ do { \
|
|
|
} else if (pid == 0) {
|
|
|
kern_proc = proc;
|
|
|
} else if (pid == 1){
|
|
|
- printf("found launchd\n");
|
|
|
+ writeMessagePlain("found launchd\n");
|
|
|
|
|
|
uint32_t csflags = rk32_electra(proc + offsetof_p_csflags);
|
|
|
wk32_electra(proc + offsetof_p_csflags, (csflags | CS_PLATFORM_BINARY | CS_INSTALLER | CS_GET_TASK_ALLOW) & ~(CS_RESTRICT | CS_HARD));
|
|
|
} else if (strstr(name, "amfid")) {
|
|
|
- printf("found amfid - getting task\n");
|
|
|
+ writeMessagePlain("found amfid - getting task\n");
|
|
|
amfid_proc = proc;
|
|
|
amfid_pid = pid;
|
|
|
|
|
|
uint32_t csflags = rk32_electra(proc + offsetof_p_csflags);
|
|
|
wk32_electra(proc + offsetof_p_csflags, (csflags | CS_PLATFORM_BINARY | CS_INSTALLER | CS_GET_TASK_ALLOW) & ~(CS_RESTRICT | CS_HARD));
|
|
|
} else if (strstr(name, "cfprefsd")){
|
|
|
- printf("found cfprefsd. keeping PID\n");
|
|
|
+ writeMessagePlain("found cfprefsd. keeping PID\n");
|
|
|
cfprefsd_pid = pid;
|
|
|
} else if (strstr(name, "backboardd")){
|
|
|
- printf("found backboardd. keeping PID\n");
|
|
|
+ writeMessagePlain("found backboardd. keeping PID\n");
|
|
|
backboardd_pid = pid;
|
|
|
} else if (strstr(name, "jailbreakd")){
|
|
|
- printf("found jailbreakd. already jailbroken!\n");
|
|
|
+ writeMessagePlain("found jailbreakd. already jailbroken!\n");
|
|
|
found_jailbreakd = true;
|
|
|
}
|
|
|
proc = rk64_electra(proc);
|
|
@@ -172,8 +173,8 @@ do { \
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- printf("our proc is at 0x%016llx\n", our_proc);
|
|
|
- printf("kern proc is at 0x%016llx\n", kern_proc);
|
|
|
+ writeMessagePlain("our proc is at 0x%016llx\n", our_proc);
|
|
|
+ writeMessagePlain("kern proc is at 0x%016llx\n", kern_proc);
|
|
|
|
|
|
// Properly copy the kernel's credentials so setuid(0) doesn't crash
|
|
|
uint64_t kern_ucred = 0;
|
|
@@ -187,15 +188,15 @@ do { \
|
|
|
|
|
|
setuid(0);
|
|
|
|
|
|
- printf("our uid is %d\n", getuid());
|
|
|
+ writeMessagePlain("our uid is %d\n", getuid());
|
|
|
|
|
|
// Test writing to file
|
|
|
{
|
|
|
FILE *f = fopen("/var/mobile/test.txt", "w");
|
|
|
if (f == 0) {
|
|
|
- printf("failed to write test file");
|
|
|
+ writeMessagePlain("failed to write test file");
|
|
|
} else {
|
|
|
- printf("wrote test file: %p\n", f);
|
|
|
+ writeMessagePlain("wrote test file: %p\n", f);
|
|
|
}
|
|
|
|
|
|
unlink("/var/mobile/test.txt");
|
|
@@ -207,7 +208,7 @@ do { \
|
|
|
if (remap_tfp0_set_hsp4(&real_tfp0)) {
|
|
|
real_tfp0 = MACH_PORT_NULL;
|
|
|
}
|
|
|
- printf("remapped tfp0: 0x%x\n", real_tfp0);
|
|
|
+ writeMessagePlain("remapped tfp0: 0x%x\n", real_tfp0);
|
|
|
}
|
|
|
|
|
|
// Remount / as rw - patch by xerub with nosuid patch added by coolstar
|
|
@@ -224,7 +225,7 @@ do { \
|
|
|
|
|
|
char *nmz = strdup("/dev/disk0s1s1");
|
|
|
int rv = mount("apfs", "/", MNT_UPDATE, (void *)&nmz);
|
|
|
- printf("remounting: %d\n", rv);
|
|
|
+ writeMessagePlain("remounting: %d\n", rv);
|
|
|
|
|
|
v_mount = rk64_electra(rootfs_vnode + offsetof_v_mount);
|
|
|
wk32_electra(v_mount + offsetof_mnt_flag, v_flag);
|
|
@@ -233,7 +234,7 @@ do { \
|
|
|
if (fd == -1) {
|
|
|
fd = creat("/.bit_of_fun", 0644);
|
|
|
} else {
|
|
|
- printf("File already exists!\n");
|
|
|
+ writeMessagePlain("File already exists!\n");
|
|
|
}
|
|
|
close(fd);
|
|
|
}
|
|
@@ -283,14 +284,14 @@ do { \
|
|
|
removingElectraBeta();
|
|
|
removeElectraBeta();
|
|
|
|
|
|
- printf("APFS Snapshots: \n");
|
|
|
- printf("=========\n");
|
|
|
+ writeMessagePlain("APFS Snapshots: \n");
|
|
|
+ writeMessagePlain("=========\n");
|
|
|
list_snapshots("/");
|
|
|
- printf("=========\n");
|
|
|
+ writeMessagePlain("=========\n");
|
|
|
|
|
|
int snapshot = check_snapshot("/", "electra-prejailbreak");
|
|
|
if (snapshot == 1){
|
|
|
- printf("Snapshot exists!\n");
|
|
|
+ writeMessagePlain("Snapshot exists!\n");
|
|
|
} else if (snapshot == 0){
|
|
|
rename("/electra/createSnapshot", "/createSnapshot");
|
|
|
rv = posix_spawn(&pd, "/electra/rm", NULL, NULL, (char **)&(const char*[]){ "rm", "-rf", "/electra", NULL }, NULL);
|
|
@@ -299,11 +300,11 @@ do { \
|
|
|
rv = posix_spawn(&pd, "/createSnapshot", NULL, NULL, (char **)&(const char*[]){ "createSnapshot", NULL }, NULL);
|
|
|
waitpid(pd, NULL, 0);
|
|
|
|
|
|
- printf("APFS Snapshots: \n");
|
|
|
+ writeMessagePlain("APFS Snapshots: \n");
|
|
|
|
|
|
- printf("=========\n");
|
|
|
+ writeMessagePlain("=========\n");
|
|
|
list_snapshots("/");
|
|
|
- printf("=========\n");
|
|
|
+ writeMessagePlain("=========\n");
|
|
|
|
|
|
snapshot = check_snapshot("/", "electra-prejailbreak");
|
|
|
if (snapshot != 1){
|
|
@@ -342,11 +343,11 @@ do { \
|
|
|
|
|
|
wk64_electra(IOSurfaceRootUserClient_port + koffset(KSTRUCT_OFFSET_IPC_PORT_IP_KOBJECT), IOSurfaceRootUserClient_addr);
|
|
|
|
|
|
- printf("Starting server...\n");
|
|
|
+ writeMessagePlain("Starting server...\n");
|
|
|
start_jailbreakd(kernel_base_electra);
|
|
|
|
|
|
while (!file_exists_electra("/var/run/jailbreakd.pid")){
|
|
|
- printf("Waiting for jailbreakd...\n");
|
|
|
+ writeMessagePlain("Waiting for jailbreakd...\n");
|
|
|
usleep(100000); //100 ms
|
|
|
}
|
|
|
|