【Android安全-通过模拟触摸屏控制器驱动来实现手机点击,滑动操作】此文章归类为:Android安全。
1
|
本人是武汉科锐毕业生,写该工具目的是用来学习内核知识的,忘各位大佬指点
|
该项目主要作用是模拟驱动来实现对触摸屏的操控。如:滑动,点击操作。
1
|
整个分为
3
个部分
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
触摸屏驱动部分:
文件synaptics_dsx_core.c,该驱动为内核原本的驱动,其中添加了函数synaptics_rmi4_f12_abs_report_me为关键代码用来向输入子系统报告触摸屏操作。通过封装synaptics_rmi4_f12_abs_report_me实现
2
个函数,set_input_touch_slide,set_input_touch_click分别实现滑动和点击事件
/
/
该函数为实现触摸关键函数
/
/
stop为控制是触摸还是停止,true为手指离开,false为手指还在屏幕上
/
/
x,y位坐标
static
int
synaptics_rmi4_f12_abs_report_me(
bool
stop,
int
x,
int
y)
{
int
wx;
int
wy;
/
/
判断是手指是否离开触摸屏
if
(stop
=
=
true){
data_me.object_type_and_status
=
20
;
}
else
{
data_me.object_type_and_status
=
F12_FINGER_STATUS;
}
wx
=
0
;
wy
=
0
;
switch (data_me.object_type_and_status) {
case F12_FINGER_STATUS:
case F12_GLOVED_FINGER_STATUS:
/
*
Stylus has priority over fingers
*
/
printk(KERN_ALERT
"zeyu F12_GLOVED_FINGER_STATUS\n"
);
/
/
向输入子系统报告触摸屏触摸信息,p_inputdev为触摸屏设备的指针,该指针我是通过正常驱动函数中拿到的,当然也可以通过其他途径,大家自行考虑
input_mt_slot(p_inputdev,
0
);
input_mt_report_slot_state(p_inputdev,
MT_TOOL_FINGER,
1
);
input_report_key(p_inputdev,
BTN_TOUCH,
1
);
input_report_key(p_inputdev,
BTN_TOOL_FINGER,
1
);
input_report_abs(p_inputdev,
ABS_MT_POSITION_X, x);
input_report_abs(p_inputdev,
ABS_MT_POSITION_Y, y);
input_report_abs(p_inputdev,
ABS_MT_TOUCH_MAJOR,
synaptics_sqrt(wx
*
wx
+
wy
*
wy));
input_report_abs(p_inputdev,
ABS_MT_TOUCH_MINOR,
min
(wx, wy));
input_report_abs(p_inputdev,
ABS_MT_PRESSURE,
1
);
break
;
default:
/
/
当手指离开触摸屏时执行到这里
printk(KERN_ALERT
"zeyu default\n"
);
input_mt_slot(p_inputdev,
0
);
input_mt_report_slot_state(p_inputdev,
MT_TOOL_FINGER,
0
);
break
;
}
/
/
该函数执行立即同步,不然会有延迟
input_sync(p_inputdev);
return
0
;
}
/
/
该函数为实现点击触摸屏
void set_input_touch_click(
int
x,
int
y)
{
/
/
这是为了模拟更像所以多调用几次
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
synaptics_rmi4_f12_abs_report_me(false,x,y);
/
/
手指离开屏幕(如果不设置,则表示为长时间触摸该位置)
synaptics_rmi4_f12_abs_report_me(true,x,y);
return
;
}
/
/
该代码作用为将该符号到处给其他驱动使用
EXPORT_SYMBOL(set_input_touch_click);
/
/
该函数实现滑动触摸屏,为开始的位置到停止的位置,可以看到我都是分为
9
次移动过去,系统会通过判断时间等来判断点击和移动的。其中代码就不仔细分析了。
void set_input_touch_slide(
int
start_x,
int
start_y,
int
end_x,
int
end_y)
{
int
tmp_x
=
0
;
int
tmp_y
=
0
;
int
zeyu_x
=
0
;
int
zeyu_y
=
0
;
size_t i
=
0
;
if
((end_x
=
=
start_x) && (end_y
=
=
start_y)) {
return
;
}
if
((end_x >
=
start_x) && (end_y >
=
start_y)) {
tmp_x
=
end_x
-
start_x;
tmp_y
=
end_y
-
start_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
+
(tmp_x
*
i);
zeyu_y
=
start_y
+
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x >
=
start_x) && (end_y <
=
start_y)) {
tmp_x
=
end_x
-
start_x;
tmp_y
=
start_y
-
end_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
+
(tmp_x
*
i);
zeyu_y
=
start_y
-
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x <
=
start_x) && (end_y >
=
start_y)) {
tmp_x
=
start_x
-
end_x;
tmp_y
=
end_y
-
start_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
-
(tmp_x
*
i);
zeyu_y
=
start_y
+
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
if
((end_x <
=
start_x) && (end_y <
=
start_y)) {
tmp_x
=
start_x
-
end_x;
tmp_y
=
start_y
-
end_y;
tmp_x
=
tmp_x
/
9
;
tmp_y
=
tmp_y
/
9
;
for
(i
=
0
; i <
=
9
; i
+
+
)
{
zeyu_x
=
start_x
-
(tmp_x
*
i);
zeyu_y
=
start_y
-
(tmp_y
*
i);
if
(i
=
=
9
) {
zeyu_x
=
end_x;
zeyu_y
=
end_y;
}
synaptics_rmi4_f12_abs_report_me(false,zeyu_x,zeyu_y);
}
synaptics_rmi4_f12_abs_report_me(true,
0
,
0
);
return
;
}
return
;
}
EXPORT_SYMBOL(set_input_touch_slide);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
自己的驱动部分:
文件hello.c,该驱动的主要作用是为了打通用户层,使得用户层可以通过ioctl来通过该驱动来调用synaptics_dsx_core.c内的函数。所以该驱动只是在
/
dev下创建一个文件。如果大家懂windows驱动的话很相似
主要代码都是在初始化代码来创建该文件
/
/
设备类别和设备变量
static struct
class
*
g_class
=
0
;
dev_t devno
=
0
;
static struct cdev
*
dev
=
0
;
char lele[
0x10
]
=
"zeyudev"
;
/
/
在dev下创建文件,但该文件是root属性
static
int
hello_init(void)
{
int
err
=
-
1
;
struct device
*
temp
=
NULL;
printk(KERN_ALERT
"zeyu Hello, world\n"
);
/
/
动态分配主设备号与从设备号
err
=
alloc_chrdev_region(&devno,
0
,
1
,
"zeyu_dev"
);
if
(err <
0
){
printk(KERN_ALERT
"zeyu alloc_chrdev_region erro\n"
);
}
dev
=
kmalloc(sizeof(struct cdev),GFP_KERNEL);
if
(!dev){
printk(KERN_ALERT
"zeyu kmalloc erro\n"
);
}
memset(dev,
0
,sizeof(struct cdev));
/
/
初始化设备,初始化结构体
cdev_init(dev,&h_ops);
dev
-
>owner
=
THIS_MODULE;
dev
-
>ops
=
&h_ops;
/
/
注册字符串设备
err
=
cdev_add(dev,devno,
1
);
if
(err <
0
){
printk(KERN_ALERT
"zeyu cdev_add erro\n"
);
}
/
/
在
/
sys
/
class
/
下创建设备类别目录
g_class
=
class_create(THIS_MODULE,
"zeyu_dev"
);
if
(IS_ERR(g_class)){
printk(KERN_ALERT
"zeyu g_class erro\n"
);
}
/
/
在
/
dev目录和
/
sys
/
class
目录下分别创建文件
temp
=
device_create(g_class,NULL,devno,
"%s"
,
"zeyudev"
);
if
(IS_ERR(temp)){
printk(KERN_ALERT
"zeyu device_create erro\n"
);
}
return
0
;
}
/
/
该函数为驱动的控制函数
static
long
myDev_compat_ioctl(struct
file
*
file
, unsigned
int
cmd, unsigned
long
arg){
struct zeyu_io_cmd_data data
=
{
0
};
struct zeyu_io_cmd_data
*
data_user_add
=
0
;
unsigned
long
ret
=
0
;
data_user_add
=
(struct zeyu_io_cmd_data
*
)arg;
/
/
将用户层数据copy到内核中
ret
=
copy_from_user((void
*
)(&data),(void __user
*
)data_user_add,sizeof(data));
switch(data.cmd){
/
/
执行点击
case INPUT_TOUCH_CLICK:
set_input_touch_click(data.x,data.y);
break
;
/
/
执行滑动
case INPUT_TOUCH_SLIDE:
set_input_touch_slide(data.x_start,data.y_start,data.x_end,data.y_end);
break
;
}
return
0
;
}
其他函数就不介绍了
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
用户层部分:
文件my_dev_user.cpp,打开自己的驱动文件然后通过自定义zeyu_io_cmd_data结构体传送数据,来实现点击。
int
main(
int
argc, char
*
argv[]){
int
fd
=
open
(
"/dev/zeyudev"
,O_RDWR);
if
(fd <
0
){
printf(
"open err"
);
}
struct zeyu_io_cmd_data data
=
{
0
};
for
(
int
i
=
0
;i <
=
100
;i
+
+
){
data.cmd
=
INPUT_TOUCH_CLICK;
data.x
=
1049
;
data.y
=
725
;
ioctl(fd,
0
,&data);
/
/
暂停一下,将点击与滑动操作分开
usleep(
3000000
);
data.cmd
=
INPUT_TOUCH_SLIDE;
data.x_start
=
614
;
data.y_start
=
1401
;
data.x_end
=
645
;
data.y_end
=
254
;
ioctl(fd,
0
,&data);
usleep(
3000000
);
}
close(fd);
printf(
"main end"
);
return
0
;
}
|
本人使用该代码,尝试在真机上在某社交app执行点赞以及滑动下一个视频动作。
这是在下的项目地址:
该手机使用的是真机piexl 1,系统版本是android10
更多【Android安全-通过模拟触摸屏控制器驱动来实现手机点击,滑动操作】相关视频教程:www.yxfzedu.com