iOS8/9/10 控制音量键- HOOK代码实现


具体实现:控制系统按键-音量键


前期在iosre找了一下有关于音量键的实现和处理,基本都是半桶水,也没有具体告知怎么去实现,的确苦恼了我几天,后来找到了相关代码和系统实现终于解决,今天我就分享出来,希望大家都贡献技术,少互黑 多闷声发大财。在群里被T了 ,这两天论坛被D,现在才上来分享一下:

**TODO:**针对 http://iphonedevwiki.net/index.php/IOHIDFamily 的文献仅仅只能参考Keyboard events的Usage对应的编号,离实际上的成功还差的远。

##问题:

  1. 最新版thoes对IOKit.framework的引入编译肯定是不行,一直报错。
  2. 导入#include <IOKit/hid/IOHIDEventSystem.h> 也是无法编译。
  3. 通过SpringBoard的_handleHIDEvent函数只能触发语音控制/home/锁屏键之类,无法实现音量实体按键。
  4. 守护程序-launchd多面手对提供自定义事物支持。

实现:

1. 引入头文件:

2. extern “C” IOKit 函数:

struct __IOHIDEvent * holdEvent;
extern "C"{
typedef uint32_t IOHIDEventOptionBits;
typedef struct __IOHIDEvent *IOHIDEventRef;

typedef CFTypeRef IOHIDEventSystemClientRef;
typedef CFTypeRef IOHIDEventSystemConnectionRef;

IOHIDEventRef IOHIDEventCreateKeyboardEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, uint16_t usagePage, uint16_t usage, Boolean down, IOHIDEventOptionBits flags);


IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);

void IOHIDEventSetSenderID(struct __IOHIDEvent * event, uint64_t sender);


void IOHIDEventSystemClientDispatchEvent(IOHIDEventSystemClientRef client, IOHIDEventRef event);


typedef CFTypeRef IOHIDEventSystemRef;
typedef uint32_t IOHIDEventType;
typedef uint32_t IOOptionBits;
typedef uint32_t IOHIDEventField;
typedef uint32_t IOHIDDigitizerTransducerType;

CFTypeID IOHIDEventSystemGetTypeID(void);
IOHIDEventSystemRef IOHIDEventSystemCreate(CFAllocatorRef allocator);

IOHIDEventRef IOHIDEventSystemCopyEvent(IOHIDEventSystemRef system, IOHIDEventType type, IOHIDEventRef event, IOOptionBits options);
CFIndex IOHIDEventGetIntegerValue(void *, uint32_t);


void IOHIDEventSetIntegerValueWithOptions(IOHIDEventRef event, IOHIDEventField field, int value, IOOptionBits options);

void IOHIDEventAppendEvent(IOHIDEventRef event, IOHIDEventRef childEvent);
void IOHIDEventSetIntegerValue(IOHIDEventRef event, IOHIDEventField field, int value);}

3.申明传递事件函数:

static void SendHIDEvent(IOHIDEventRef event) {
    static IOHIDEventSystemClientRef client_(NULL);
    if (client_ == NULL)
        client_ = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
    
    IOHIDEventSetSenderID(event, 0xDEFACEDBEEFFECE5);
    IOHIDEventSystemClientDispatchEvent(client_, event);
    CFRelease(event);
}

4. 音量键减 点击触发:

  uint64_t abTime = mach_absolute_time();
    {
        //down
        IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, *(AbsoluteTime *)&abTime, 0x0c, 0xea, 1, 0);                        

#define kIOHIDEventFieldBuiltIn 4
#define kIOHIDEventFieldDigitizerDisplayIntegrated 720921

        //IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldDigitizerDisplayIntegrated, 1, -268435456); //-268435456
        //IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldBuiltIn, 1, -268435456); //-268435456
        
        IOHIDEventSetIntegerValue(event,kIOHIDEventFieldBuiltIn, 1);

        #define kIOHIDEventDigitizerSenderID 0x0000000100000194
        IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);
        
        SendHIDEvent(event);

    }
    
    {
        //up
        uint64_t abTime2 = mach_absolute_time();        
        IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, *(AbsoluteTime *)&abTime2, 0x0c, 0xea, 0, 0);                        

#define kIOHIDEventFieldBuiltIn 4
#define kIOHIDEventFieldDigitizerDisplayIntegrated 720921

        //IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldDigitizerDisplayIntegrated, 1, -268435456); //-268435456
        //IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldBuiltIn, 1, -268435456); //-268435456
       
        IOHIDEventSetIntegerValue(event,kIOHIDEventFieldBuiltIn, 1);
        #define kIOHIDEventDigitizerSenderID 0x0000000100000194
        IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);            
        SendHIDEvent(event);

    }

操作步骤:

  1. 安装deb后注销手机 Killall -9 SpringBoard
  2. 手机环境: iOS8.2 iOS9.2 iOS10.2 iPhone5s arm64

结尾:

对于 IOHIDEventSetIntegerValue 函数的处理很关键。

别看短短的几句代码,实际上困扰了很多人,至少我在gogole没有找到比较完美的解决办法。关于问题第4点launchd多面手主要是提供底层接口接受处理事物支持,比如你在某个app的xm里调用函数 [%c(xxx) sendMessage:@"click_volume_up"] 后这时候你注册的守护程序会直接hook SpringBoard触发音量键按键。希望可以帮到大家!

5 个赞

所以你是干了啥被踢了

群里发了一个公司想招人的职位信息,然后说没说好,就被T了。


群规里我记得是说过不能发招聘的。嘛

具体报错是啥

群规我忘记看了,论坛的群我看的不是很多。的确失误没注意,哈哈。
具体报错主要是我用的thoes版本和IOKit的设置没对,就没折腾了。最后还是用的extern的方式实现了,使用场景主要是为了在hook代码里控制触动精灵的脚本运行逻辑。这样HOOK+触动动态配合,就简单的实现了。

3 个赞

感谢大神的分享。
关于这里

想请教一下:
1.[%c(xxx) sendMessage:@"click_volume_up"]是指 app 与守护程序通信吗?
如果是,请问是什么方式?
2. 守护程序是指 Daemon 么?
如果是,守护程序如何 hook SpringBoard 触发音量键?

谢谢大神分享。直接 hook SpringBoard 调用代码真实有效。

后面看到的同学,有点问题需要注意,编译的时候 IOHIDEventSystemClientCreate 无法找到引用,需要吧 IOKit.framework 拖入项目引用,编译才会不会报错。

我想实现的功能,和楼主一样。也是调用 按键精力 运行执行脚本。 太感谢了。

楼主哥,怎么只有音量-,有没有音量+的代码呢?

不客气~~

目前只有实现音量-的实现 +的逻辑直接看iphonewiki里的代号

大神你好,试了你的代码真实有效,这个是模拟点击了音量键。请问模拟点击Home键,要怎么做,本人是小白,可以给我个详细链接吗。

您真Pro啊

你好,能分享一下实现的项目demo吗?

你好,具体的实现demo能分享一下吗,我在使用的过程中xcode会报错。

就把上面代码直接粘贴进去就可以了 没有什么demo。

关键是具体怎么实现还不知道,想在方法中执行c++代码。

Undefined symbols for architecture arm64:
“_IOHIDEventSystemClientCreate”, referenced from:
SendHIDEvent(__IOHIDEvent*) in HOOKVolumeViewController.o
“_IOHIDEventSystemClientDispatchEvent”, referenced from:
SendHIDEvent(__IOHIDEvent*) in HOOKVolumeViewController.o
“_IOHIDEventCreateKeyboardEvent”, referenced from:
-[HOOKVolumeViewController rightButtonItemClick] in HOOKVolumeViewController.o
“_IOHIDEventSetIntegerValue”, referenced from:
-[HOOKVolumeViewController rightButtonItemClick] in HOOKVolumeViewController.o
“_IOHIDEventSetSenderID”, referenced from:
-[HOOKVolumeViewController rightButtonItemClick] in HOOKVolumeViewController.o
SendHIDEvent(__IOHIDEvent*) in HOOKVolumeViewController.o
ld: symbol(s) not found for architecture arm64
这是报错信息

#import "HOOKVolumeViewController.h"

#include <stdlib.h>
#include <string.h>
#include <mach/mach_time.h>
#include <stdio.h>


struct __IOHIDEvent * holdEvent;
extern "C"{
	typedef uint32_t IOHIDEventOptionBits;
	typedef struct __IOHIDEvent *IOHIDEventRef;
	
	typedef CFTypeRef IOHIDEventSystemClientRef;
	typedef CFTypeRef IOHIDEventSystemConnectionRef;
	
	IOHIDEventRef IOHIDEventCreateKeyboardEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, uint16_t usagePage, uint16_t usage, Boolean down, IOHIDEventOptionBits flags);
	
	
	IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);
	
	void IOHIDEventSetSenderID(struct __IOHIDEvent * event, uint64_t sender);
	
	
	void IOHIDEventSystemClientDispatchEvent(IOHIDEventSystemClientRef client, IOHIDEventRef event);
	
	
	typedef CFTypeRef IOHIDEventSystemRef;
	typedef uint32_t IOHIDEventType;
	typedef uint32_t IOOptionBits;
	typedef uint32_t IOHIDEventField;
	typedef uint32_t IOHIDDigitizerTransducerType;
	
	CFTypeID IOHIDEventSystemGetTypeID(void);
	IOHIDEventSystemRef IOHIDEventSystemCreate(CFAllocatorRef allocator);
	
	IOHIDEventRef IOHIDEventSystemCopyEvent(IOHIDEventSystemRef system, IOHIDEventType type, IOHIDEventRef event, IOOptionBits options);
	CFIndex IOHIDEventGetIntegerValue(void *, uint32_t);
	
	
	void IOHIDEventSetIntegerValueWithOptions(IOHIDEventRef event, IOHIDEventField field, int value, IOOptionBits options);
	
	void IOHIDEventAppendEvent(IOHIDEventRef event, IOHIDEventRef childEvent);
	void IOHIDEventSetIntegerValue(IOHIDEventRef event, IOHIDEventField field, int value);
}

static void SendHIDEvent(IOHIDEventRef event) {
	static IOHIDEventSystemClientRef client_(NULL);
	if (client_ == NULL)
		client_ = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
	
	IOHIDEventSetSenderID(event, 0xDEFACEDBEEFFECE5);
	IOHIDEventSystemClientDispatchEvent(client_, event);
	CFRelease(event);
}


@interface HOOKVolumeViewController ()

@end

@implementation HOOKVolumeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
	self.view.backgroundColor = [UIColor lightGrayColor];
	
	UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithTitle:@"音量键-" style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonItemClick)];
	self.navigationItem.rightBarButtonItem = barItem;
    // Do any additional setup after loading the view.
}

- (void)rightButtonItemClick
{
	NSLog(@"%s",__func__);
	
	uint64_t abTime = mach_absolute_time();
	{
			//down
		IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, *(AbsoluteTime *)&abTime, 0x0c, 0xea, 1, 0);
		
#define kIOHIDEventFieldBuiltIn 4
#define kIOHIDEventFieldDigitizerDisplayIntegrated 720921
		
			//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldDigitizerDisplayIntegrated, 1, -268435456); //-268435456
			//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldBuiltIn, 1, -268435456); //-268435456
		
		IOHIDEventSetIntegerValue(event,kIOHIDEventFieldBuiltIn, 1);
		
#define kIOHIDEventDigitizerSenderID 0x0000000100000194
		IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);
		
		SendHIDEvent(event);
		
	}
	
	{
			//up
		uint64_t abTime2 = mach_absolute_time();
		IOHIDEventRef event = IOHIDEventCreateKeyboardEvent(kCFAllocatorDefault, *(AbsoluteTime *)&abTime2, 0x0c, 0xea, 0, 0);
		
#define kIOHIDEventFieldBuiltIn 4
#define kIOHIDEventFieldDigitizerDisplayIntegrated 720921
		
			//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldDigitizerDisplayIntegrated, 1, -268435456); //-268435456
			//IOHIDEventSetIntegerValueWithOptions(event, kIOHIDEventFieldBuiltIn, 1, -268435456); //-268435456
		
		IOHIDEventSetIntegerValue(event,kIOHIDEventFieldBuiltIn, 1);
#define kIOHIDEventDigitizerSenderID 0x0000000100000194
		IOHIDEventSetSenderID(event, kIOHIDEventDigitizerSenderID);
		SendHIDEvent(event);
		
	}
	
}

所有的代码都在这了,能帮忙鉴定一下吗,谢谢

1 个赞