diff --git a/ios/AppDelegate.mm b/ios/AppDelegate.mm index 5ae6e18003..289db7f942 100644 --- a/ios/AppDelegate.mm +++ b/ios/AppDelegate.mm @@ -105,4 +105,8 @@ NativeMessageReceived("got_focus", ""); } +- (void)applicationWillTerminate:(UIApplication *)application { + exit(0); +} + @end diff --git a/ios/codesign.h b/ios/codesign.h deleted file mode 100644 index 57df032409..0000000000 --- a/ios/codesign.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the License - * may not be used to create, or enable the creation or redistribution of, - * unlawful or unlicensed copies of an Apple operating system, or to - * circumvent, violate, or enable the circumvention or violation of, any - * terms of an Apple operating system software license agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ - -#ifndef _SYS_CODESIGN_H_ -#define _SYS_CODESIGN_H_ - -#include - -/* code signing attributes of a process */ -#define CS_VALID 0x0001 /* dynamically valid */ -#define CS_HARD 0x0100 /* don't load invalid pages */ -#define CS_KILL 0x0200 /* kill process if it becomes invalid */ -#define CS_EXEC_SET_HARD 0x1000 /* set CS_HARD on any exec'ed process */ -#define CS_EXEC_SET_KILL 0x2000 /* set CS_KILL on any exec'ed process */ -#define CS_KILLED 0x10000 /* was killed by kernel for invalidity */ -#define CS_RESTRICT 0x20000 /* tell dyld to treat restricted */ - -/* csops operations */ -#define CS_OPS_STATUS 0 /* return status */ -#define CS_OPS_MARKINVALID 1 /* invalidate process */ -#define CS_OPS_MARKHARD 2 /* set HARD flag */ -#define CS_OPS_MARKKILL 3 /* set KILL flag (sticky) */ -#define CS_OPS_PIDPATH 4 /* get executable's pathname */ -#define CS_OPS_CDHASH 5 /* get code directory hash */ -#define CS_OPS_PIDOFFSET 6 /* get offset of active Mach-o slice */ -#define CS_OPS_ENTITLEMENTS_BLOB 7 /* get entitlements blob */ -#define CS_OPS_MARKRESTRICT 8 /* set RESTRICT flag (sticky) */ - -#ifndef KERNEL - -__BEGIN_DECLS - -/* code sign operations */ -int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize); - -__END_DECLS - -#endif /* ! KERNEL */ - -#endif /* _SYS_CODESIGN_H_ */ diff --git a/ios/main.mm b/ios/main.mm index 107a804b6e..ff23140b43 100644 --- a/ios/main.mm +++ b/ios/main.mm @@ -1,12 +1,14 @@ // main.mm boilerplate #import +#import +#import +#import #import #import #import #import #import -#import "codesign.h" #import "AppDelegate.h" #import "PPSSPPUIApplication.h" @@ -15,53 +17,33 @@ #include "base/NativeApp.h" #include "profiler/profiler.h" -#define CS_OPS_STATUS 0 /* return status */ -#define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */ -#define PTRACE_TRACEME 0 /* Indicate that this process is to be traced by its parent. */ -#define PT_ATTACHEXC 14 /* attach to running process with signal exception */ -#define PT_DETACH 11 /* stop tracing a process */ -int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize); -#define ptrace(a, b, c, d) syscall(SYS_ptrace, a, b, c, d) +#define CS_OPS_STATUS 0 /* return status */ +#define CS_DEBUGGED 0x10000000 /* process is currently or has previously been debugged and allowed to run with invalid pages */ +#define PT_TRACE_ME 0 /* child declares it's being traced */ +#define PT_SIGEXC 12 /* signals as exceptions for current_proc */ -bool get_debugged() { +static int (*csops)(pid_t pid, unsigned int ops, void * useraddr, size_t usersize); +static boolean_t (*exc_server)(mach_msg_header_t *, mach_msg_header_t *); +static int (*ptrace)(int request, pid_t pid, caddr_t addr, int data); + +bool cs_debugged() { int flags; - int rv = csops(getpid(), CS_OPS_STATUS, &flags, sizeof(flags)); - if (rv==0 && flags&CS_DEBUGGED) return true; + return !csops(getpid(), CS_OPS_STATUS, &flags, sizeof(flags)) && flags & CS_DEBUGGED; +} - pid_t pid = fork(); - if (pid > 0) { - int st,rv,i=0; - do { - usleep(500); - rv = waitpid(pid, &st, 0); - } while (rv<0 && i++<10); - if (rv<0) fprintf(stderr, "Unable to wait for child?\n"); - } else if (pid == 0) { - pid_t ppid = getppid(); - int rv = ptrace(PT_ATTACHEXC, ppid, 0, 0); - if (rv) { - perror("Unable to attach to process"); - exit(1); - } - for (int i=0; i<100; i++) { - usleep(1000); - errno = 0; - rv = ptrace(PT_DETACH, ppid, 0, 0); - if (rv==0) break; - } - if (rv) { - perror("Unable to detach from process"); - exit(1); - } - exit(0); - } else { - perror("Unable to fork"); - } +kern_return_t catch_exception_raise(mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + exception_data_t code, + mach_msg_type_number_t code_count) { + return KERN_FAILURE; +} - rv = csops(getpid(), CS_OPS_STATUS, &flags, sizeof(flags)); - if (rv==0 && flags&CS_DEBUGGED) return true; - - return false; +void *exception_handler(void *argument) { + auto port = *reinterpret_cast(argument); + mach_msg_server(exc_server, 2048, port, 0); + return NULL; } @@ -185,10 +167,28 @@ void Vibrate(int mode) { int main(int argc, char *argv[]) { + csops = reinterpret_cast(dlsym(dlopen(nullptr, RTLD_LAZY), "csops")); + exc_server = reinterpret_cast(dlsym(dlopen(NULL, RTLD_LAZY), "exc_server")); + ptrace = reinterpret_cast(dlsym(dlopen(NULL, RTLD_LAZY), "ptrace")); // see https://github.com/hrydgard/ppsspp/issues/11905 - if (!get_debugged()) { - fprintf(stderr, "Unable to cleanly obtain CS_DEBUGGED - probably not jailbroken. Attempting old method.\n"); - ptrace(PTRACE_TRACEME, 0, 0, 0); + if (!cs_debugged()) { + pid_t pid = fork(); + if (pid == 0) { + ptrace(PT_TRACE_ME, 0, nullptr, 0); + exit(0); + } else if (pid < 0) { + perror("Unable to fork"); + + ptrace(PT_TRACE_ME, 0, nullptr, 0); + ptrace(PT_SIGEXC, 0, nullptr, 0); + + mach_port_t port = MACH_PORT_NULL; + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); + mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND); + task_set_exception_ports(mach_task_self(), EXC_MASK_SOFTWARE, port, EXCEPTION_DEFAULT, THREAD_STATE_NONE); + pthread_t thread; + pthread_create(&thread, nullptr, exception_handler, reinterpret_cast(&port)); + } } PROFILE_INIT();