Перехват CFNotificationCenter для всех уведомлений darwin — iOS

Я пишу хук, который регистрирует все уведомления Дарвина в системе. Я подключаюсь к функциям ниже:

CFNotificationCenterPostNotification
CFNotificationCenterPostNotificationWithOptions
NSNotificationCenter::postNotification
NSNotificationCenter::postNotificationName

Я вижу много журналов. Например, когда я разблокирую экран, он показывает мне SBDeviceLockStateChangedNotification.

Но я ожидаю таких событий, как "com.apple.springboard.lockcomplete" или других событий, таких как здесь

Не уверен, почему я не могу захватывать уведомления, подобные Дарвину. Любая помощь приветствуется. Вот код для обзора

#include <notify.h>
#include <substrate.h>
#include <sqlite3.h>
#include <string.h>
#import <CoreFoundation/CFNotificationCenter.h>
//#include "CPDistributedMessagingCenter.h"
#import <CoreFoundation/CoreFoundation.h>
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
//#import <SpringBoard/SpringBoard.h>


// init CFNotificationCenterPostNotification hook
void (*orig_CFNotificationCenterPostNotification) (
                                                   CFNotificationCenterRef center,
                                                   CFStringRef name,
                                                   const void *object,
                                                   CFDictionaryRef userInfo,
                                                   Boolean deliverImmediately
                                                   );

void replaced_CFNotificationCenterPostNotification (
                                                    CFNotificationCenterRef center,
                                                    CFStringRef name,
                                                    const void *object,
                                                    CFDictionaryRef userInfo,
                                                    Boolean deliverImmediately
                                                    ){
    NSLog(@"CFNotificationCenterPostNotification: %@", name );

    orig_CFNotificationCenterPostNotification(center,name,object,userInfo,deliverImmediately);

}

void (*orig_CFNotificationCenterPostNotificationWithOptions) (
                                                      CFNotificationCenterRef center,
                                                      CFStringRef name,
                                                      const void *object,
                                                      CFDictionaryRef userInfo,
                                                      CFOptionFlags options
                                                      );
void replaced_CFNotificationCenterPostNotificationWithOptions (
                                                      CFNotificationCenterRef center,
                                                      CFStringRef name,
                                                      const void *object,
                                                      CFDictionaryRef userInfo,
                                                      CFOptionFlags options
                                                      )
{
    NSLog(@"CFNotificationCenterPostNotificationWithOptions: %@", name );

    orig_CFNotificationCenterPostNotificationWithOptions(center,name,object,userInfo,options);

}

%hook SpringBoard

-(void)applicationDidFinishLaunching:(id)application {
    %orig;

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Welcome"
                                                    message:@"Welcome to my iPhone!"
                                                   delegate:nil
                                          cancelButtonTitle:@"Thanks"
                                          otherButtonTitles:nil];
    [alert show];
    //[alert release];
}
%end
%hook NSNotificationCenter
- (void)postNotification:(NSNotification *)notification{

        NSLog(@"NSNotificationCenterpostNotification: %@",[notification name]);

    %orig;
}
- (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo{

        NSLog(@"NSNotificationCenterpostNotificationName: %@",aName);

    %orig;
}

%end
__attribute__((constructor)) void notificationinit() {

%init;

    MSHookFunction(CFNotificationCenterPostNotification, replaced_CFNotificationCenterPostNotification, &orig_CFNotificationCenterPostNotification);

    MSHookFunction(CFNotificationCenterPostNotificationWithOptions, replaced_CFNotificationCenterPostNotificationWithOptions, &orig_CFNotificationCenterPostNotificationWithOptions);

}

person TorukMakto    schedule 17.07.2013    source источник


Ответы (1)


Итак, несколько мыслей:

  1. Во-первых, можете ли вы объяснить, почему вы хотите использовать метод swizzling или hooking для обнаружения этих уведомлений? Вы действительно пытаетесь перехватить уведомления, обработать их в своем программном обеспечении и помешать их доставке в остальную часть системы? Если это то, чего вы хотите, то я понимаю ваш подход. Если вы просто хотите получать эти уведомления, я бы порекомендовал обычный подход — просто зарегистрироваться на события Дарвина (на все или по имени). см. пример здесь.

  2. Это просто проблема с событием com.apple.springboard.lockcomplete? Потому что это событие не генерируется, когда вы разблокируете устройство. Оно публикуется только при блокировке. Чтобы обнаружить событие разблокировки, вы можете см. этот ответ.

  3. Если у вас по-прежнему возникают проблемы, возможно, это связано с тем, что события можно публиковать несколькими способами. Вы можете перехватывать CFNotificationCenterPostNotification() и CFNotificationCenterPostNotificationWithOptions(), но это не единственные способы публикации событий. Низкоуровневый notify_post() API также можно использовать. Я предполагаю, что CFNotificationCenterPostNotification() на самом деле будет использовать вызов notify_post() для публикации события. Таким образом, вполне возможно, что если вы пытаетесь обнаружить событие, особенно незадокументированное, iOS публикует событие напрямую с помощью notify_post(), что объясняет, почему вы его не видите.

Надеюсь это поможет.

person Nate    schedule 19.07.2013
comment
Ната - Большое спасибо за подробный ответ. 1) Я просто хочу получать каждое уведомление Дарвина. Однако пример, который вы упомянули, дает мне уведомления только тогда, когда мое приложение находится на переднем плане. (Или я прикалываюсь). 2) и 3) notify_post сделал свое дело. Теперь я могу подключиться к notify_post и перехватить каждое уведомление в системе. Ценим вашу помощь и время. - person TorukMakto; 19.07.2013
comment
Кстати, цель состояла не в том, чтобы остановить их, а в том, чтобы зарегистрировать их и создать базу данных всех возможных уведомлений, чтобы, когда возникнет потребность, мы могли просмотреть основной список и выяснить, как этого можно достичь... - person TorukMakto; 19.07.2013
comment
@Bugivore, я сейчас не на своем Mac, поэтому не могу бежать. Вы должны иметь возможность получать уведомления, пока ваше приложение находится в фоновом режиме. Однако вам может потребоваться выполнить некоторые действия, чтобы ваше приложение полностью активно работало в фоновом режиме. Для обычного UI-приложения iOS отключает довольно много функций в фоновом режиме. Вы можете обойти это, сделав ваше приложение демоном или используя недокументированные фоновые режимы в вашем Info.plist (continuous и unboundedTaskCompletion). Мне нужно идти спать сейчас, но я могу опубликовать больше об этом завтра. Или вы можете поискать в моих старых постах... - person Nate; 19.07.2013
comment
@Bugivore, если вы посмотрите мой старый ответ, он покажет вам, как изменить приложение, чтобы остаться в живых в фоновом режиме так долго, как вы хотите. Возможно, это может быть необходимо для продолжения доставки уведомлений вашему приложению после того, как оно перейдет в фоновый режим. Обратите внимание, что я также упоминаю Launch Daemons, которые похожи на неграфические фоновые службы, которые работают все время. В зависимости от того, что вы пытаетесь сделать, это также может быть хорошим решением. - person Nate; 22.07.2013