2

我有一个 SpringBoard 挂钩,可以监听分布式通知。我已经挂钩了在 SpringBoard 中收到的各种其他应用程序发布通知。

如果我将 userInfo 传递为 null,SpringBoard 会收到来自所有应用程序的通知。如果我将 CFDictionaryRef 作为 userInfo 传递,则 SpringBoard 仅接收来自 SpringBoard 和 SystemApps 的通知。但是,用户应用程序无法发送通知。(或者更确切地说,Springboard 没有收到)。

CFDictionaryRef 是无辜的,而不是罪魁祸首,因为当发送者和接收者是系统应用程序时,我能够通过它。

是否存在用户应用程序无法将 userInfo 对象发送到系统应用程序的限制?

编辑: 附上代码。我使用 iOSOpenDev 编译它。依靠 NSLog 来调试。 场景 1:如果您触摸 SpringBoard,您将看到 2 条日志,用于通知发送和接收通知。 场景 2:调用任何系统应用程序,如时钟等,您会看到两个日志。 场景 3:应用商店中的任何应用,如 SketchBookX 等,只打印一个日志用于通知发送。它没有收到。

我已经尝试了所有风格的 CFNotificationCenterPostNotification 但没有任何效果。

#import <UIKit/UIKit.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFNotificationCenter.h>
#include "GraphicsServices/GSEvent.h"

#define GS_EVENT_TYPE_OFFSET 2
#define HOME_DOWN 1000
#define HOME_UP 1001
#define VOL_DOWN_KEY_DOWN 1008
#define VOL_DOWN_KEY_UP 1009

extern "C" CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);


void LogEvent(CFNotificationCenterRef center,
          void *observer,
          CFStringRef name,
          const void *object,
          CFDictionaryRef userInfo)
{

NSString *str = [[NSString alloc]initWithFormat:@"%@,%@,%d,%d,%d,%d,%d\r\n",
     (NSString*)CFDictionaryGetValue(userInfo,@"strWindow"),
     (NSString*)CFDictionaryGetValue(userInfo,@"strView"),
     [(NSNumber*)CFDictionaryGetValue(userInfo,@"phase") intValue],
     [(NSNumber*)CFDictionaryGetValue(userInfo,@"xInView") intValue],
     [(NSNumber*)CFDictionaryGetValue(userInfo,@"yInView") intValue],
     [(NSNumber*)CFDictionaryGetValue(userInfo,@"xInWindow") intValue],
     [(NSNumber*)CFDictionaryGetValue(userInfo,@"yInWindow") intValue]];

    NSLog(@"Area51 Notification Received: %@",str);
}

%hook UIApplication
-(void) sendEvent:(UIEvent*)event
{

if(  [NSStringFromClass([event class]) isEqualToString:@"UITouchesEvent"] )
{

    NSSet *touches = [event allTouches];

    NSEnumerator *enumerator = [touches objectEnumerator];
    id value;

    while ((value = [enumerator nextObject])) {
        UITouch *touch = value;
        NSString *strViewClassName;
        if(!touch.view)
            strViewClassName = @" ";
        else
            strViewClassName = [NSString stringWithString:NSStringFromClass([[touch view] class])];

        CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(NULL,0,&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

        CFDictionaryAddValue(dictionary, @"phase", [NSNumber numberWithInt:[touch phase]] );
        CFDictionaryAddValue(dictionary, @"strWindow", NSStringFromClass([[touch window] class]) );
        CFDictionaryAddValue(dictionary, @"strView", strViewClassName);
        CFDictionaryAddValue(dictionary, @"xInView", [NSNumber numberWithInt:[touch locationInView:touch.view].x]) ;
        CFDictionaryAddValue(dictionary, @"yInView", [NSNumber numberWithInt:[touch locationInView:touch.view].y]) ;
        CFDictionaryAddValue(dictionary, @"xInWindow", [NSNumber numberWithInt:[touch locationInView:nil].x]) ;
        CFDictionaryAddValue(dictionary, @"yInWindow", [NSNumber numberWithInt:[touch locationInView:nil].y]) ;

        CFNotificationCenterPostNotificationWithOptions(
             CFNotificationCenterGetDistributedCenter(),
             (CFStringRef)@"RecordTouch",
             NULL,
             dictionary,
             kCFNotificationDeliverImmediately|kCFNotificationPostToAllSessions);

            NSLog(@"Area 51: Notification Send for App: %@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] );

    }

}

%orig;
}

%end

%hook SpringBoard
-(void)applicationDidFinishLaunching:(UIApplication*) application
{

CFNotificationCenterAddObserver(
    CFNotificationCenterGetDistributedCenter(),
    NULL,
    LogEvent,
    NULL,
    NULL,
    CFNotificationSuspensionBehaviorDeliverImmediately);

NSLog(@"Area51: ObserverAdded");

%orig;
}

%end

__attribute__((constructor)) void area51init() {

%init;
}
4

1 回答 1

0

问题似乎是userInfo在将达尔文通知中心用作center. 资源

另请参阅此线程

于 2017-05-10T11:00:40.633 回答