Get currently foreground running app (third party) bundle Identifier - ios

How to get application name running in foreground? it was working in iOS 7 using SpringBoard but in iOS 8 I don't get the result. Any help is appreciated. I don't need to submit my app on apple store so if any patch or script also available then please let me know.
Code is working fine on below iOS 8.0
- (NSMutableString*) getActiveApps
{
mach_port_t *port;
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(lib, "SBSSpringBoardServerPort");
port = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(lib);
//mach_port_t * port = [self getSpringBoardPort];
// open springboard lib
//void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
// retrieve function SBFrontmostApplicationDisplayIdentifier
void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) =
dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");
// reserve memory for name
char appId[256];
memset(appId, 0, sizeof(appId));
// retrieve front app name
SBFrontmostApplicationDisplayIdentifier(port, appId);
// close dynlib
dlclose(lib);
return [[NSString stringWithFormat:#"%s", appId] retain];
}
Also I show new framework FrontBoard anyone know should it will help to out of this problem?

There's no way to do that anymore in iOS 8 since a vulnerability was discovered. A background app could attack though the frontmost app. More details here: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4361

Related

Can I use Unix socket for local communication between two iOS applications

Background: I have two iOS applications that need to exchange data locally with each other. The ideal scenario is that app A calls app B into foreground using URL scheme, with app A in the background, the two apps could exchange data with each other multiple rounds. I can declare app A the ability to run in background(I have valid reason to do so) so background execution for A is not a problem. I don't want to continue using URL scheme for the data exchange part between two apps because using URL scheme will open the other app and that means these two apps will be opened multiple times if there is multiple rounds of data exchange.
Also please note that these two iOS applications do not belong to the same developer so anything that relies on app group to share data will not work in this case...
Currently I have found a solution using a Unix Internet Domain Socket that binds onto the local loopback interface. It is technically working but I don't know if Apple permits this or not? Is there any better way to do this?
This is the code for the unix socket:
For the server app(app A):
BOOL _listenForConnections = false;
int listenfd = 0;
struct sockaddr_in serv_addr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(8008);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
_listenForConnections = true;
listen(listenfd, 10);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(#"Waiting for connections...");
while (_listenForConnections)
{
__block int connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
NSLog(#"Connection accepted");
char buffer[4096];
bzero(buffer, 4096);
NSString *message = #"";
bool continueReading = true;
do{
recv(connfd , buffer , 4096 , 0);
continueReading = false;
NSLog(#"%#", [NSString stringWithFormat: #"%#", [NSString stringWithFormat: #"Received message from client: %#%s", message, buffer]]);
}while (continueReading);
char* answer = "Hello World";
write(connfd, answer, strlen(answer));
NSLog(#"%#", [NSString stringWithFormat: #"Sent response to client"]);
}
NSLog(#"Now stop listening for connections");
close(listenfd);
});

Are there new device identifiers in iOS 10?

Has anyone found a new way to uniquely identify a device in iOS 10? I haven't seen any documentation mentioning changes in that area and I wanted to ask before I surrendered to identifier for vendor.
If you're submitting to the store, the only real identifier you have left is the Advertising Identifier for the AdSupport framework.
If you want to go down the rabbit hole a little further and potentially go into some unsafe API territory, you could hook into IOKit and try to get the battery identifier on the device. This is taken from Anthony Agatiello gist of UIDevice extensions:
- (NSString *)batteryID {
void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY);
NSParameterAssert(IOKit);
mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
NSParameterAssert(kIOMasterPortDefault);
CFMutableDictionaryRef (*IOServiceNameMatching)(const char *name) = dlsym(IOKit, "IOServiceNameMatching");
NSParameterAssert(IOServiceNameMatching);
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
NSParameterAssert(IOServiceGetMatchingService);
kern_return_t (*IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, UInt32 options) = dlsym(IOKit, "IORegistryEntryCreateCFProperties");
NSParameterAssert(IORegistryEntryCreateCFProperties);
kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
NSParameterAssert(IOObjectRelease);
CFMutableDictionaryRef properties = NULL;
mach_port_t service = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceNameMatching("charger"));
IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0);
IOObjectRelease(service);
service = 0;
NSDictionary *dictionary = (__bridge NSDictionary *)properties;
NSData *batteryIDData = [dictionary objectForKey:#"battery-id"];
CFRelease(properties);
properties = NULL;
dlclose(IOKit);
return [NSString stringWithUTF8String:[batteryIDData bytes]];
}
This still works on iOS 10.

iOS app crash while send msg by socket

I use this method for send msg to server
ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send);
This is standard Lib from Apple (socket.h and socket.m )
NSString *msg = #"Message want to send";
// socketFileDescriptor is int
NSData *wdata = [msg dataUsingEncoding:NSUTF8StringEncoding];
ssize_t n;
const UInt8 *buf = (const UInt8 *)[wdata bytes];
n = send(socketFileDescriptor, buf,[wdata length],0); // I really sure,it's crash at this statement on device iPad Air, iPad Air2 only
BUT on debug mode isn't not crash!
App will crash when I archive project to IPA (Ad-Hoc Mode)
I have no ideal for this case please help me.
This is more information
I use this method for connect to server
I have already assign value for self.host and self.port variable.
(I sure it can be connect normally in debug mode)
http://pastebin.com/raw.php?i=KFKJsJHZ
and I use this method for send message to server
http://pastebin.com/raw.php?i=Z7Js2JT8
2 method in same class BSDSocket
Please tell me If you want more information.
Thank you

IPConfiguration apple80211Open() crashes on iOS8

I am trying to read RSSI of iPhone WIFI connection to AP.
Using Xcode 6.1.1 with iPhone6+ ios 8.1.3
Code below crashes at apple80211Open() and gets EXC_BAD_ACCESS (code=1, address= 0) on iOS 8. (code works on iOS 7.1)
This is for app that is NOT for Apple Store -- for adhoc distribution only.
=================================================================
void *libHandle;
void *airportHandle;
int (*apple80211Open)(void *);
int (*apple80211Bind)(void *, NSString *);
int (*apple80211Close)(void *);
int (*apple80211GetInfoCopy)(void *, CFDictionaryRef *);
NSMutableDictionary *infoDict = [NSMutableDictionary new];
NSDictionary * tempDictionary;
libHandle = dlopen("/System/Library/SystemConfiguration/IPConfiguration.bundle/IPConfiguration", RTLD_LAZY);
char *dlerror_error;
if (libHandle == NULL && (dlerror_error = dlerror()) != NULL) {
NSLog(#"%s", dlerror_error);
}
apple80211Open = dlsym(libHandle, "Apple80211Open");
apple80211Bind = dlsym(libHandle, "Apple80211BindToInterface");
apple80211Close = dlsym(libHandle, "Apple80211Close");
apple80211GetInfoCopy = dlsym(libHandle, "Apple80211GetInfoCopy");
apple80211Open(&airportHandle);
apple80211Bind(airportHandle, #"en0");
CFDictionaryRef info = NULL;
apple80211GetInfoCopy(airportHandle, &info);
tempDictionary = (__bridge NSDictionary *)info;
apple80211Close(airportHandle);
[infoDict setObject:(tempDictionary[#"RSSI"])[#"RSSI_CTL_AGR"] ? (tempDictionary[#"RSSI"])[#"RSSI_CTL_AGR"] : #"0" forKey:#"RSSI"];
[infoDict setObject:tempDictionary[#"BSSID"] ? tempDictionary[#"BSSID"] : #"null" forKey:#"BSSID"];
[infoDict setObject:tempDictionary[#"SSID_STR"] ? tempDictionary[#"SSID_STR"] : #"null" forKey:#"SSID"];
[infoDict setObject:tempDictionary[#"RATE"] ? tempDictionary[#"RATE"] : #"0" forKey:#"SPEED"];
That's because Apple removed the 80211 framework from within IPConfiguration. The symbols can't be found, dlsym returns NULL, and - a crash (you should always check return values, you know).
To begin with, this was a private framework. In new versions of iOS (8+), it's deprecated in favor of MobileWifi, and the use of entitlements (and XPC) so as to have /usr/libexec/wifid to all the work.
There's more detail on this in this article: http://newosxbook.com/articles/11208ellpA.html
The Apple80211 API was removed from IPConfiguration at some point e.g. iOS 11 & 12, but came back in iOS 13 and as of today the methods are all still there and working in iOS 13.4.1. What I expect is the reason you were unable to get it working is likely since iOS 8 you need the com.apple.wlan.authentication entitlement as mentioned here.
There is currently a sneaky way to use this entitlement in apps (for your own use), but it will stop working in iOS 13.5.

Programmatically send iMessage using private frameworks

Does anyone know if it's possible to directly send an iMessage using a private framework?
I tried using CTMessageCenter from CoreTelephony but it'll send an SMS even though my phone can send iMessages.
I haven't tested this, but look at the code posted here. If you look at httpResponseForMethod:URI:, you see where he/she sends a message (appears to be hardcode to support iOS 5 or iOS 4):
CKSMSService *smsService = [CKSMSService sharedSMSService];
//id ct = CTTelephonyCenterGetDefault();
CKConversationList *conversationList = nil;
NSString *value =[[UIDevice currentDevice] systemVersion];
if([value hasPrefix:#"5"])
{
//CKMadridService *madridService = [CKMadridService sharedMadridService];
//NSString *foo = [madridService _temporaryFileURLforGUID:#"A5F70DCD-F145-4D02-B308-B7EA6C248BB2"];
NSLog(#"Sending SMS");
conversationList = [CKConversationList sharedConversationList];
CKSMSEntity *ckEntity = [smsService copyEntityForAddressString:Phone];
CKConversation *conversation = [conversationList conversationForRecipients:[NSArray arrayWithObject:ckEntity] create:TRUE service:smsService];
NSString *groupID = [conversation groupID];
CKSMSMessage *ckMsg = [smsService _newSMSMessageWithText:msg forConversation:conversation];
[smsService sendMessage:ckMsg];
[ckMsg release];
} else {
//4.0
id ct = CTTelephonyCenterGetDefault();
void* address = CKSMSAddressCreateWithString(pid);
int group = [grp intValue];
if (group <= 0) {
group = CKSMSRecordCreateGroupWithMembers([NSArray arrayWithObject:address]);
}
void *msg_to_send = _CKSMSRecordCreateWithGroupAndAssociation(NULL, address, msg, group, 0);
CKSMSRecordSend(ct, msg_to_send);
}
The code uses normal SMS, but you can see the following commented out code:
//CKMadridService *madridService = [CKMadridService sharedMadridService];
The "Madrid" service is probably what can send iMessages. See the private header here.
Both SMS and iMessage private APIs are in the ChatKit.framework.
Through a non jailbreak iPhone there is absolutely no access to the iMessage CoreTelephony API

Resources