Gssendevent - Inject Touch Event iOS

GSSendEvent - Inject Touch Event iOS

Only tested on iOS 6

You are actually on the right track. The problem is you have to figure out what values you should assign to these variables.

First of all, you need to import GraphicsServices.h. Then, you can try the following code with the port which you can get from How to find the purple port for the front most application in IOS 5 and above?.

I am not an iOS expert and Apple doesn't provide any documentation so I can't explain much what's going on here. (It happens to work fine for me.)

Anyway, you can play with it using xcode debug mode to see what happens under the hood.

struct GSTouchEvent * touchEvent = (struct GSTouchEvent*) &gsTouchEvent;
bzero(touchEvent, sizeof(touchEvent));
touchEvent->record.type = kGSEventHand;
touchEvent->record.subtype = kGSEventSubTypeUnknown;
touchEvent->record.location = point;
touchEvent->record.windowLocation = point;
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.window = winRef;
touchEvent->record.senderPID = 919;
bzero(&touchEvent->handInfo, sizeof(GSHandInfo));
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
GSHandInfo touchEventHandInfo;
touchEventHandInfo._0x5C = 0;
touchEventHandInfo.deltaX = 0;
touchEventHandInfo.deltaY = 0;
touchEventHandInfo.height = 0;
touchEventHandInfo.width = 0;
touchEvent->handInfo = touchEventHandInfo;
touchEvent->handInfo.type = handInfoType;
touchEvent->handInfo.deltaX = 1;
touchEvent->handInfo.deltaY = 1;
touchEvent->handInfo.pathInfosCount = 0;
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03: 0x00;
touchEvent->handInfo.x52 = 1;
touchEvent->handInfo.pathInfos[0].pathLocation = point;
touchEvent->handInfo.pathInfos[0].pathWindow = winRef;
GSEventRecord* record = (GSEventRecord*) touchEvent;
record->timestamp = GSCurrentEventTimestamp();
GSSendEvent(record, port);

To use this code, you have to call it multiple times. For one tap, there are touch-down, touch-drag and then touch-up.

Also note that pathProximity is 0 when touch is up.

As far as I remember, the winRef doesn't matter.

Hope this helps.

Edit: From Bugivore's comment, the problem is:

The way I allocated touchEvent via malloc was wrong. It should be done as EntryLevelDev showed - "static uint8_t handJob[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];"

how to make GSSendEvent call and simulate a touch event

1) struct GSTouchEvent *touchEvent = (struct GSTouchEvent *) malloc(sizeof(struct GSTouchEvent));

memory is not enough
need one more pathinfo for touchEvent->handInfo.pathInfos[0]
as its define in struct has no memory, length of array "pathInfos" is 0, but you used 1struct GSTouchEvent

2) memory of GSHandInfo touchEventHandInfo should be reset

bzero(&touchEventHandInfo, sizeof(GSHandInfo));

How can I simulate the touch events by IOHIDEvent?

As I mentioned in my answer to your other question today, you might try looking at GSEvent.h from GraphicsServices.framework, or in IOKit.framework.

Here are some good answers on stackoverflow to help you:

iOS Private API: lock device and power off the screen

GSSendEvent - Inject Touch Event iOS

iOS touch event notifications (private API)

How to find the purple port for the front most application in IOS 5 and above?

UPDATE: I haven't tested this on ios7.

I happen to work on the exact same requirement before.

To get the purple port, you can use GSCopyPurpleNamedPort() with the bundle Id as an argument.

If you need to simulate touch on SpringBoard, use GSGetPurpleSystemEventPort.

With this below code, you should be able to get the port and use it to inject touch system wide.

#import <dlfcn.h>
// Framework Paths
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
-(mach_port_t)getFrontMostAppPort
{
bool locked;
bool passcode;
mach_port_t *port;
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() = dlsym(lib, "SBSSpringBoardServerPort");
void* (*SBGetScreenLockStatus)(mach_port_t* port, bool *lockStatus, bool *passcodeEnabled) = dlsym(lib, "SBGetScreenLockStatus");
port = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(lib);
SBGetScreenLockStatus(port, &locked, &passcode);
void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) = dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");
char appId[256];
memset(appId, 0, sizeof(appId));
SBFrontmostApplicationDisplayIdentifier(port, appId);
NSString * frontmostApp=[NSString stringWithFormat:@"%s",appId];
if([frontmostApp length] == 0 || locked)
return GSGetPurpleSystemEventPort();
else
return GSCopyPurpleNamedPort(appId);
}

I've tested...this works fine on iOS 5 and 6.
You might not need the lock part if you don't inject when the lock screen shows up.
Hope this helps.

Open Siri using private API's in iOS 8

You should check out the runtime headers of all the private/public apis here.

I found a method hidden in accessibility, which could possibly work in your case. Have a look at it here: http://git.io/frK6Sw . The method is named -(void)openSiri, which suggest that it might open Siri, I haven't tried though.



Related Topics



Leave a reply



Submit