使用无障碍实现自动化脚本可能会被检测,进而被风控,甚至有的app直接从内部禁止使用无障碍技术,一旦发现开启无障碍直接退出app等。今天给大家介绍一种全新的不使用无障碍技术实现的、防检测,防风控的自动化的方案。众所周知,自动化脚本最核心的要素有以下几点:识别界面元素、点击和滑动界面、输入文本,下面就以冰狐智能辅助这个自动化平台为例子,分别就这几点核心要素分别介绍
一、识别界面元素
除了无障碍外,还有多种方法实现识别界面元素,定位目标位置。
1.ocr识别
直接通过ocr来识别界面中的文本来定位目标位置,然后使用hid等来点击。
冰狐的OCR支持在线增量学习,汉字识别率(可以做到99.999%接近100%识别率)高于任何已知的ocr。返回值为数组,里面存放识别到的文本和对应的区域,区域格式为[left, top, width, height](相对屏幕的坐标,不是相对识别区域的坐标)例:[{text:'a', region:[11, 23, 10, 50]}, {text:'b', region:[111, 231, 50, 20]}]。
除了一般的ocr外,冰狐还提供了非常好用的ocrFindView,ocrClick,ocrSwitchPage,ocrBack2Page等api。
function main() {
requestScreenShot();
var ret = ocr();
// 开启awesome,实现汉字100%成功率
// var ret = ocr({awesome:{threshold: 0.9, count: 4}});
console.log('ret:' + ret);
var ret = ocrFindView('txt:数据分析|txt^:首页');
console.log('ret:' + ret);
var ret = ocrClick('数据分析|首页');
console.log('ret:' + ret);
var ret = ocrSwitchPage('查看', '数据分析|首页');
console.log('ret:' + ret);
var ret = ocrBack2Page('首页');
console.log('ret:' + ret);
}
2.找色
找色看起是找颜色,实际上用处非常广,可以制作类似“字库”,也可以实现“找图”功能,直接比对,非常精确,效率也非常高。
冰狐的找色和颜色比较功能在当前UI界面中搜索相似的颜色,返回数组,数组元素为找到的点,用point表示点(屏幕坐标)。可用于找图标,找文字,找颜色等,注意和“比较颜色”的区别,找色可以兼容不同手机的分辨率。
function main() {
requestScreenShot();
// 注意,注意,注意:一定要去冰狐网站,移动端/我的设备/远程控制,然后用鼠标在界面上选择目标颜色和neighbor颜色,可以自动生成找色代码,非常方便。
// 比如我们想找图标,可以先在目标图标中选定一个其他地方没有的目标颜色(#445533),然后再在目标颜色周围选定比较有代表的颜色(最好是不同的颜色)作为neighbor参数,此时就可以高效,准确的找到目标位置了。
var arr = findColor('#445533', {similarity: 0.9, findAll: true, region:[10, 10, 300, 300], neighbor:[[0, 3, '#444455'],[3, 0, '#5673ff'],[-3, 10, '#ff3322'],[-9, 20, '#6ab322']]});
for(var point of arr) {
console.log('find color x:', point.x, ' y:', point.y);
}
// 注意,注意,注意:一定要去冰狐网站,移动端/我的设备/远程控制,然后用鼠标在界面上选择目标颜色,可以自动生成比较颜色的代码,非常方便。
if (compareColors([[45, 112, '#ff0055'], [44, 113, 345566]], {similarity:0.95})) {
console.log('颜色全部匹配');
}
}
可以通过冰狐的在线“图色工具”来非常方便的制作类似的“字库”,如下图所示,只需要点击目标文字或者图标,即可自动搜索搜索对应的点,点击即可自动拷贝找色代码
3.找图
冰狐提供了图片匹配,也即找图功能,在当前UI界面中寻找指定的图片,返回找到图片区域Region,比如:(x:10, y: 20, width:100, height:100),若找不到图,则返回的坐标为负值比如:(x:-1, y:-1, width:0, height:0)。若想同时找多张图片或者要求更高的识别率建议使用YoloV8。
例子:
function main() {
requestScreenShot();
// 相对目录,Pictures目录下的图片
// var region = findImage('Pictures/template.jpg', {region:[10, 10, 300, 100]});
// 在apk资源目录中
// var region = findImage('asset:img.png', {region:[10, 10, 300, 100]});
// 绝对路径
var region = findImage('/sdcard/template.jpg');
if (region) {
console.log('find success x:', region.x, ' y:', region.y, ' width:', region.width, ' height:', region.height);
} else {
console.log('find image failed');
}
}
4.yolo
冰狐提供的YoloV8是基于深度学习(ai大模型)的图片检测、识别算法,是目前为止效率最高、效果最好的算法。可以完全替代找图,不同的分辨率也可以很好的识别,比任何基于OpenCV的找图算法强很多。如果分类比较多,请使用更多的训练图片,否则识别率会降低。
function main() {
requestScreenShot();
var yolo = new YoloV8();
// model_name替换成自己的模型名(注意不要带后缀名),模型文件为:model_name.param和model_nam.bin。class1,class2为目标的类别名
var b = yolo.init('/sdcard/model_name', ['class1', 'class2'])
console.log('b:', b)
// 会自动截屏,然后检测截图,识别目标
var r = yolo.detect();
console.log('r', r)
}
二、点击和滑动界面
除了无障碍外,还有多种方法实现对界面的点击和滑动操作
1.蓝牙hid
冰狐提供的蓝牙HID客户端是通用的,对应的硬件模块为蓝牙HID服务端,也即用户可以直接使用BleClient和蓝牙HID硬件进行通信。这是一个通用接口,支持任何蓝牙HID硬件,可以轻松实现点击、滑动、各种按键等。即可使用冰狐的蓝牙硬件,也可以使用其他的蓝牙硬件。
function main() {
// 参数为蓝牙硬件中对应的service的uuid和characteristic的UUID,这个值一般是固定的
var ret = ble.connect('fe2342e1-d234-fee3-aae4-fe2e342211dc', 'cf3432fb-d234-fee3-aae4-fe2e342211dc');
console.log('ret:', ret)
if (1 == ret) {
bleHome();
}
}
function bleRelease() {
var cmd = 'v';
console.log('cmd:' + cmd)
var ret = ble.send(cmd)
console.log('send ret:', ret)
}
function bleMove(x, y) {
x = parseInt(x * 10000 / rsScreenWidth);
y = parseInt(y * 10000 / rsScreenHeight);
var cmd = `e${x},${y}`;
console.log('cmd:' + cmd)
var ret = ble.send(cmd)
console.log('send ret:', ret)
}
function bleClick(x, y, duration) {
x = parseInt(x * 10000 / rsScreenWidth);
y = parseInt(y * 10000 / rsScreenHeight);
if (null == duration) {
duration = 200
}
var cmd = `c${x},${y},${duration}`;
console.log('cmd:' + cmd)
var ret = ble.send(cmd)
console.log('send ret:', ret)
}
// curvable为1表示模拟真人曲线滑动,0表示直线滑动,默认为1.
function bleSwipe(x1, y1, x2, y2, duration, curvable) {
x1 = parseInt(x1 * 10000 / rsScreenWidth);
y1 = parseInt(y1 * 10000 / rsScreenHeight);
x2 = parseInt(x2 * 10000 / rsScreenWidth);
y2 = parseInt(y2 * 10000 / rsScreenHeight);
if (null == duration) {
duration = 500;
}
if (null == curvable) {
curvable = 1;
}
var cmd = `m${x1},${y1},${x2},${y2},${duration},${curvable}`;
console.log('cmd:' + cmd)
var ret = ble.send(cmd)
console.log('send ret:', ret)
}
function bleSelectAll() {
var ret = ble.send('s')
console.log('send ret:', ret)
}
function bleCopy() {
var ret = ble.send('o')
console.log('send ret:', ret)
}
function bleCut() {
var ret = ble.send('t')
console.log('send ret:', ret)
}
function blePaste() {
var ret = ble.send('p')
console.log('send ret:', ret)
}
function bleHome() {
var ret = ble.send('h')
console.log('send ret:', ret)
}
function bleBack() {
var ret = ble.send('b')
console.log('send ret:', ret)
}
2.usb hid
冰狐提供USB HID客户端,对应的硬件模块为USB HID服务端(比如ESP32 S3等),也即用户可以直接使用UsbClient和USB HID硬件进行通信。这是一个通用接口,支持任何USB HID硬件,可以轻松实现点击、滑动、各种按键等。
function main() {
var b = usb.connect();
console.log('connect:', b);
if (b) {
usbInit(rsScreenWidth, rsScreenHeight)
// usbRecentApps()
// usbSwipe(400, 2000, 600, 1000, 1000)
// usbBack(usb)
usbHome()
// usbClick(800, 650)
}
console.log('end')
}
function usbInit(screenWidth, screenHeight) {
usb.send([0xe].concat(int2bytes(screenWidth, 2), int2bytes(screenHeight, 2)))
sleep(3000)
}
function usbClick(x, y, duration) {
if (null == duration) {
duration = 200
}
usbMouseMove(usb, x, y);
sleep(duration);
usbMouseUp(usb, x, y);
}
function usbMouseMove(x, y) {
usb.send([0x9].concat(int2bytes(x, 2), int2bytes(y, 2)))
}
function usbMouseUp(x, y) {
usb.send([0xa].concat(int2bytes(x, 2), int2bytes(y, 2)))
}
function usbSwipe(x1, y1, x2, y2, duration) {
if (null == duration) {
duration = 300
}
var moveCount = randInt(6, 20)
var dTime = parseInt(duration / moveCount);
var startX = 0, startY = 0, endX = 0, endY = 0, useCurve = false;
if (x1 != x2 && y1 != y2) {
if (x1 < x2 && y1 > y2) {
startX = x1;
startY = y1;
endX = x2;
endY = y2;
useCurve = true;
} else if (x1 > x2 && y1 < y2) {
startX = x2;
startY = y2;
endX = x1;
endY = y1;
useCurve = true;
}
}
if (useCurve) {
var x = endX - startX;
var y = startY - endY;
var a = (endX - startX) / ((endY - startY) * (endY - startY));
var yb = y1;
var ya = (y2 - yb) / (moveCount * moveCount);
for (var i = 1; i < moveCount; ++i) {
var fY = (ya * i * i + yb);
var y = parseInt(fY);
var x = parseInt(a * (y - startY) * (y - startY) + startX);
if (i > 1 && i < moveCount - 1) {
x += randInt(0, 5) - 2;
y += randInt(0, 5) - 2;
}
usbMouseMove(usb, x, y)
sleep(dTime);
}
} else {
usbMouseMove(usb, x1, y1)
var a = (x1 - x2) / (y1 - y2);
var b = x1 - a * y1;
var yb = y1;
var ya = (y2 - yb) / (moveCount * moveCount);
for (var i = 1; i < moveCount; ++i) {
var fY = (ya * i * i + yb);
var y = parseInt(fY);
var x = parseInt((a * y + b));
if (i > 1 && i < moveCount - 1) {
x += randInt(0, 5) - 2;
y += randInt(0, 5) - 2;
}
usbMouseMove(usb, x, y)
sleep(dTime);
}
}
usbMouseMove(usb, x2, y2)
sleep(10);
usbMouseUp(usb, x2, y2)
}
function usbHome() {
usb.send([0x20])
}
function usbBack() {
usb.send([0xd])
}
function usbRecentApps() {
usb.send([0x8, 0x4, 0x2b])
}
function usbCopy() {
usb.send([0x08, 0x01, 0x06])
}
function usbPaste() {
usb.send([0x08, 0x01, 0x19])
}
function usbCut() {
usb.send([0x08, 0x01, 0x1B])
}
function usbSelectAll() {
usb.send([0x08, 0x01, 0x04])
}
3.shizuku
Shizuku允许应用直接使用需要高权限的系统API,而无需通过root,从而提高了效率和安全性。支持ADB命令,用户可以查看和管理应用程序的权限,确保只授予必要的权限,保护隐私和安全。
注意在使用之前必须先下载并安装shizukuapp。打开shizuku后,app界面会显示操作方法,android11及以上建议使用无线调试模式,无线调试模式不需要pc机来配合使用(推荐使用该模式)。其他android版本使用adb调试模式,该模式需要pc机来执行adb命令来开启和授权shizuku服务,授权服务后手机可以和pc断开连接。
function main() {
shizuku.init();
if (shizuku.connect()) {
var r = shizuku.execCmd('ls')
console.log('exe r:' + r)
}
console.log('end')
}
4.adb
冰狐提供的adb功能不需要链接手机和电脑,是使用shizuku来实现的自动化操作的,所以请按shizuku文档先安装和配置好shizuku。可以轻松实现点击、滑动、各种按键等操作
function main() {
adb.init();
if (adb.connect()) {
adb.click(750, 650)
}
adb.close();
console.log('end')
}
5.root
狐支持在已经被root过的手机上使用root权限开发自动化脚本。可以轻松实现点击、滑动、各种按键等操作
function main() {
root.click(750, 650)
}
6.定制rom
冰狐支持在定制rom中实现静默无障碍,或者直接使用系统底层来实现点击、滑动等,app几乎不可能检测到。
三、输入文本
有时候我们会遇到无法使用无障碍输入文本的情况,此时可以使用输入法模块直接通过api将文本输入到输入框中,注意:必须先去手机设置中启用“Simple IME”输入法。
使用定制输入法模块可以直接输入文本到输入框,比无障碍稳定好用n倍,而且还支持输入法命令,比如:done、search等等。
function main() {
ime.inputText('你好');
ime.inputAction('done');
}
四、总结
本文全面介绍了不使用无障碍技术实现自动化脚本的方法,以冰狐智能辅助作为例子,具体讲解了如何实现识别界面元素、点击和滑动界面、输入文本等功能,并给出了具体实现过程和相关源代码。从根本上做到了防检测、放风控。