aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcomex2015-01-28 02:54:21 -0500
committercomex2015-01-28 02:54:21 -0500
commit6536ff3cd2b2fac8a2068058735e77479341f19f (patch)
treeaa7186817874fc41ce8087cdcd4d520dbbc9b45a
parentsorta (diff)
downloadsubstitute-6536ff3cd2b2fac8a2068058735e77479341f19f.tar.gz
***yawn***
-rw-r--r--Makefile8
-rw-r--r--ios-bootstrap/generic-dyld-inserted.m5
-rw-r--r--ios-bootstrap/inject-into-launchd.c77
-rw-r--r--ios-bootstrap/posixspawn-hook.c10
-rw-r--r--ios-bootstrap/unrestrict-me.c11
-rw-r--r--lib/darwin/inject.c2
-rw-r--r--lib/darwin/unrestrict.c21
-rwxr-xr-xscript/gen-deb.sh2
8 files changed, 122 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 9fd0c34..b11646e 100644
--- a/Makefile
+++ b/Makefile
@@ -171,9 +171,15 @@ all: safety-dance
out/posixspawn-hook.dylib: ios-bootstrap/posixspawn-hook.c out/libsubstitute.dylib
$(CC) -dynamiclib -o $@ $< -Lout -lsubstitute
+out/generic-dyld-inserted.dylib: ios-bootstrap/generic-dyld-inserted.m out/libsubstitute.dylib
+ $(CC) -dynamiclib -o $@ $< -Lout -lsubstitute
out/unrestrict-me: ios-bootstrap/unrestrict-me.c out/libsubstitute.dylib
$(CC) -o $@ $< -Lout -lsubstitute
-all: out/posixspawn-hook.dylib out/unrestrict-me
+ ldid -Sent.plist $@
+out/inject-into-launchd: ios-bootstrap/inject-into-launchd.c out/libsubstitute.dylib
+ $(CC) -o $@ $< -Lout -lsubstitute -framework IOKit -framework CoreFoundation
+ ldid -Sent.plist $@
+all: out/posixspawn-hook.dylib out/generic-dyld-inserted.dylib out/unrestrict-me out/inject-into-launchd
endif
diff --git a/ios-bootstrap/generic-dyld-inserted.m b/ios-bootstrap/generic-dyld-inserted.m
new file mode 100644
index 0000000..532b844
--- /dev/null
+++ b/ios-bootstrap/generic-dyld-inserted.m
@@ -0,0 +1,5 @@
+#include <syslog.h>
+__attribute__((constructor))
+static void init() {
+ syslog(LOG_WARNING, "Hi!");
+}
diff --git a/ios-bootstrap/inject-into-launchd.c b/ios-bootstrap/inject-into-launchd.c
new file mode 100644
index 0000000..1da4a02
--- /dev/null
+++ b/ios-bootstrap/inject-into-launchd.c
@@ -0,0 +1,77 @@
+#include "substitute.h"
+#include "substitute-internal.h"
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <syslog.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+void *IOHIDEventCreateKeyboardEvent(CFAllocatorRef, uint64_t, uint32_t, uint32_t, bool, uint32_t);
+void *IOHIDEventSystemCreate(CFAllocatorRef);
+void *IOHIDEventSystemCopyEvent(void *, uint32_t, void *, uint32_t);
+
+CFIndex IOHIDEventGetIntegerValue(void *, uint32_t);
+enum {
+ kIOHIDEventTypeKeyboard = 3,
+ kIOHIDEventFieldKeyboardDown = 3 << 16 | 2,
+};
+
+static bool button_pressed(uint32_t usage_page, uint32_t usage) {
+ /* This magic comes straight from Substrate... I don't really understand
+ * what it's doing. In particular, where is the equivalent kernel
+ * implementation on OS X? Does it not exist? But I guess Substrate is
+ * emulating backboardd. */
+ void *dummy = IOHIDEventCreateKeyboardEvent(NULL, mach_absolute_time(),
+ usage_page, usage,
+ 0, 0);
+ if (!dummy) {
+ syslog(LOG_EMERG, "couldn't create dummy HID event");
+ return false;
+ }
+ void *event_system = IOHIDEventSystemCreate(NULL);
+ if (!event_system) {
+ syslog(LOG_EMERG, "couldn't create HID event system");
+ return false;
+ }
+ void *event = IOHIDEventSystemCopyEvent(event_system,
+ kIOHIDEventTypeKeyboard,
+ dummy, 0);
+ if (!event) {
+ syslog(LOG_EMERG, "couldn't copy HID event");
+ return false;
+ }
+ CFIndex ival = IOHIDEventGetIntegerValue(event, kIOHIDEventFieldKeyboardDown);
+ return ival;
+}
+
+int main(UNUSED int argc, char **argv) {
+ pid_t pid = argv[1] ? atoi(argv[1]) : 1; /* for testing */
+
+ if (button_pressed(0x0c, 0xe9) || /* consumer page -> Volume Increment */
+ button_pressed(0x0b, 0x21)) { /* telephony page -> Flash */
+ syslog(LOG_WARNING, "disabling due to button press");
+ return 0;
+ }
+ mach_port_t port = 0;
+ kern_return_t kr = mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_RECEIVE,
+ &port);
+ if (kr) {
+ syslog(LOG_EMERG, "mach_port_allocate: %x", kr);
+ return 0;
+ }
+ const char *lib = "/Library/Substitute/posixspawn-hook.dylib";
+ struct shuttle shuttle = {
+ .type = SUBSTITUTE_SHUTTLE_MACH_PORT,
+ .u.mach.right_type = MACH_MSG_TYPE_MAKE_SEND,
+ .u.mach.port = port
+ };
+ char *error;
+ int ret = substitute_dlopen_in_pid(pid, lib, 0, &shuttle, 1, &error);
+ if (ret) {
+ syslog(LOG_EMERG, "substitute_dlopen_in_pid: %s/%s",
+ substitute_strerror(ret), error);
+ return 0;
+ }
+}
diff --git a/ios-bootstrap/posixspawn-hook.c b/ios-bootstrap/posixspawn-hook.c
index 525b597..25c7973 100644
--- a/ios-bootstrap/posixspawn-hook.c
+++ b/ios-bootstrap/posixspawn-hook.c
@@ -67,7 +67,6 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old,
const char *p = orig_dyld_insert;
while (*p) { /* W.N.H. */
const char *next = strchr(p, ':') ?: (p + strlen(p));
- printf("p:%s next:%s\n", p, next);
/* append if it isn't a copy of ours */
if (!(next - p == sizeof(my_dylib) - 1 &&
memcmp(next, my_dylib, sizeof(my_dylib) - 1))) {
@@ -76,9 +75,10 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old,
memcpy(newp, p, next - p);
newp += next - p;
}
- p = next;
+ if (!*next)
+ break;
+ p = next + 1;
}
- printf("ok\n");
/* append ours if necessary */
if (!safe_mode) {
if (newp != newp_orig)
@@ -138,6 +138,10 @@ static int hook_posix_spawn_generic(__typeof__(posix_spawn) *old,
"posixspawn-hook: couldn't start unrestrict-me - oh well...");
goto skip;
}
+ int xstat;
+ /* reap intermediate to avoid zombie - if it doesn't work, not a big deal */
+ if (waitpid(prog_pid, &xstat, 0))
+ syslog(LOG_ERR, "posixspawn-hook: couldn't waitpid");
}
int ret = old(pid, path, file_actions, &my_attr, argv, envp_to_use);
diff --git a/ios-bootstrap/unrestrict-me.c b/ios-bootstrap/unrestrict-me.c
index a297471..5a2c6dd 100644
--- a/ios-bootstrap/unrestrict-me.c
+++ b/ios-bootstrap/unrestrict-me.c
@@ -2,6 +2,8 @@
#include "substitute-internal.h"
#include <stdlib.h>
#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
int main(int argc, char **argv) {
if (argc != 3) {
@@ -22,6 +24,15 @@ int main(int argc, char **argv) {
return 1;
}
+ /* double fork to avoid zombies */
+ int ret = fork();
+ if (ret == -1) {
+ syslog(LOG_EMERG, "unrestrict-me: fork: %s", strerror(errno));
+ return 1;
+ } else if (ret) {
+ return 0;
+ }
+
char *err = NULL;
int sret = substitute_ios_unrestrict((pid_t) pid, should_resume[0] == '1', &err);
if (sret) {
diff --git a/lib/darwin/inject.c b/lib/darwin/inject.c
index 76ecbcb..6ec07fa 100644
--- a/lib/darwin/inject.c
+++ b/lib/darwin/inject.c
@@ -397,6 +397,7 @@ static int do_baton(const char *filename, size_t filelen, bool is64,
size_t filelen_rounded = (filelen + 7) & ~7;
size_t total_len = baton_len + shuttles_len + filelen_rounded;
mach_vm_address_t target_stack_top = target_stackpage_end - total_len;
+ target_stack_top &= ~7;
*target_stack_top_p = target_stack_top;
char *stackbuf = calloc(total_len, 1);
if (!stackbuf) {
@@ -505,6 +506,7 @@ fail:
return ret;
}
+EXPORT
int substitute_dlopen_in_pid(int pid, const char *filename, int options,
const struct shuttle *shuttle, size_t nshuttle,
char **error) {
diff --git a/lib/darwin/unrestrict.c b/lib/darwin/unrestrict.c
index 6526019..dd852bc 100644
--- a/lib/darwin/unrestrict.c
+++ b/lib/darwin/unrestrict.c
@@ -2,6 +2,9 @@
#include "substitute-internal.h"
#include "darwin/mach-decls.h"
#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
#include <mach/vm_region.h>
static int unrestrict_macho_header(void *header, size_t size, bool *did_modify_p,
@@ -73,21 +76,19 @@ setback:
while (1) {
/* if calling from unrestrict-me, the process might not have transitioned
* yet. if it has, then TASK_DYLD_INFO will be filled with 0. */
- struct task_dyld_info tdi;
- mach_msg_type_number_t cnt = TASK_DYLD_INFO_COUNT;
+ task_basic_info_data_t tbi;
+ mach_msg_type_number_t cnt = TASK_BASIC_INFO_COUNT;
- kern_return_t kr = task_info(task, TASK_DYLD_INFO, (void *) &tdi, &cnt);
- if (kr || cnt != TASK_DYLD_INFO_COUNT) {
+ kern_return_t kr = task_info(task, TASK_BASIC_INFO, (void *) &tbi, &cnt);
+ if (kr || cnt != TASK_BASIC_INFO_COUNT) {
asprintf(error, "task_info: %x", kr);
ret = SUBSTITUTE_ERR_MISC;
goto fail;
}
- printf("=>%llx\n", tdi.all_image_info_addr);
- printf("=>%llx\n", tdi.all_image_info_size);
- if (tdi.all_image_info_size == 0)
+ if (tbi.user_time.seconds == 0 && tbi.user_time.microseconds == 0)
break;
if (retries++ == 20) {
- asprintf(error, "all_image_info_size was not 0 after 20 retries");
+ asprintf(error, "user_time was not 0 after 20 retries");
ret = SUBSTITUTE_ERR_MISC;
goto fail;
}
@@ -168,8 +169,8 @@ setback:
ret = SUBSTITUTE_OK;
fail:
if (should_resume) {
- if ((kr = task_resume(task))) {
- asprintf(error, "task_resume: %x", kr);
+ if ((kill(pid, SIGCONT))) {
+ asprintf(error, "kill: %s", strerror(errno));
ret = SUBSTITUTE_ERR_MISC;
}
}
diff --git a/script/gen-deb.sh b/script/gen-deb.sh
index d817ad2..656e61d 100755
--- a/script/gen-deb.sh
+++ b/script/gen-deb.sh
@@ -13,6 +13,8 @@ ln -s libsubstitute.0.dylib $debroot/usr/lib/libsubstitute.dylib
mkdir -p $debroot/usr/include/substitute
cp lib/substitute.h $debroot/usr/include/substitute/
cp substrate/substrate.h $debroot/usr/include/substitute/
+mkdir -p $debroot/Library/Substitute
+cp out/{posixspawn-hook.dylib,generic-dyld-inserted.dylib,unrestrict-me,inject-into-launchd} $debroot/Library/Substitute/
cp -a DEBIAN $debroot/
sed "s#{VERSION}#$version#g" DEBIAN/control > $debroot/DEBIAN/control
#... add bootstrap stuff