How to communicate between applications in iOS? - ios

Before we can use CFMessagePort, but now it's invalid for iOS7 and above, is there any replaced methods? I tried CFMessagePort when hooking the constructor of UIApplication in the jailbreak environment, but in most of the apps, it can't CFMessagePortCreateLocal successfully, it just return NULL.Am I wrong somewhere?
static void setupUIApplicationMessagePort()
{
NSString *identifier = #"com.foo.foo.UIApplication";
CFMessagePortRef local = CFMessagePortCreateLocal(NULL, (__bridge CFStringRef)identifier, callBackForUIApplication, NULL, NULL);
if (local) {
NSLog(#"local OK: %#", local);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(NULL, local, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
rocketbootstrap_cfmessageportexposelocal(local);
} else {
NSLog(#"local is NULL"); // in most of the apps it returns NULL
}
}
%ctor {
if(%c(UIApplication)) {
setupUIApplicationMessagePort();
}
}

try CFNotificationCenter using CFNotificationCenterGetDarwinNotifyCenter
#include <CoreFoundation/CFNotificationCenter.h>
/* This function will be called whatever a notification posted with the specified name */
void NotificationCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
}
void addObserver(){
CFStringRef name = CFSTR("NotificationName");
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),&NotificationCallback,name,NULL,CFNotificationSuspensionBehaviorDeliverImmediately);
}
This will listen to notifications named NotificationName
To post a notification
void postNotification(){
CFStringRef name = CFSTR("NotificationName");
/* You have to create the userInfo dictionary and add all the keys to it */
CFDictionaryRef userInfo;
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), name, NULL, userInfo, true);
}

Related

How to hook Apple's `os_log_with_type` method in Objective-C

I want to hook "React Native" RCTLog logs method _RCTLogJavaScriptInternal , The source codes is:
void _RCTLogJavaScriptInternal(RCTLogLevel level, NSString *message)
{
RCTLogFunction logFunction = RCTGetLocalLogFunction();
BOOL log = RCT_DEBUG || (logFunction != nil);
if (log && level >= RCTGetLogThreshold()) {
if (logFunction) {
logFunction(level, RCTLogSourceJavaScript, nil, nil, message);
}
}
}
RCTLogFunction RCTDefaultLogFunction =
^(RCTLogLevel level,
RCTLogSource source,
__unused NSString *fileName,
__unused NSNumber *lineNumber,
NSString *message) {
os_log_with_type(RCTLogForLogSource(source), RCTLogTypeForLogLevel(level), "%{public}s", message.UTF8String);
};
So if I just hook Apple's os_log_with_type, I will get the RCTLog logs.
This is my codes, but not working. Please help me. Thanks!!!!
#import <os/log.h>
#import "fishhook.h"
static void (*original_oslog)((os_log_t log, os_log_type_t type, const char *format, ...));
void hook_oslog(os_log_t log, os_log_type_t type, const char *format, ...) {
NSLog(#"hook success!");
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct rebinding oslog_rebinding = { "os_log_with_type", hook_oslog, (void *)&original_oslog };
rebind_symbols((struct rebinding[1]){oslog_rebinding}, 1);
});
}
Final, I found solution. Not need to hook, Related API have been provided by React Native already.
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
NSLog(#"%#", message);
});

IOS development how to solve the capture signal handler by covering problems

I want to make both the existing singal handler in the project and my own singal handler co-exist so that both can properly capture singal.
typedef void (*signalHandler)(int signo, siginfo_t *info, void *context);
static signalHandler previousSignalHandler = NULL;
void signalExceptionHandler(int signal, siginfo_t* info, void* context)
{
NSMutableString *mstr = [[NSMutableString alloc] init];
[mstr appendString:#"Stack:\n"];
void* callstack[128];
int i, frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
for (i = 0; i <frames; ++i) {
[mstr appendFormat:#"%s\n", strs[i]];
}
BYLOGI(#"%#",mstr);
[BYCrashCacheHelper saveAppCrashDataWithCrashInfo:mstr];
if (previousSignalHandler) {
previousSignalHandler(signal, info, context);
}
}
void signalRegister(int signal)
{
struct sigaction action;
action.sa_sigaction = signalExceptionHandler;
action.sa_flags = SA_NODEFER | SA_SIGINFO;
sigemptyset(&action.sa_mask);
sigaction(signal, &action, 0);
}
void judgePreviousSignalHandlerAndSignalRegister(int signal)
{
struct sigaction old_action;
sigaction(signal, NULL, &old_action);
if (old_action.sa_flags & SA_SIGINFO) {
previousSignalHandler = old_action.sa_sigaction;
}
signalRegister(signal);
}
void installSignalHandler(void)
{
judgePreviousSignalHandlerAndSignalRegister(SIGHUP);
judgePreviousSignalHandlerAndSignalRegister(SIGINT);
judgePreviousSignalHandlerAndSignalRegister(SIGQUIT);
judgePreviousSignalHandlerAndSignalRegister(SIGABRT);
judgePreviousSignalHandlerAndSignalRegister(SIGILL);
judgePreviousSignalHandlerAndSignalRegister(SIGSEGV);
judgePreviousSignalHandlerAndSignalRegister(SIGFPE);
judgePreviousSignalHandlerAndSignalRegister(SIGBUS);
judgePreviousSignalHandlerAndSignalRegister(SIGPIPE);
}
I found the above method in some blogs, but after debugging, I found that it can not get to the previous handler.
Excuse me, how to get the previous handler correctly, and avoid the handler coverage problem?

How to know if the network state is WiFi hotspot on iOS

Now I can just recognize WiFi/2G/3G/4G, but when the state is WiFi hotspot, AFNetworkReachabilityManager or Reachability also recognize the state as WiFi. Please help me to achieve this requirement, thanks a lot.
I had found the right way:
- (void)startMonitorWifiChange {
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
NULL,
&onNotifyCallback,
CFSTR("com.apple.system.config.network_change"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
}
static void onNotifyCallback(CFNotificationCenterRef center,
void *observer,
CFStringRef name,
const void *object,
CFDictionaryRef userInfo) {
if (CFStringCompare(name, CFSTR("com.apple.system.config.network_change"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
//TODO when wifi changed
[[BaiduLocationManager sharedManager].baiduLocationManager requestNetworkState];
}
else {
NBLog(#"intercepted %#", name);
}
}
- (void)stopMonitorWifiChange {
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(),
NULL,
CFSTR("com.apple.system.config.network_change"),
NULL);
}

MobileInstallationInstall progress

I wanna install a ipa on a jailbreak i-device.I get this code bellow on google. Here is the code
#import "dlfcn.h"
typedef int (*MobileInstallationInstall)(NSString *path, NSDictionary *dict, void *na, NSString *path2_equal_path_maybe_no_use);
void *lib = dlopen("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation", RTLD_LOCAL);
if (lib)
{
MobileInstallationInstall pMobileInstallationInstall = (MobileInstallationInstall)dlsym(lib, "MobileInstallationInstall");
if (pMobileInstallationInstall)
{
int ret = pMobileInstallationInstall(path, [NSDictionary dictionaryWithObject:#"User" forKey:#"ApplicationType"], nil, path);
dlclose(lib);
return ret;
}
}
return -1;
But that's not enough.I wanna get the install progress.Just like download progress. Unfortunately,I get nothing on google.any ideas?
you have to specify a callback function on the third parameter of MobileInstallationInstall
void MobileInstallationCallback(CFDictionaryRef information){
NSLog(#"%#",information);
}
int ret = pMobileInstallationInstall(path, [NSDictionary dictionaryWithObject:#"User" forKey:#"ApplicationType"], & MobileInstallationCallback, path);
all the informations will be sent to MobileInstallationCallback via the parameter information

iOS CFSocket crash on empty UDP packet

I am using a CFSocket configured for UDP to send data through wifi. The problem is that when I receive an empty UDP packet, the wifi suddenly stops working. I cant receive or send wnything anymore after that. Does anyone know what seems to be the problem? Here is my configuration and callback code:
void socketCallback(CFSocketRef cfSocket, CFSocketCallBackType type, CFDataRef address, const void *data, void *userInfo)
{
NSData * inputData = (__bridge NSData*)data;
NSUInteger inputDataCapacity = inputData.length * 2;
if(inputDataCapacity > minimalFrameSize*2){
//DO STH
}
}
-(void) initNetworkCommunication
{
CFSocketContext socketContext = {0, (__bridge void *)(self), NULL, NULL, NULL};
_cfSocket = CFSocketCreate(kCFAllocatorDefault, AF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketAcceptCallBack | kCFSocketDataCallBack, (CFSocketCallBack)socketCallback, &socketContext);
if ( _cfSocket == NULL) {
// NSLog(#"CfSocketCreate failed");
}
else {
if( _cfSocket ) {
_addrData = [Utils createIpAddressDataRef:COMM_INT_LISTENER_ADDR];
int flag = 1;
CFSocketNativeHandle socket_handle = (CFSocketNativeHandle)CFSocketGetNative(_cfSocket);
setsockopt(socket_handle, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));
//set address of the socket to listen to
CFSocketSetAddress (_cfSocket, _addrData);
_cfSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _cfSocket, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), _cfSource, kCFRunLoopDefaultMode);
CFRelease(_cfSource);
CFRelease(_cfSocket);
}
}
}
And sometimes after the wifi "crash" happens, I get an "EXC_BAD_ACCESS" when using CFSocketSendData.

Resources