Inter-processCommunicationByRrocketbootstrap

前言

These are some of the existing methods to implement IPC on iOS:

  • Community Libraries to Help
1、RocketBootstrap: Service registration and lookup system for iOS 
2、OBJCIPC :High-level API for hosting services inside apps (by Alan Yip/a1anyip)
3、LightMessaging: Header-only library for simple IPC
  • 本文重点讲解 RocketBootstrap的两种包装方式:CFMessagePort、CPDistributedMessagingCenter
    Easy to use wrappers for CFMessagePort and CPDistributedMessagingCenter(todo: XPC) 
    

UIPasteboard\NSPasteboard

  • OpenUDID的使用例子
    #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
    #import <UIKit/UIPasteboard.h>
    #import <UIKit/UIKit.h>
    #else
    #import <AppKit/NSPasteboard.h>
    #endif
    #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
          UIPasteboard* slotPB = [UIPasteboard pasteboardWithName:slotPBid create:NO];
    #else
          NSPasteboard* slotPB = [NSPasteboard pasteboardWithName:slotPBid];
    #endif
    
/**
 应用级别的,数据在属于自己的应用内部共享;
 (默认情况下是不会把数据写进沙盒的,也就是说(复制、剪切)粘贴内容会因为应用的退出而销毁掉,我们可以设置相关属性 persistent值为 YES让其进行数据的持久化存储起来)
 
 Ps:例如 persistent 是否进行数据持久化 还有 changeCount 改变次数(剪切板)系统重启方才重新计数
 
 */
- (NSObject *)model{
    
    if (_model == nil) {
        
        NSString *contentUserID =@"";
        UIPasteboard *pasteboardUserID = [UIPasteboard pasteboardWithName:KNpasteboardWithNameKeyUserID create:NO];
        
        if (pasteboardUserID){
            contentUserID = pasteboardUserID.string;////获取内容
        }
        
        _model = [[NSObject alloc]init];
//        _model.UserId =contentUserID;
        
        
    }
    return _model;
}

LightMessaging

  • feature
 1、Mid-level API,
 2、Message-oriented 
 3、Zero copy, for certain message types
 4、No additional cost over standard mach calls 
 5、Easy integration with RocketBootstrap 
 6、No package dependencies

  • using
 1、Start services with LMStartService

 2、Send messages with LMConnectionSendTwoWay (and friends)

 3、Send replies with LMSendReply (and friends)

 4、Bring your own security checks still :Community developers, your input on API please!


librocketbootstrap

  • feature
    1、Uses iOS7’s security model: Privileged processes can register, any process can look up 
    2、Works with existing mach-based IPC mechanisms
    3、Similar to Apple’s bootstrap APIs: bootstrap_look_up becomes rocketbootstrap_look_up
    bootstrap_register becomes rocketbootstrap_register
    

4、Easy to use wrappers for CFMessagePort and CPDistributedMessagingCenter(todo: XPC) 
5、Bring your own security model by using audit_token_to_au32 to know who’s calling
6、Requires package dependency, commonly installed on users’ devices
  • 本文重点讲解 RocketBootstrap的两种包装方式:CFMessagePort、CPDistributedMessagingCenter
    Easy to use wrappers for CFMessagePort and CPDistributedMessagingCenter(todo: XPC) 
    
//registerMsgCenter 基本可以解决双向通信;例子:避免重启其他进程从sb获取源地址信息的变更。 守护进行都可以注册成为服务
+ (kern_return_t)rockettest_messageport_server
{
    static CFMessagePortRef messagePort;//
    if (messagePort)
        return 0;
    messagePort = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR("rockettest_messageport"), messagePortCallback, NULL, NULL);//CFSTR("rockettest_messageport")即server key,
    CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, messagePort, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, (CFStringRef)UITrackingRunLoopMode);
    return rocketbootstrap_cfmessageportexposelocal(messagePort);
}
typedef CFDataRef (*CFMessagePortCallBack)(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info);
//回调的定义
static CFDataRef messagePortCallback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info)
{
    NSLog(@"rockettest_messageport_server: received %@", data);
    return CFDataCreate(kCFAllocatorDefault, (const UInt8 *)"bootstrap", 9);
}
Private API, does change between iOS versions  : 目前发现这种方式只能在SpringBoard   注册为服务端,处理消息,;进程间其实是单向通信;  http://iphonedevwiki.net/index.php/RocketBootstrap#LightMessaging_example
#TweakDemo.xm  SpringBoard  接受消息
#import "rocketbootstrap.h"

#define kXPCCenterNameKey  @"kXPCCenterNameKey_83641"

%hook SpringBoard
- (void)applicationDidFinishLaunching:(id)application {
   %orig;
   CPDistributedMessagingCenter *c = [%c(CPDistributedMessagingCenter) centerNamed:kXPCCenterNameKey];
   rocketbootstrap_distributedmessagingcenter_apply(c);
   [c runServerOnCurrentThread];
   [c registerForMessageName:@"myMessageName" target:self selector:@selector(handleMessage:withUserInfo:)];
   NSLog(@"注册监听 start");
}

%new
- (void)handleMessage:(NSString *)name withUserInfo:(NSDictionary *)userInfo {
   NSLog(@"handleMessage withUserInfo:%@",userInfo);
   //TODO:something
}

%end
//在需要发送的地方(沙盒 app ),如此这般的写: 
%hook SomeClass

-(void)someMethod{
   %orig;
    NSMutableDictionary *userInfo = [@{} mutableCopy];
    [userInfo setObject:@"123" forKey:@"arg001"];
    [userInfo setObject:@"456" forKey:@"arg002"];
    NSLog(@"发送: %@=%@",kXPCCenterNameKey,userInfo);
    CPDistributedMessagingCenter *c = [%c(CPDistributedMessagingCenter) centerNamed:kXPCCenterNameKey];
    rocketbootstrap_distributedmessagingcenter_apply(c);
    [c sendMessageName:@"myMessageName" userInfo:userInfo];
}
%end
  • 获取librocketbootstrap :Install this from Cydia 直接搜索rocketbootstrap安装即可
iPhone:/var/log root# ls -l /usr/lib/librocketbootstrap.dylib
-rwxr-xr-x 1 root wheel 221776 Feb  6  2017 /usr/lib/librocketbootstrap.dylib*

/Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist
/usr/libexec/rocketd
launchctl load  /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist
launchctl unload /Library/LaunchDaemons/com.rpetrich.rocketbootstrapd.plist

IPC

allows processes to send each other messages and data

libobjcipc

  • feature
    • High level API provides service lookup and IPC, easy to use
    • Background-launches and fakes app lifecycle for you 
    • Message-oriented
    • Mostly asynchronous
    • “Open” security model 
    • Requires separate package dependency, but very small
    • Simple Objective-C APIs: 
    Register using --registerIncomingMessageFromAppHandlerForMessageName:handler:
    Send using -- sendMessageToAppWithIdentifier:messageName:dictionary:replyHandler:  
    • Similar patterns for App to SpringBoard
    

XPC

XPC can be accessed through either the libxpc C API, or the NSXPCConnection Objective-C API.

  • feature
    1、High level API, easy to use :One of Apple’s many wrappers for Mach messages;
    2、Message-oriented
    3、Public API on OS X only
    4、Asynchronous always, no synchronous versions
    5、Service lookup is restricted on iOS 7+ 
    
  • 参考文章
  • Inter-Process Communication

Tweaks on a multi-process iOS

  • Inter-Process Communication
    1、Mechanisms provided by the kernel to facilitate coordinated sharing of data and commands between processes
    2、Used heavily in recent versions of iOS and OS X to implement system frameworks and APIs
    
  • Standard Techniques
    1、Save to temp files:High level APIs, easy to use
    2、Unix Domain Sockets: Low level API  ,Stream oriented, requires basic parsing to reconstruct
    messages
    
  • Other standard techniques
    • Shared Memory
    • Signals
    • Named pipes
    • Network sockets 
    
  • Apple/iOS-specific Techniques
    1、Darwin Notifications:No data, only a simple “go” message,Any process can post or observe ,Always asynchronous
    2、Mach Ports :seriously low level 
    3、CPDistributedNotificationCenter: Private API, does change between iOS versions
    4、CFMessagePort: Public API,Only supports synchronous use ,Service lookup is restricted on iOS 6+
    5、XPC : High level API, easy to use �,One of Apple’s many wrappers for Mach messages ;
    
  • Creative Techniques
    1、Relax existing service permissions
    2、Repurpose existing iOS services’ IPC channels:Service internals are frequently rewritten in new iOS versions
    3、Delegate to someone else
    
  • Libraries that use IPC under the hood
    1、http://iphonedevwiki.net/index.php/AppList
    2、http://iphonedevwiki.net/index.php/Flipswitch
    3、http://iphonedevwiki.net/index.php/Libactivator
    4、https://github.com/r-plus/libcanopenurl
    
  • Community Libraries to Help
    1、RocketBootstrap: Service registration and lookup system for iOS
    
  • Be aware of potential deadlocks
    1、 SpringBoard will block on backboardd—don’t call from backboardd to SpringBoard! 
    2、Communicate with these processes using one-way IPC, asynchronous IPC, or two-way IPC with timeouts 
    3、Avoid the pitfall of accidentally sending blocking API calls to one’s own process
    4、SpringBoard is usually a good choice for coordinator as it often has much work to do anyway
    5、Batch all of the operations for a single user action into one IPC call, if possible 
    6、Filter to only the data required before sending 
    

Q&A

  • 使用yalu102 激活了之后,无法连接ssh
#/usr/local/bin/dropbear 此次越狱工具默认安装了 SSH。采用了 Dropbear 取代 Openssh。
因此在部署安装使用yalu102的时候记得修改dropbear.plist的信息:ProgramArguments的127.0.0.1:22 直接改为22。
如果部署完成,直接修改沙盒的信息的话,记得重启设备。

# 获取直接修改对应的配置信息
iPhone:~ root# ps -e |grep yalu*
 1174 ??         0:00.80 /var/containers/Bundle/Application/B831448D-BCD0-4F29-BDA6-9FC03903D30C/yalu102.app/yalu102

#plutil plist 内容
iPhone:/var/containers/Bundle/Application/B831448D-BCD0-4F29-BDA6-9FC03903D30C/yalu102.app root# plutil dropbear.plist
{
    KeepAlive = 1;
    Label = ShaiHulud;
    Program = "/usr/local/bin/dropbear";
    ProgramArguments =     (
        "/usr/local/bin/dropbear",
        "-F",
        "-R",
        "-p",
        22
    );
    RunAtLoad = 1;
}
  • dropbear 参数
 iPhone:/var/containers/Bundle/Application/B831448D-BCD0-4F29-BDA6-9FC03903D30C/yalu102.app root# ps -e |grep dropbear
  228 ??         0:00.05 /usr/local/bin/dropbear -F -R -p 22
  • 利用wget 安装scp( 解决:sh: scp: command not found)
#两台服务器都要安装scp才能传文件
#wget + 空格 + 要下载文件的url路径
# cydia里面安装wget
#  安装scp,默认安装在当前目录
wget mila432.com/scp
ldid -S scp
# chmod +x scp
chmod 777 scp
mv scp /usr/bin/scp
# 或者使用curl: curl -O mila432.com/scp ./scp

dyld: Library not loaded: /usr/lib/libssl.0.9.8.dylib 重新安装openssl

  • 浏览器下载scp
 find . -name "scp" 
 
devzkndeMacBook-Pro:deviceconsole-master devzkn$ /Users/devzkn/Library/Developer/Xcode/DerivedData/deviceconsole-gfjsthvevyxiqyahugfpmzjlseye/Build/Products/Debug/deviceconsole --help
Usage: /Users/devzkn/Library/Developer/Xcode/DerivedData/deviceconsole-gfjsthvevyxiqyahugfpmzjlseye/Build/Products/Debug/deviceconsole [options]
Options:
 -d			Include connect/disconnect messages in standard out
 -u <udid>		Show only logs from a specific device
 -p <process name>	Show only logs from a specific process

Control-C to disconnect
Mail bug reports and suggestions to <ryan.petrich@medialets.com>
  • deviceconsole 的改进版
    devzkndeMacBook-Pro:deviceconsole-master devzkn$ knlog -h
    knlog: invalid option -- h
    Usage: knlog [options]
    Options:
    -i | --case-insensitive     Make filters case-insensitive
    -f | --filter <string>      Filter include by single word occurrences (case-sensitive)
    -x | --exclude <string>     Filter exclude by single word occurrences (case-sensitive)
    -p | --process <string>     Filter by process name (case-sensitive)
    -u | --udid <udid>          Show only logs from a specific device
    -s | --simulator <version>  Show logs from iOS Simulator
       --debug                Include connect/disconnect messages in standard out
       --use-separators       Skip a line between each line
       --force-color          Force colored text
       --message-only          Display only level and message
    Control-C to disconnect
    devzkndeMacBook-Pro:.git devzkn$ knlog -i -f AppStore
    Jan 10 18:57:45 iPhone appstored(libsystem_network.dylib)[587] <Info>: nw_endpoint_resolver_start_next_child [6 su.itunes.apple.com:443 in_progress resolver (satisfied)] starting child endpoint 123.53.139.209:443
    Jan 10 18:57:45 iPhone appstored(libsystem_network.dylib)[587] <Info>: nw_endpoint_resolver_start_next_child [6 su.itunes.apple.com:443 in_progress resolver (satisfied)] starting next child endpoint in 250ms
    Jan 10 18:57:45 iPhone appstored(libsystem_network.dylib)[587] <Info>: nw_endpoint_handler_start [6.2 123.53.139.209:443 initial path (null)]
    Jan 10 18:57:45 iPhone appstored(libsystem_network.dylib)[587] <Info>: nw_connection_endpoint_report [6.2 123.53.139.209:443 initial path (null)] reported event path:start
    Jan 10 18:57:45 iPhone appstored(libsystem_network.dylib)[587] <Info>: nw_connection_endpoint_report [6.2 123.53.139.209:443 waiting path (satisfied)] reported event path:satisfied
    

*ldid

devzkndeMacBook-Pro:bin devzkn$ which ldid
/opt/iOSOpenDev/bin/ldid

See also

xpc资料

- (void)clearTrace
{
        // Kill all App Store Apps
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:@"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"])
        {
                NSDictionary *dictionary1 = [NSDictionary dictionaryWithContentsOfFile:@"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"];
                NSDictionary *dictionary2 = [dictionary1 objectForKey:@"User"];
                NSEnumerator *enumerator = [dictionary2 keyEnumerator];
                NSString *key;
                while ((key = [enumerator nextObject]))
                {
                        NSDictionary *dictionary3 = [dictionary2 objectForKey:key];
                        NSString *targetApp = [dictionary3 objectForKey:@"CFBundleExecutable"];
                        system([NSString stringWithFormat:@"killall -9 %@", targetApp] UTF8String]);
                }
        }

        // Kill Safari
        system("killall -9 MobileSafari");

        // Enumerate all App Store Apps' directories and delete /Documents, /Library, /tmp, /StoreKit
        NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:@"/var/mobile/Applications/"];
        NSString *file;
        while ((file = [dirEnum nextObject]))
                if ([file hasSuffix:@"/Documents"] || [file hasSuffix:@"/Library"] || [file hasSuffix:@"/tmp"] || [file hasSuffix:@"/StoreKit"])
                {
                        [fileManager removeItemAtPath:[NSString stringWithFormat:@"/var/mobile/Applications/%@", file] error:nil];
                        [fileManager createDirectoryAtPath:[NSString stringWithFormat:@"/var/mobile/Applications/%@", file] withIntermediateDirectories:NO attributes:[NSDictionary dictionaryWithObjectsAndKeys:@"mobile", NSFileOwnerAccountName, @"mobile", NSFileGroupOwnerAccountName, nil] error:nil];
                }

        // Delete cookies
        [fileManager removeItemAtPath:@"/var/mobile/Library/Cookies/Cookies.binarycookies" error:nil];
        [fileManager removeItemAtPath:@"/private/var/root/Library/Cookies/Cookies.binarycookies" error:nil];
        [fileManager removeItemAtPath:@"/var/mobile/Library/Safari/History.plist" error:nil];
        [fileManager removeItemAtPath:@"/var/mobile/Library/Safari/SuspendState.plist" error:nil];

        // Delete pasteboard contents and relaunch pasteboardd
        system("launchctl unload -w /System/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist");

        dirEnum = [fileManager enumeratorAtPath:@"/var/mobile/Library/Caches/com.apple.UIKit.pboard/"];
        while ((file = [dirEnum nextObject]))
                [fileManager removeItemAtPath:[NSString stringWithFormat:@"/var/mobile/Library/Caches/com.apple.UIKit.pboard/%@", file] error:nil];

        system("launchctl load -w /System/Library/LaunchDaemons/com.apple.UIKit.pasteboardd.plist");

        // Delete entries in keychain-2.db
        sqlite3 *database;
        int openResult = sqlite3_open("/var/Keychains/keychain-2.db", &database);
        if (openResult == SQLITE_OK)
        {
                int execResult = sqlite3_exec(database, "DELETE FROM genp WHERE agrp<>'apple'", NULL, NULL, NULL);
                if (execResult != SQLITE_OK) NSLog(@"iOSRE: Failed to exec DELETE FROM genp WHERE agrp<>'apple', error %d", execResult);

                execResult = sqlite3_exec(database, "DELETE FROM cert WHERE agrp<>'lockdown-identities'", NULL, NULL, NULL);
                if (execResult != SQLITE_OK) NSLog(@"iOSRE: Failed to exec DELETE FROM cert WHERE agrp<>'lockdown-identities', error %d", execResult);

                execResult = sqlite3_exec(database, "DELETE FROM keys WHERE agrp<>'lockdown-identities'", NULL, NULL, NULL);
                if (execResult != SQLITE_OK) NSLog(@"iOSRE: Failed to exec DELETE FROM keys WHERE agrp<>'lockdown-identities'', error %d", execResult);

                execResult = sqlite3_exec(database, "DELETE FROM inet", NULL, NULL, NULL);
                if (execResult != SQLITE_OK) NSLog(@"iOSRE: Failed to exec DELETE FROM inet, error %d", execResult);

                execResult = sqlite3_exec(database, "DELETE FROM sqlite_sequence", NULL, NULL, NULL);
                if (execResult != SQLITE_OK) NSLog(@"iOSRE: Failed to exec DELETE FROM sqlite_sequence, error %d", execResult);

                sqlite3_close(database);
        }
        else NSLog(@"iOSRE: Failed to open /var/Keychains/keychain-2.db, error %d", openResult);
}

转载请注明: > Inter-processCommunicationByRrocketbootstrap

在操作过程或者文章有问题的话欢迎在 原文 里提问或指正。

赞赏支持

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少
最近的文章

iOSOpenDevInstallFailed

前言 Com.apple.product-type.tool解决方法,通常Xcode9 和Xcode8 都会遇到这个问题,尤其是在开发 Command Line Tools的时候下载此文件夹 https://svn.webkit.org/repository/webkit/trunk/Tools/Scripts或者下载本帖附件解压然后运行 cd Scriptssudo ./configure-xcode-for-ios-developmentiOSOpenDevInstallFailed...…

iOSre继续阅读
更早的文章

AppSync

前言借助AppSync限制签名验证,,利用它可以安装未签名的ipa。安装未签名的ipa 添加源:http://apt.so/,并安装对应系统版本的AppSync 使用iTools 或者ipainstaller 进行ipa文件的安装 #在iPhone安装ipa installer Console之后利用命令行安装iPhone:~ root# ipainstaller ./*_v6.5.9.ipaAnalyzing 信_v6.5.9.ipa...Install...…

iOSre继续阅读
更多