0x00 ...最近在瞎琢磨Android设备的云控,想要实现一个多点滑动的功能。我们知道通过shell执行input swipe x1 y1 x2 y2 t
可以实现t毫秒内从坐标(x1, y1)滑动到(x2, y2),滑动完成后模拟的动作就“被抬起”,很难直接通过input实现滑动”转弯“。于是花了半天时间看了一下sendevent的参数含义,简单实现了连续滑动的功能。
0x01 简述sendevent需要4个参数,如下:use: sendevent device type code value
含义分别是设备、事件类型、事件代码以及传递的数据。 在分析之前可以通过getevent获取事件的数据以便参照,如下为简单滑动后获取的数据:
/dev/input/event0: 0003 0039 00000c3a
/dev/input/event0: 0001 014a 00000001
/dev/input/event0: 0001 0145 00000001
/dev/input/event0: 0003 0035 00000124
/dev/input/event0: 0003 0036 00000393
/dev/input/event0: 0003 0031 00000005
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0031 00000006
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0030 00000007
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0030 00000006
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0036 00000391
/dev/input/event0: 0003 0030 00000007
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0036 0000038f
/dev/input/event0: 0003 0030 00000006
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0035 00000125
/dev/input/event0: 0003 0036 00000389
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0035 00000126
/dev/input/event0: 0003 0036 00000380
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0035 00000133
/dev/input/event0: 0003 0036 00000353
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0035 0000013a
/dev/input/event0: 0003 0036 00000341
/dev/input/event0: 0003 0031 00000005
/dev/input/event0: 0000 0000 00000000
....
/dev/input/event0: 0003 0035 0000031c
/dev/input/event0: 0003 0036 000002a3
/dev/input/event0: 0000 0000 00000000
/dev/input/event0: 0003 0039 ffffffff
/dev/input/event0: 0001 014a 00000000
/dev/input/event0: 0001 0145 00000000
/dev/input/event0: 0000 0000 00000000
type和code的含义可参照内核源码中的input.h,笔者用的Nexus6P,msm-android-msm-angler-3.10-nougat-mr2,该头文件位于include/uapi/linux/input.h。
滑动所需的type含义如下:
type 0000 Synchronization events type 0001 Keys and buttons type 0003 Absolute axes,即描述运动事件的值
code含义如下
0000 0000 SYN_REPORT,这里笔者简单理解为与io的flush类似 0003 0039 开始接触设备的唯一标识号,这里为0xc3a, 0xffffffff代表结束接触 0001 014a 标明触摸事件,1代表按下,0代表放开 0001 0145 表明是用手指触摸的,同样1代表按下,0代表放开 0003 0035 触摸的x坐标 0003 0036 触摸的y坐标 0003 0030 接触面椭圆长轴,非必需 0003 0031 接触面椭圆短轴,非必需
0x02 实现其实到这里已经很清晰了,开始接触->按下->一系列坐标移动->结束接触->放开,通过坐标的移动可以控制滑动的痕迹,sendevent执行的快慢控制滑动的快慢。要注意最好执行在同一个shell,并且不要阻塞(waitfor)。 给出的代码直接调用即可:
EventEmulator.swipeStart();
EventEmulator.swipeRun(357, 2054, 1112, 1308);
EventEmulator.swipeRun(1112, 1308, 1112, 2032);
EventEmulator.swipeEnd();
即从(357, 2054)滑动到(1112, 1308),接着又滑到(1112, 2032)。代码写得很粗糙。
如果需要改变滑动的速度,可以将代码里控制坐标间隔次数的值SWIPE_RUN_INTERVAL
改小一点,间隔次数越少,滑动越快。
private static final int SWIPE_RUN_INTERVAL = 5;
public static void swipeRun(int x1, int y1, int x2, int y2) {
int xStep = (x2 - x1) / SWIPE_RUN_INTERVAL;
int yStep = (y2 - y1) / SWIPE_RUN_INTERVAL;
int x = x1, y = y1;
for (int step = 0; step <= SWIPE_RUN_INTERVAL; ++step) {
sendEvent(EV_ABS, ABS_MT_POSITION_X, x);
sendEvent(EV_ABS, ABS_MT_POSITION_Y, y);
sendEvent(EV_SYN, SYN_REPORT, 0);
x += xStep;
y += yStep;
}
}
0x03 TODO为了更好地拟人,滑动速度的大小以及变化、路线是否弯曲都应该做相应调整,并且需要加上接触面长短轴变化的时间。
CTF训练营-Web篇
最后于 2019-11-20 10:02
被Umiade编辑
,原因:
上传的附件: