在上一篇文章 Android 外部 imgui 绘制 (二)–补充补充说明了 ue4 游戏下触摸输入的获取方法。本篇介绍一种更为通用的获取系统输入的方法.
原理
在 Android 系统中获取系统输入的原理是读取 "/dev/input/event" 下的文件,监听是否有系统输入。然后将不同的输入进行加工,然后分发.
在安卓系统中输入事件被分成了
1 | KeyEvent(键盘输入) |
参考
/frameworks/native/libs/input/Input.cpp
每一种 Event 在分发之前都会经过初始化的流程,以触摸事件为例
1 | 1345 void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) { |
注意到,event->initialize 就是初始化一个 MotionEvent.
而这个函数 (InputConsumer::initializeMotionEvent) 就是需要 Hook 的函数.
参考
/frameworks/native/libs/input/InputTransport.cpp
过程
随便观察一个 app 进程的 maps, 过滤得到 libinput.so 的路径.
这个 libinput.so 就包含上面 InputConsumer::initializeMotionEvent 的代码.
拉到电脑上,ida 打开.
得到它的导出函数符号是
1 | _ZN7android13InputConsumer21initializeMotionEventEPNS_11MotionEventEPKNS_12InputMessageE |
用 Dobby 进行 hook
1 | static void hook_input() |
在 new_input 就可以得到系统输入了.
1 | static void new_input(void *thiz, void *a2, void *a3) |
如果出现崩溃等 bug, 请检查是否是 DobbySymbolResolver 的问题,请指定第一个参数为 libinput.so 的路径
例如:
1 | void *sym_input = DobbySymbolResolver("system/lib/libinput.so","_ZN7android13InputConsumer21initializeMotionEventEPNS_11MotionEventEPKNS_12InputMessageE"); |