11

我正在尝试编写一个在后台运行并向跳板或其他应用程序注入触摸的应用程序。我了解我将使用私有 API 和结构。该应用程序是企业应用程序,不需要获得 AppStore 的批准。

我正在使用 KennyTM 建议的 GSEvent 结构,并对 IOS 5/6 进行了一些小的修改。我可以通过发送 GSSystemEvents 将触摸事件和其他事件发送到 Springboard。

我还需要能够将类似的事件发送到其他应用程序,但我无法找到最前面的应用程序的端口。

有没有办法为预先运行的应用程序获取端口,以便我可以将我的 GSEvents 发送到应用程序?

如果有人可以为我指出示例或向我展示如何获得最前端应用程序的紫色端口,那就太好了。

谢谢!

4

1 回答 1

12

更新:我没有在 ios7 上测试过这个。

我之前碰巧在完全相同的要求上工作。

要获取紫色端口,您可以使用 GSCopyPurpleNamedPort() 并将捆绑 ID 作为参数。

如果需要在 SpringBoard 上模拟触摸,请使用 GSGetPurpleSystemEventPort。

使用下面的代码,您应该能够获取端口并使用它在整个系统范围内注入触摸。

#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);
}

我已经测试过...这在 iOS 5 和 6 上运行良好。如果您在锁定屏幕出现时不注入,您可能不需要锁定部分。希望这可以帮助。

于 2013-04-22T22:04:02.493 回答