Try to not use private entitlements
This commit is contained in:
@@ -8,9 +8,14 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// See note in hooking.m about why this was a bad idea
|
||||
#define HOOK_IMAGENT 0
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MBIMBridge : NSObject
|
||||
@property (nonatomic, assign) const char *dylibPath;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#import "MBIMBridge.h"
|
||||
#import "MBIMBridgeOperation.h"
|
||||
#import "hooking.h"
|
||||
|
||||
#import <GCDWebServers/GCDWebServers.h>
|
||||
|
||||
@@ -55,14 +56,32 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_terminate
|
||||
{
|
||||
// *shrug*
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Connection
|
||||
|
||||
- (void)connect
|
||||
{
|
||||
#if HOOK_IMAGENT
|
||||
char *errorString = nil;
|
||||
BOOL hooked = HookIMAgent(self.dylibPath, &errorString);
|
||||
if (!hooked) {
|
||||
NSString *errorNSString = [NSString stringWithUTF8String:errorString];
|
||||
NSLog(@"Error hooking imagent: %@", errorNSString);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (![sDaemonController hasListenerForID: MBIMBridgeToken]) {
|
||||
if (![sDaemonController addListenerID:MBIMBridgeToken capabilities:(kFZListenerCapFileTransfers | kFZListenerCapManageStatus | kFZListenerCapChats | kFZListenerCapMessageHistory | kFZListenerCapIDQueries | kFZListenerCapSendMessages)]) {
|
||||
NSLog(@"Failed to connect to imagent");
|
||||
|
||||
[self _terminate];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,6 +177,7 @@ static NSString *const MBIMBridgeToken = @"net.buzzert.kordophone";
|
||||
NSLog(@"iMessage account connected: %@", iMessageAccount);
|
||||
} else {
|
||||
NSLog(@"imagent returned no accounts (not entitled?)");
|
||||
[self _terminate];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
12
kordophone/Hooking/hooking.h
Normal file
12
kordophone/Hooking/hooking.h
Normal file
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// hooking.h
|
||||
// MessagesBridge
|
||||
//
|
||||
// Created by James Magahern on 11/13/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Returns success and a populated errorString on error.
|
||||
BOOL HookIMAgent(const char *hookDylibPath, char **errorString);
|
||||
75
kordophone/Hooking/hooking.m
Normal file
75
kordophone/Hooking/hooking.m
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// hooking.c
|
||||
// kordophoned
|
||||
//
|
||||
// Created by James Magahern on 11/13/18.
|
||||
// Copyright © 2018 James Magahern. All rights reserved.
|
||||
//
|
||||
|
||||
#include "hooking.h"
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
BOOL HookIMAgent(const char *relativeDylibPath, char **errorString)
|
||||
{
|
||||
NSLog(@"Hooking imagent");
|
||||
|
||||
const char *hookDylibPath = realpath(relativeDylibPath, NULL);
|
||||
|
||||
// See if file is there.
|
||||
int succ = access(hookDylibPath, R_OK);
|
||||
if (succ != 0) {
|
||||
*errorString = "Unable to access hook dylib. Does file exist?";
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Make sure we can load the dylib (filters out codesigning issues)
|
||||
void *handle = dlopen(hookDylibPath, RTLD_NOW);
|
||||
if (!handle) {
|
||||
*errorString = dlerror();
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*********
|
||||
***********
|
||||
PROBABLY DON'T DO THIS
|
||||
|
||||
If other processes start and load agentHook, then they will crash because dyld tries to
|
||||
interpose a function that doesn't exist.
|
||||
|
||||
A better way (maybe put this in a script or something):
|
||||
( But launchctl debug needs to run as root :( )
|
||||
|
||||
$ launchctl debug gui/501/com.apple.imagent --environment DYLD_INSERT_LIBRARIES=(path to libagentHook.dylib)
|
||||
|
||||
$ launchctl kill SIGKILL gui/501/com.apple.imagent
|
||||
|
||||
// then let it restart...
|
||||
|
||||
**/
|
||||
|
||||
// Set launchd DYLD_INSERT_LIBRARIES environment variable
|
||||
const char *systemCommandFormatString = "/bin/launchctl setenv DYLD_INSERT_LIBRARIES %s";
|
||||
size_t bufferSize = strlen(systemCommandFormatString) + strlen(hookDylibPath) + 2;
|
||||
char *systemCommand = (char *)malloc(sizeof(char) * bufferSize);
|
||||
|
||||
sprintf(systemCommand, "/bin/launchctl setenv DYLD_INSERT_LIBRARIES %s", hookDylibPath);
|
||||
int setEnvSucc = system(systemCommand);
|
||||
if (setEnvSucc != 0) {
|
||||
*errorString = "Unable to set launchd environment variable.";
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSLog(@"Successfully setup environment variables");
|
||||
|
||||
// Kill imagent so the new one has the loaded bundle
|
||||
NSLog(@"Killing imagent...");
|
||||
int killAgentSuccess = system("killall imagent");
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
system("/bin/launchctl unsetenv DYLD_INSERT_LIBRARIES");
|
||||
});
|
||||
|
||||
return (killAgentSuccess == 0);
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.private.corespotlight.search.internal</key>
|
||||
<true/>
|
||||
<key>com.apple.private.corespotlight.internal</key>
|
||||
<true/>
|
||||
<key>com.apple.CommCenter.fine-grained</key>
|
||||
<array>
|
||||
<string>spi</string>
|
||||
</array>
|
||||
<key>com.apple.accounts.inactive.fullaccess</key>
|
||||
<true/>
|
||||
<key>com.apple.imagent</key>
|
||||
<true/>
|
||||
<key>com.apple.private.accounts.allaccounts</key>
|
||||
<true/>
|
||||
<key>com.apple.private.aps-connection-initiate</key>
|
||||
<array>
|
||||
<string>com.apple.ess</string>
|
||||
<string>com.apple.madrid</string>
|
||||
</array>
|
||||
<key>com.apple.private.communicationsfilter</key>
|
||||
<true/>
|
||||
<key>com.apple.private.ids.idquery-cache</key>
|
||||
<true/>
|
||||
<key>com.apple.private.ids.remoteurlconnection</key>
|
||||
<true/>
|
||||
<key>com.apple.private.imcore.imdpersistence.database-access</key>
|
||||
<true/>
|
||||
<key>com.apple.private.tcc.allow</key>
|
||||
<array>
|
||||
<string>kTCCServiceAddressBook</string>
|
||||
</array>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>appleaccount</string>
|
||||
<string>InternetAccounts</string>
|
||||
<string>IMCore</string>
|
||||
<string>ichat</string>
|
||||
<string>apple</string>
|
||||
</array>
|
||||
<key>com.apple.logd.admin</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -13,6 +13,16 @@
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
MBIMBridge *bridge = [MBIMBridge sharedInstance];
|
||||
|
||||
#if HOOK_IMAGENT
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: kordophoned agentHook.dylib\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bridge.dylibPath = argv[1];
|
||||
#endif
|
||||
|
||||
[bridge connect];
|
||||
|
||||
BOOL running = YES;
|
||||
|
||||
Reference in New Issue
Block a user