Skip to content

Commit

Permalink
Merge pull request #3 from mologie/xpc-support
Browse files Browse the repository at this point in the history
Add XPC support
  • Loading branch information
rpetrich committed Mar 22, 2014
2 parents f4de0cf + 16f54c6 commit 6ad404f
Show file tree
Hide file tree
Showing 21 changed files with 4,265 additions and 21 deletions.
21 changes: 13 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ librocketbootstrap_FRAMEWORKS = Foundation

ADDITIONAL_CFLAGS = -std=c99

IPHONE_ARCHS = armv6 armv7 armv7s arm64

SDKVERSION_armv6 = 5.1
INCLUDE_SDKVERSION_armv6 = 7.0
TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0

TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0
THEOS_PLATFORM_SDK_ROOT_armv6 = /Applications/Xcode_Legacy.app/Contents/Developer
NOLEGACY ?= 0
ifeq ($(NOLEGACY), 0)
IPHONE_ARCHS = armv6 armv7 armv7s arm64
SDKVERSION_armv6 = 5.1
INCLUDE_SDKVERSION_armv6 = 7.0
TARGET_IPHONEOS_DEPLOYMENT_VERSION = 4.0
TARGET_IPHONEOS_DEPLOYMENT_VERSION_armv6 = 3.0
THEOS_PLATFORM_SDK_ROOT_armv6 = /Applications/Xcode_Legacy.app/Contents/Developer
else
IPHONE_ARCHS = armv7 armv7s arm64
TARGET_IPHONEOS_DEPLOYMENT_VERSION = 5.0
endif

include framework/makefiles/common.mk
include framework/makefiles/tweak.mk
include framework/makefiles/library.mk

stage::
Expand Down
93 changes: 92 additions & 1 deletion Shims.x
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ kern_return_t $bootstrap_look_up3(mach_port_t bp, const name_t service_name, mac
if (obj) {
[threadDictionary removeObjectForKey:@"rocketbootstrap_intercept_next_lookup"];
[pool drain];
return rocketbootstrap_look_up(bp, service_name, sp);
return rocketbootstrap_look_up3(bp, service_name, sp, target_pid, instance_id, flags);
}
[pool drain];
return _bootstrap_look_up3(bp, service_name, sp, target_pid, instance_id, flags);
Expand Down Expand Up @@ -117,3 +117,94 @@ void rocketbootstrap_distributedmessagingcenter_apply(CPDistributedMessagingCent
OSSpinLockUnlock(&spin_lock);
objc_setAssociatedObject(messaging_center, &has_hooked_messaging_center, (id)kCFBooleanTrue, OBJC_ASSOCIATION_ASSIGN);
}

typedef void *xpc_connection_t;
typedef void(*_xpc_connection_init_type)(xpc_connection_t connection);
static _xpc_connection_init_type _xpc_connection_init;
static _xpc_connection_init_type __xpc_connection_init;
extern void xpc_connection_cancel(xpc_connection_t connection) __attribute__((weak_import));
typedef void(*xpc_connection_cancel_type)(xpc_connection_t connection);
static xpc_connection_cancel_type _xpc_connection_cancel;
extern const char *xpc_connection_get_name(xpc_connection_t connection) __attribute__((weak_import));
static CFMutableSetRef tracked_xpc_connections;

// FIXME this theos fork's Cydia Substrate headers are outdated; the stub it builds however contains the following functions
typedef const void *MSImageRef;
MSImageRef MSGetImageByName(const char *file);
void *MSFindSymbol(const void *image, const char *name);

static void $_xpc_connection_init(xpc_connection_t connection)
{
OSSpinLockLock(&spin_lock);
Boolean tracking_connection;
if (tracked_xpc_connections) {
tracking_connection = CFSetContainsValue(tracked_xpc_connections, connection);
} else {
tracking_connection = false;
}
OSSpinLockUnlock(&spin_lock);
if (tracking_connection) {
hook_bootstrap_lookup();
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *threadDictionary = [NSThread currentThread].threadDictionary;
[threadDictionary setObject:(id)kCFBooleanTrue forKey:@"rocketbootstrap_intercept_next_lookup"];
__xpc_connection_init(connection);
[threadDictionary removeObjectForKey:@"rocketbootstrap_intercept_next_lookup"];
[pool drain];
} else {
__xpc_connection_init(connection);
}
}

void $xpc_connection_cancel(xpc_connection_t connection)
{
OSSpinLockLock(&spin_lock);
if (tracked_xpc_connections) {
CFSetRemoveValue(tracked_xpc_connections, connection);
}
OSSpinLockUnlock(&spin_lock);
_xpc_connection_cancel(connection);
}

static void hook_xpc(void)
{
static bool hooked_xpc;
OSSpinLockLock(&spin_lock);
if (!hooked_xpc) {
MSImageRef libxpc = MSGetImageByName("/usr/lib/system/libxpc.dylib");
if (libxpc) {
_xpc_connection_init = MSFindSymbol(libxpc, "__xpc_connection_init");
if (_xpc_connection_init) {
MSHookFunction(_xpc_connection_init, $_xpc_connection_init, (void **)&__xpc_connection_init);
} else {
NSLog(@"RocketBootstrap: Cannot find _xpc_connection_init in libxpc.dylib");
}
MSHookFunction(xpc_connection_cancel, $xpc_connection_cancel, (void **)&_xpc_connection_cancel);
} else {
NSLog(@"RocketBootstrap: Cannot open /usr/lib/system/libxpc.dylib");
}
hooked_xpc = true;
}
OSSpinLockUnlock(&spin_lock);
}

void rocketbootstrap_xpc_connection_apply(xpc_connection_t connection)
{
if (rocketbootstrap_is_passthrough())
return;
hook_xpc();
OSSpinLockLock(&spin_lock);
if (!tracked_xpc_connections) {
tracked_xpc_connections = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
}
CFSetAddValue(tracked_xpc_connections, connection);
OSSpinLockUnlock(&spin_lock);
}

kern_return_t rocketbootstrap_xpc_unlock(xpc_connection_t listener)
{
const char *name = xpc_connection_get_name(listener);
if (!name)
return KERN_INVALID_ADDRESS;
return rocketbootstrap_unlock(name);
}
14 changes: 13 additions & 1 deletion Tweak.x
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
typedef struct {
mach_msg_header_t head;
mach_msg_body_t body;
pid_t target_pid;
uuid_t instance_id;
uint64_t flags;
uint32_t name_length;
char name[];
} _rocketbootstrap_lookup_query_t;
Expand All @@ -36,6 +39,12 @@ static NSMutableSet *allowedNames;
static volatile OSSpinLock namesLock;

kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name, mach_port_t *sp)
{
uuid_t instance_id = { 0 };
return rocketbootstrap_look_up3(bp, service_name, sp, 0, instance_id, 0);
}

kern_return_t rocketbootstrap_look_up3(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags)
{
if (rocketbootstrap_is_passthrough() || %c(SBUserNotificationCenter)) {
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_5_0) {
Expand Down Expand Up @@ -73,6 +82,9 @@ kern_return_t rocketbootstrap_look_up(mach_port_t bp, const name_t service_name,
message->head.msgh_local_port = replyPort;
message->head.msgh_reserved = 0;
message->head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
message->target_pid = target_pid;
memcpy(message->instance_id, instance_id, sizeof(uuid_t));
message->flags = flags;
message->name_length = service_name_size;
memcpy(&message->name[0], service_name, service_name_size);
err = mach_msg(&message->head, MACH_SEND_MSG | MACH_RCV_MSG | MACH_RCV_TIMEOUT, size, size, replyPort, 200, MACH_PORT_NULL);
Expand Down Expand Up @@ -175,7 +187,7 @@ static void replacementMachPortCallback(CFMachPortRef port, void *bytes, CFIndex
mach_port_t bootstrap = MACH_PORT_NULL;
err = task_get_bootstrap_port(selfTask, &bootstrap);
if (!err) {
bootstrap_look_up(bootstrap, [name UTF8String], &servicePort);
bootstrap_look_up3(bootstrap, [name UTF8String], &servicePort, lookup_message->target_pid, lookup_message->instance_id, lookup_message->flags);
}
}
[name release];
Expand Down
70 changes: 70 additions & 0 deletions bootstrap_priv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2007 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/

#ifndef __BOOTSTRAP_PRIVATE_H__
#define __BOOTSTRAP_PRIVATE_H__

#include "bootstrap.h"
#include <sys/types.h>
#include <uuid/uuid.h>

__BEGIN_DECLS

#pragma GCC visibility push(default)

#define BOOTSTRAP_PER_PID_SERVICE (1 << 0)
#define BOOTSTRAP_ALLOW_LOOKUP (1 << 1)
#define BOOTSTRAP_DENY_JOB_CREATION (1 << 2)
#define BOOTSTRAP_PRIVILEGED_SERVER (1 << 3)
#define BOOTSTRAP_FORCE_LOCAL (1 << 4)
#define BOOTSTRAP_SPECIFIC_INSTANCE (1 << 5)
#define BOOTSTRAP_STRICT_CHECKIN (1 << 6)
#define BOOTSTRAP_STRICT_LOOKUP (1 << 7)

#define BOOTSTRAP_PROPERTY_EXPLICITSUBSET (1 << 0) /* Created via bootstrap_subset(). */
#define BOOTSTRAP_PROPERTY_IMPLICITSUBSET (1 << 1) /* Created via _vprocmgr_switch_to_session(). */
#define BOOTSTRAP_PROPERTY_MOVEDSUBSET (1 << 2) /* Created via _vprocmgr_move_subset_to_user(). */
#define BOOTSTRAP_PROPERTY_PERUSER (1 << 3) /* A per-user launchd's root bootstrap. */
#define BOOTSTRAP_PROPERTY_XPC_DOMAIN (1 << 4) /* An XPC domain. Duh. */
#define BOOTSTRAP_PROPERTY_XPC_SINGLETON (1 << 5) /* A singleton XPC domain. */

void bootstrap_init(void);

kern_return_t bootstrap_register2(mach_port_t bp, name_t service_name, mach_port_t sp, uint64_t flags);

kern_return_t bootstrap_look_up2(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, uint64_t flags);

kern_return_t bootstrap_check_in2(mach_port_t bp, const name_t service_name, mach_port_t *sp, uint64_t flags);

kern_return_t bootstrap_look_up_per_user(mach_port_t bp, const name_t service_name, uid_t target_user, mach_port_t *sp);

kern_return_t bootstrap_lookup_children(mach_port_t bp, mach_port_array_t *children, name_array_t *names, bootstrap_property_array_t *properties, mach_msg_type_number_t *n_children);

kern_return_t bootstrap_look_up3(mach_port_t bp, const name_t service_name, mach_port_t *sp, pid_t target_pid, const uuid_t instance_id, uint64_t flags);

kern_return_t bootstrap_check_in3(mach_port_t bp, const name_t service_name, mach_port_t *sp, uuid_t instance_id, uint64_t flags);

kern_return_t bootstrap_get_root(mach_port_t bp, mach_port_t *root);

#pragma GCC visibility pop

__END_DECLS

#endif /* __BOOTSTRAP_PRIVATE_H__ */
Loading

0 comments on commit 6ad404f

Please sign in to comment.