diff --git a/.gitignore b/.gitignore index c4ca332..d10fad9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ contrib/ *.o .vscode checkra1n* +payload.c +src/palera1n diff --git a/Makefile b/Makefile index b0cc49e..364518b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ SRC = $(shell pwd) DEP = $(SRC)/dep_root CC = cc -CFLAGS = -mmacosx-version-min=12.0 -I$(DEP)/include -I/opt/procursus/include -I$(SRC)/include -g -O0 -Wall -Wextra +CFLAGS = -mmacosx-version-min=12.0 -I$(DEP)/include -I/opt/procursus/include -I$(SRC)/include -I$(SRC) -g -O0 -Wall -Wextra LIBS = $(DEP)/lib/libimobiledevice-1.0.a $(DEP)/lib/libirecovery-1.0.a $(DEP)/lib/libusbmuxd-2.0.a $(DEP)/lib/libplist-2.0.a $(DEP)/lib/libimobiledevice-glue-1.0.a -pthread LIBS += $(DEP)/lib/libcrypto.35.tbd $(DEP)/lib/libssl.35.tbd LIBS += -framework CoreFoundation -framework SystemConfiguration -framework IOKit diff --git a/src/Makefile b/src/Makefile index 404289d..cd7b089 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,10 +1,13 @@ all: palera1n -OBJECTS = main.o dfuhelper.o lockdown_helper.o devhelper.o +OBJECTS = main.o dfuhelper.o lockdown_helper.o devhelper.o exec_checkra1n.o checkra1n.o %.o: %.c $(CC) -c $(CFLAGS) $< +checkra1n.c: checkra1n + xxd -iC checkra1n > checkra1n.c + palera1n: $(OBJECTS) $(CC) $(OBJECTS) $(CFLAGS) $(LDFLAGS) -o palera1n diff --git a/src/common.h b/src/common.h index 225819c..cfffeb8 100644 --- a/src/common.h +++ b/src/common.h @@ -57,4 +57,5 @@ int recvinfo_cmd(recvinfo_t* info, const uint64_t ecid); int autoboot_cmd(const uint64_t ecid); int exitrecv_cmd(const uint64_t ecid); +void exec_checkra1n(); #endif \ No newline at end of file diff --git a/src/dfuhelper.c b/src/dfuhelper.c index fcecccb..910e339 100644 --- a/src/dfuhelper.c +++ b/src/dfuhelper.c @@ -40,7 +40,7 @@ void step(int time, int time2, char *text, bool (*cond)(uint64_t), uint64_t cond printf(CYN "\r\e[K%s (%d)" CRESET, text, time - i + time2); fflush(stdout); sleep(1); - if (cond != NULL && cond(cond_arg)) return; + if (cond != NULL && cond(cond_arg)) pthread_exit(NULL); } printf(CYN "\r%s (%d)" CRESET, text, time2); if (time2 == 0) puts(""); @@ -80,11 +80,12 @@ int connected_normal_mode(const usbmuxd_device_info_t *usbmuxd_device) { } static bool conditional(uint64_t ecid) { - return ecid_wait_for_dfu == ecid; + return ecid_wait_for_dfu != ecid; } void* connected_recovery_mode(struct irecv_device_info* info) { int ret; + uint64_t ecid; if (!cpid_is_arm64(info->cpid)) { LOG(LOG_WARNING, "Ignoring non-arm64 device..."); return NULL; @@ -109,17 +110,18 @@ void* connected_recovery_mode(struct irecv_device_info* info) { } printf("\r\e[K"); ecid_wait_for_dfu = info->ecid; + ecid = info->ecid; bool nohome = NOHOME; if (nohome) step(2, 0, "Hold Volume Down + Side button", NULL, 0); else step(2, 0, "Hold Home + Power Button", NULL, 0); if (nohome) - step(10, 0, "Hold Volume Down button", conditional, info->ecid); + step(10, 0, "Hold Volume Down button", conditional, ecid); else - step(10, 0, "Hold Home button", conditional, info->ecid); + step(10, 0, "Hold Home button", conditional, ecid); + ecid_wait_for_dfu = 0; if (ecid_wait_for_dfu != info->ecid) { - LOG(LOG_INFO, "Device entered DFU mode successfully"); } else { LOG(LOG_WARNING, "Whoops, device did not enter DFU mode"); LOG(LOG_INFO, "Waiting for device to reconnect..."); @@ -129,9 +131,11 @@ void* connected_recovery_mode(struct irecv_device_info* info) { } void* connected_dfu_mode(struct irecv_device_info* info) { - + if (ecid_wait_for_dfu == info->ecid) { + ecid_wait_for_dfu = 0; + LOG(LOG_INFO, "Device entered DFU mode successfully"); + } unsubscribe_cmd(); - if (ecid_wait_for_dfu == info->ecid) ecid_wait_for_dfu = 0; spin = 0; return NULL; } @@ -150,6 +154,7 @@ void device_event_cb(const usbmuxd_event_t *event, void *userdata) { void irecv_device_event_cb(const irecv_device_event_t *event, void *userdata) { pthread_t recovery_thread, dfu_thread; + switch(event->type) { case IRECV_DEVICE_ADD: if (event->mode == IRECV_K_RECOVERY_MODE_1 || event->mode == IRECV_K_RECOVERY_MODE_2 || event->mode == IRECV_K_RECOVERY_MODE_3 || event->mode == IRECV_K_RECOVERY_MODE_4) { @@ -161,10 +166,8 @@ void irecv_device_event_cb(const irecv_device_event_t *event, void *userdata) { } break; case IRECV_DEVICE_REMOVE: - if (event->mode == IRECV_K_RECOVERY_MODE_1 || event->mode == IRECV_K_RECOVERY_MODE_2 || event->mode == IRECV_K_RECOVERY_MODE_3 || event->mode == IRECV_K_RECOVERY_MODE_4) { - LOG(LOG_VERBOSE, "Recovery mode device %ld disconnected", event->device_info->serial_string); - } else if (event->mode == IRECV_K_DFU_MODE) { - LOG(LOG_VERBOSE, "DFU mode device %ld disconnected", event->device_info->ecid); + if (event->device_info->ecid == ecid_wait_for_dfu) { + LOG(LOG_VERBOSE, "Recovery mode device %ld disconnected", event->device_info->ecid); } break; } diff --git a/src/exec_checkra1n.c b/src/exec_checkra1n.c index e69de29..ea40dca 100644 --- a/src/exec_checkra1n.c +++ b/src/exec_checkra1n.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern char **environ; + +#include "common.h" +#include "checkra1n.h" + +void exec_checkra1n() { + LOG(LOG_INFO, "About to execute checkra1n"); + int fd, ret; + char checkra1n_path[] = "/tmp/checkra1n.XXXXXX"; + fd = mkstemp(checkra1n_path); + if (fd == -1) { + LOG(LOG_FATAL, "Cannot open temporary file: %d (%s)", errno, strerror(errno)); + return; + } + ssize_t didWrite = write(fd, checkra1n, checkra1n_len); + if (didWrite != checkra1n_len) { + LOG(LOG_FATAL, "Size written does not match expected: %lld != %d: %d (%s)", didWrite, checkra1n_len, errno, strerror(errno)); + close(fd); + unlink(checkra1n_path); + return; + } + close(fd); + ret = chmod(checkra1n_path, 0700); + if (ret) { + LOG(LOG_FATAL, "Cannot chmod %s: %d (%s)", checkra1n_path, errno, strerror(errno)); + unlink(checkra1n_path); + } + char* checkra1n_qrgv[] = { + checkra1n_path, + "-pVE", + NULL + }; + pid_t pid; + ret = posix_spawn(&pid, checkra1n_path, NULL, NULL, checkra1n_qrgv, environ); + if (ret) { + LOG(LOG_FATAL, "Cannot posix spawn %s: %d (%s)", checkra1n_path, errno, strerror(errno)); + unlink(checkra1n_path); + } + unlink(checkra1n_path); + waitpid(pid, NULL, 0); + return; +} diff --git a/src/main.c b/src/main.c index a2dc13a..a3ff54e 100644 --- a/src/main.c +++ b/src/main.c @@ -57,5 +57,6 @@ int main(int argc, char* argv[]) { pthread_t dfuhelper_thread; pthread_create(&dfuhelper_thread, NULL, dfuhelper, NULL); pthread_join(dfuhelper_thread, NULL); + exec_checkra1n(); return 0; } diff --git a/src/palera1n b/src/palera1n deleted file mode 100755 index 4bdbe13..0000000 Binary files a/src/palera1n and /dev/null differ