Can you directly inject into backboardd on iOS 14 and later to simulate events without using UIWindow?
#import "TouchSimulator.h" #import <UIKit/UIApplication.h> #import <dlfcn.h>
// 函数声明 static void postEvent(IOHIDEventRef event); static void execute(); static IOHIDEventRef parent = NULL; unsigned long long int senderID = 0;
void simulateTouch(int type, float x, float y) { if (parent == NULL) { parent = IOHIDEventCreateDigitizerEvent(kCFAllocatorDefault, mach_absolute_time(), kIOHIDDigitizerTransducerTypeHand, 0, 0, kIOHIDDigitizerEventTouch, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, true, 0 ); IOHIDEventSetIntegerValue(parent, kIOHIDEventFieldDigitizerIsDisplayIntegrated, 1); }
uint32_t isTouch = type == TOUCH_UP ? 0 : 1;
IOHIDDigitizerEventMask eventMask = 0;
if (type != TOUCH_UP && type != TOUCH_DOWN)
eventMask |= kIOHIDDigitizerEventPosition;
if (type == TOUCH_UP || type == TOUCH_DOWN)
eventMask |= (kIOHIDDigitizerEventTouch | kIOHIDDigitizerEventRange);
IOHIDEventRef child = IOHIDEventCreateDigitizerFingerEvent(kCFAllocatorDefault, mach_absolute_time(), 1, 3, eventMask, x, y, 0.0f, 0.0f, 0.0f, isTouch, isTouch, 0);
IOHIDEventSetFloatValue(child, kIOHIDEventFieldDigitizerMajorRadius, 0.04f);
IOHIDEventSetFloatValue(child, kIOHIDEventFieldDigitizerMinorRadius, 0.04f);
IOHIDEventAppendEvent(parent, child);
execute();
}
static UIWindow* getKeyWindow() { for (UIWindow *window in [UIApplication sharedApplication].windows) { if (window.isKeyWindow) { return window; } } return NULL; }
static void postEvent(IOHIDEventRef event) { static IOHIDEventSystemClientRef ioSystemClient = nil; UIWindow* keyWindow = getKeyWindow();
if (ioSystemClient == NULL) {
ioSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
}
if (event != NULL && keyWindow != NULL) {
uint32_t contextID = keyWindow._contextId;
void *handle = dlopen("/System/Library/PrivateFrameworks/BackBoardServices.framework/BackBoardServices", RTLD_NOW);
if (handle) {
typedef void (* BKSHIDEventSetDigitizerInfoType)(IOHIDEventRef,uint32_t,uint8_t,uint8_t,CFStringRef,CFTimeInterval,float);
BKSHIDEventSetDigitizerInfoType digitizer = (BKSHIDEventSetDigitizerInfoType)dlsym(handle, "BKSHIDEventSetDigitizerInfo");
digitizer(event, contextID, false, false, NULL, 0, 0);
[[UIApplication sharedApplication] _enqueueHIDEvent:event];
}
}
IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);
IOHIDEventSystemClientDispatchEvent(ioSystemClient, event);
}
static void execute() { IOHIDEventSetIntegerValue(parent, kIOHIDEventFieldDigitizerTiltX, kIOHIDDigitizerTransducerTypeHand); IOHIDEventSetIntegerValue(parent, kIOHIDEventFieldDigitizerTiltY, 1); IOHIDEventSetIntegerValue(parent, kIOHIDEventFieldDigitizerAltitude, 1); postEvent(parent); CFRelease(parent); parent = NULL; }