一种全新的防检测、防风控的自动化脚本方案(市面上最全的rpa方案)

使用无障碍实现自动化脚本可能会被检测,进而被风控,甚至有的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');
}

四、总结

本文全面介绍了不使用无障碍技术实现自动化脚本的方法,以冰狐智能辅助作为例子,具体讲解了如何实现识别界面元素、点击和滑动界面、输入文本等功能,并给出了具体实现过程和相关源代码。从根本上做到了防检测、放风控。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值