隐藏

基于autojs的群控插件

发布:2023/11/21 10:10:21作者:管理员 来源:本站 浏览次数:552

   autojs4.1端,打包成apk。upd服务自动发现,websocket命令中转,服务自检。


//引入需要用到的安卓包

importClass("java.net.InetAddress");

importClass("java.net.Inet6Address");

importClass("java.net.NetworkInterface");

importClass("java.net.InetSocketAddress");

importClass("java.net.DatagramPacket");

importClass("java.net.DatagramSocket");



// websocket全局对象,本地IP(用于终端验证)

let ws, localIP;

// 全局检测,ws服务端中断以后,需要重新自启组播服务,扫描服务用于子发现

let isConnect;



// 等待获取无障碍权限

auto.waitFor();


// 服务监控

let serverListenser = setInterval(function () {

   log("服务侦听…");

   initServer();

}, 3000);

// initServer();


//监听log事件,发送给服务端

events.broadcast.on("log", function (words) {

   try {

       if (!localIP) {

           localIP = getIntranetIP();

       }

       log(words);

       ws.send(JSON.stringify({ "type": "msg", "ip": localIP, "result": words }));

   } catch (err) {

       log(err);

   }

});



function initServer() {

   // 服务未连接

   if (isConnect != true) {

       // 临时暂停监听服务

       clearInterval(serverListenser);

       let ds = initDs();

       log("服务端发现…")

       while (true) {

           try {

               log("尝试通信…")

               // 发送组播消息,检测ws服务端口

               sendDs(ds, '255.255.255.255', 8061, JSON.stringify({ "type": "initAuto.js" }));

               // 等待消息响应

               let msg = getDsMsg(ds);

               log(msg);

               if (msg["msg"]["statues"] === "success") {

                   ds.close();

                   log("检测到服务,尝试链接…")

                   log("ws:/" + msg["ip"] + ":" + msg["msg"]["port"])

                   // 创建websocket链接

                   ws = initWs("ws:/" + msg["ip"] + ":" + msg["msg"]["port"] + "/worker");

                   // 服务器启动成功,更新标记位

                   isConnect = true;

                   log("链接成功!!")

                   // 重启监听服务

                   serverListenser = setInterval(function () {

                       initServer();

                   }, 3000);

                   break;

               }

           } catch (error) {

               log("未检测到服务…");

           }

       }

   }

}



// 创建组播

function initDs() {

   // 构造数据报套接字并将其绑定到本地主机上任何可用的端口

   log("初始化服务…")

   let ds = new DatagramSocket();

   ds.setBroadcast(true);

   return ds;

}


// 发送组播消息

function sendDs(ds, ip, port, msg) {

   ip = InetAddress.getByName(ip);

   let bts = new java.lang.String(msg).getBytes("UTF-8");

   ds.send(new DatagramPacket(bts, bts.length, ip, port));

}


// 接收组播消息

function getDsMsg(ds) {

   let bts = util.java.array('byte', 1024);

   let packet = new DatagramPacket(bts, bts.length);

   ds.setSoTimeout(2000);

   ds.receive(packet);

   return { "ip": packet.getAddress().toString(), "msg": JSON.parse(new java.lang.String(packet.getData(), 0, packet.getLength(), "UTF-8")) };

}

7

// 创建websocket

function initWs(url) {

   global

   let mClient = new OkHttpClient();

   let request = new Request.Builder().get().url(url).build();

   let globalWebsocket = null;


   mClient.newWebSocket(request, new JavaAdapter(WebSocketListener, {

       onOpen: function (webSocket, response) {

           globalWebsocket = webSocket;

       },

       onMessage: function (webSocket, text) {

           // 接收到消息后,这里转发到引擎执行脚本

           log("收到消息…");

           try {

               autojsHandle(text);

           } catch (error) {

               log(error);

               events.broadcast.emit('log', error + "");

           }


       },

       onClosed: function (webSocket, code, reason) {

           // 这里更新全局连接标记位,用于重新拉起服务检测

           isConnect = false;

           globalWebsocket = null;

           log("服务错误…");

           try {

               webSocket.close();

           } catch (error) {

               log(error);

           }

       },

       onFailure: function (webSocket, throwable, response) {

           isConnect = false;

           globalWebsocket = null;

           log("服务链接中断…");

           try {

               webSocket.close();

           } catch (error) {

               log(error);

           }

       }

   }));


   while (true) {

       try {

           if (globalWebsocket != null) {

               break;

           }

           sleep(1000)

       } catch (e) {

       }

   }

   return globalWebsocket;

}


function autojsHandle(text) {

   let msg = JSON.parse(text);

   // log(msg)

   // 所有的log都加上events.broadcast.emit("log",)来发送结果给websocket

   // msg["source"] = msg["source"].replace(/(log\(((?:['"]?).*\1)\)[;\n])/ig, "$1;events.broadcast.emit('log',$2);\n");

   msg["source"] = msg["source"].replace(/log\(/ig, "events.broadcast.emit(\"log\",");

   // log(msg);

   switch (msg["type"]) {

       case "main":

           eval(msg["source"]);

           break;

       default:

           engines.execScript(msg["title"], msg["source"], msg["config"]);

           break;

   }

}


function getIntranetIP() {

   // 获取所有网卡信息

   let networkInterfaces = NetworkInterface.getNetworkInterfaces();

   while (networkInterfaces.hasMoreElements()) {

       // 遍历网卡

       let networkInterface = networkInterfaces.nextElement();

       // 获取网卡地址

       let inetAddresses = networkInterface.getInetAddresses();

       while (inetAddresses.hasMoreElements()) {

           let inetAddress = inetAddresses.nextElement();

           // 判断网卡地址类型是不是IPV6,IPV6的舍弃

           if (inetAddress instanceof Inet6Address) {

               continue;

           }

           // 获取IP地址

           let ip = inetAddress.getHostAddress();

           // 非本地IP就绑定组播到网卡

           if (!"127.0.0.1".equals(ip)) {

               // 绑定网卡组播

               return ip;

           }

       }

   }

}


   服务端用python,udp广播服务,websocket服务端。打包成exe。

   服务端代码


# coding=utf-8

'''

Created on 2022年5月23日


@author: 瞌睡蟲子

'''

import asyncio

from http import client

import websockets

import json

import click



wsWorkerClents = set()

wsCommanderClents = set()

WS_PORT = None



class EchoServerProtocol:

   def connection_made(self, transport):

       self.transport = transport


   def datagram_received(self, data, addr):

       message = data.decode("utf-8")

       # print(message)

       message = json.loads(message)

       print('Received %r from %s' % (message, addr))

       if "type" in message and message["type"] == "initAuto.js":

           # 重新组合数据打印数据

           msg = json.dumps({"statues": "success", "port": WS_PORT})

           self.transport.sendto(msg.encode('utf-8'), addr)

       else:

           msg = json.dumps(

               {"statues": "error", "port": None, "msg": "type error"})

           self.transport.sendto(msg.encode('utf-8'), addr)



async def echo(websocket, path):

   # print(path)

   # print('%s:%d' % websocket.remote_address)

   cnt = '%s:%d' % websocket.remote_address

   if path == "/worker":

       print('[Worker %s] online' % (cnt))

       wsWorkerClents.add(websocket)

       try:

           async for message in websocket:

               print('[Worker %s] Received: %r' % (cnt, message))

               if wsCommanderClents:

                   [await user.send(message) for user in wsCommanderClents]

       except:

           print("[Worker %s] offline" % (cnt))

       finally:

           wsWorkerClents.remove(websocket)

   elif path == "/commander":

       print('[Commander %s] online' % (cnt))

       wsCommanderClents.add(websocket)

       try:

           async for message in websocket:

               print('[Commander %s] Received: %r' % (cnt, message))

               if wsWorkerClents:

                   [await user.send(message) for user in wsWorkerClents]

       except:

           print("[Commander %s] offline" % (cnt))

       finally:

           wsCommanderClents.remove(websocket)



@click.command()

@click.option('--port', default=5432, type=int, help='port of websocket server.')

def server(port):

   global WS_PORT

   WS_PORT = port


   loop = asyncio.get_event_loop()

   print("Starting server")

   # One protocol instance will be created to serve all client requests

   listen = loop.create_datagram_endpoint(

       EchoServerProtocol, local_addr=('0.0.0.0', 8061))

   transport, protocol = loop.run_until_complete(listen)


   wsServer = websockets.serve(echo, "0.0.0.0", port)

   loop.run_until_complete(wsServer)


   try:

       loop.run_forever()

   except:

       pass

   finally:

       transport.close()

       loop.close()



if __name__ == "__main__":

   server()


打包脚本入口:install.bat

@echo off


rem conda的python引擎库名字

set env=p38_x64


cd %~dp0

%~d0


conda create -n %env% python=3.7 && conda activate %env% && package.bat %env%

@echo package ok!!

pause


打包脚本:package.bat

@echo off

@echo package start...

echo %1

FOR /F "delims=/ tokens=1" %%i IN ('conda env list ^| find "%1"') DO @set pkg=%%i

SET PADDLEOCR_PATH=%pkg:~25%\Lib\site-packages

echo %PADDLEOCR_PATH%

SET CODE_PATH=%~dp0

echo %CODE_PATH%

cd %~dp0

%~d0


@REM pip install websockets

@REM pip install click

@REM pip install pyinstaller


pyinstaller -F --clean -y -i logo.ico autoServer.py


@echo package ok!!

pause


   uibot python插件,控制端。通过websocket发送autojs命令。


# coding=utf-8

'''

Created on 2022年5月23日


@author: 瞌睡蟲子

'''

from time import sleep

import websocket

import threading

import json

import os

import re

from queue import Queue

from os.path import join, dirname


q = Queue()

ws_port = None

ws_client = None



def on_message(ws, message):

   # print(message)

   message = json.loads(message)

   # if "message" in message:

   q.put(message)



def on_close(wss):

   global ws_port

   server(ws_port)

   print("### closed ###")



def server(port=5432):

   global ws_client

   global ws_port

   ws_port = port

   p = checkServer()

   if p == 0:

       cmd = "cd /d \"" + join(dirname(__file__), 'autoServer') + \

           "\"&start autoServer.exe --port " + str(port)

       print(cmd)

       os.system(cmd)

       sleep(2)

   websocket.enableTrace(True)

   ws_client = websocket.WebSocketApp(

       "ws://127.0.0.1:" + str(port) + "/commander", on_message=on_message, on_close=on_close)

   # ws.run_forever()

   threading.Thread(target=ws_client.run_forever, daemon=True).start()

   sleep(2)



def run(source, config={}, title="uibot.js", tp="main"):

   ws_client.send(json.dumps(

       {"source": source, "type": tp, "title": title, "config": config}))



def checkServer(pname="autoServer.exe"):

   data = _command("tasklist | findstr " + pname)

   if data == "":

       return 0

   print(data)

   data = re.findall("(\\d+)\\s+Console", data)

   print(data)

   for pid in data:

       temp = _command(

           "netstat -ano | findstr LISTENING | findstr " + pid + "$")

       if len(temp) > 0:

           temp = re.findall(

               "TCP\\s+[\\d.]+:(\\d+)\\s+[\\d.]+:\\d+\\s+LISTENING", temp)

           if len(temp) > 0:

               return int(temp[0])

   return 0



def _command(sCommand):

   with os.popen(sCommand, 'r') as f:

       res = f.read()

   return res



def getMsg(timeout=1000):

   # 获取执行结果的消息

   msg = None

   try:

       msg = q.get(True, timeout/1000)

   except Exception:

       msg = None

   return msg



if __name__ == "__main__":

   server()

   # run("log(\"你好\");")

   # print(q.get())

   # while True:

   # print(q.get())

   for i in range(1, 5):

       run("log('你好')")

       print(getMsg())

       sleep(1)

   # print(checkServer())


只做了基础框架,没有做任何安全方面设计。