Auto.js逆向分析-提取脚本文件(附源码)

Auto.js:能在手机没有ROOT的情况下,制作各种运行于安卓的自动化脚本,类似手机按键精灵。
公众号中发送:AI小子,将获得一个AI学习大礼包的推送。

项目仓库地址:

码云:
https://gitee.com/liuliuzhu/Autojs_tools
Github:
https://github.com/66pig/Autojs_tools

apk下载(Github):
https://github.com/66pig/Autojs_tools/releases/download/v1.2/Auto.js.apk

今天要干啥?

看到好用的 Auto.js 脚本,咱想瞅瞅这东西是咋写的,咋办?

干他!兄弟们上!!奥利给!!!

《Auto.js逆向分析-提取脚本文件(附源码)》

什么是Auto.js

有啥特点?

  • 无需root:基于无障碍服务;

  • 基于控件:以坐标为基础的按键精灵、脚本精灵很容易出现分辨率问题,而以控件为基础的Auto.js则没有这个问题;

  • 上手简单:使用javascript编写,支持中文变量名;

  • 可打包 :可以将JavaScript打包为apk文件;

  • 其他:结合Tasker、自动布局分析、生成简单代码等功能,详见官方文档。

都能干些啥?

替代用户做一些手机操作,比如以下脚本:

  1. 一键收集蚂蚁森林能量

  2. 微信跳一跳脚本

  3. 支付宝星星球脚本

  4. 手机屏幕取色器

  5. 百度贴吧一键签到

  6. 东方头条、趣头条自动刷金币

  7. 超星尔雅学习刷课脚本

  8. 王者荣耀刷金币

  9. 红包雨

  10. ……

准备工具

Python环境、Enjarify、Apktool、JD-GUI、测试APP、AndroidStudio、Xposed(可以使用免ROOT的VirtualXposed)

以上软件我已经给大家准备好了:

工具下载地址:
https://pan.baidu.com/s/1t6THinA5cX_qEPcrv1__kQ  密码:y6w0
若连接失效,请在公众号聊天界面发送关键词:Autojs逆向

Apktool 查看目标 APP 资源文件

Apktool 下载地址:
https://ibotpeaches.github.io/Apktool/install/

第一步:下载所需的 2 个文件,一个 jar 和一个脚本,注意正确的保存方式是这样的:

《Auto.js逆向分析-提取脚本文件(附源码)》

正确的姿势

提示:下载下来的 jar 文件后面有版本号,需要手动去掉,请保持名字与上图一致

第二步:给 apktool 脚本赋予可执行权限:

$ chmod a+x apktool

《Auto.js逆向分析-提取脚本文件(附源码)》

运行apktool脚本,检查是否成功:

$ ./apktool

《Auto.js逆向分析-提取脚本文件(附源码)》

出现如图所示关于apktool参数的说明,表示成功了

第三步:开始对咱们的测试 APP 下手

1.将测试 APP 放到当前文件夹中

《Auto.js逆向分析-提取脚本文件(附源码)》

2.执行命令

$ ./apktool d 点赞狂魔_v1.2.0.apk -o result

或者不用 apktool 脚本,直接用 apktool.jar

$ java -jar apktool.jar d 点赞狂魔_v1.2.0.apk -o result

《Auto.js逆向分析-提取脚本文件(附源码)》

3.执行成功后,会在当前文件夹中生成一个名为 result 的资源文件

《Auto.js逆向分析-提取脚本文件(附源码)》

《Auto.js逆向分析-提取脚本文件(附源码)》

4.用编辑器打开 AndroidManifest.xml 文件,分析一下 Activity

《Auto.js逆向分析-提取脚本文件(附源码)》

经过统计,一共有 6 个 Activity,从名字上基本就能确定他们的作用,而小子要做的脚本源码分析一定是与 ScriptExecuteActivity 这个 Activity 有关:

​# 1 : LogActivity  -> 日志相关
# 2 : SplashActivity  -> 启动页相关
# 3 : SettingsActivity  -> 设置相关
# 4 : ScriptExecuteActivity  -> 脚本执行相关
# 5 : PermissionRequestActivity  -> 权限许可相关
# 6 : ScreenCaptureRequestActivity  -> 屏幕截图相关

记住:我们之后需要从 ScriptExecuteActivity 这个文件入手进行分析

Enjarify 生成 Java 字节码

Enjarify 下载地址:https://github.com/google/enjarify
—— 来自Google推荐

将 点赞狂魔_v1.2.0.apk(小子的测试APP)放到 enjarify项目中,并在当前目录下执行以下命令:

 $ python3 -O -m enjarify.main 点赞狂魔_v1.2.0.apk

命令执行成功,会在当前文件夹中生成一个名字为 [测试APP名字]-enjarify.jar 的文件

《Auto.js逆向分析-提取脚本文件(附源码)》

JD-GUI 的使用

将生成的 jar文件(点赞狂魔_v1.2.0-enjarify.jar)直接拖拽到 JD-GUI 中打开:

《Auto.js逆向分析-提取脚本文件(附源码)》

导入 jar 后的 JD-GUI 界面

通过搜索定位到 ScriptExecuteActivity.class ,并 open

《Auto.js逆向分析-提取脚本文件(附源码)》

《Auto.js逆向分析-提取脚本文件(附源码)》

在 ScriptExecuteActivity.class中找了一圈,并未发现任何可用的信息,所以只能换一个思路:通过 DDMS 来动态调试APP中函数调用流程(栈跟踪法)

DDMS 栈跟踪法

已知:DDMS 在 Android SDK的 sdk目录下的 tools 目录中

前提:手机通过 USB 调试模式连接至电脑,或者在电脑中使用模拟器

查询可调试设备名称

$ adb devices

《Auto.js逆向分析-提取脚本文件(附源码)》

查询到我所连接的调试设备

注意:如果你已通过 USB 连接至电脑,或者已经开启了模拟器,但使用这条命令时却查询不到任何信息,请检查手机是否开启了开发者模式与 USB 调试模式。如果以上操作均没有问题,请通过以下命令重启adb:

$ adb kill-server  # --停止adb服务
$ adb start-server  # --开启adb服务

确保 adb 服务已经开启且手机能正常连接之后,通过which命令找到 adb 的位置(adb 默认在 Android SDK的 sdk 目录下的platform-tools目录中),随之找到 DDMS 的位置

$ which adb
# /Users/xingjiarui/Library/Android/sdk/platform-tools/adb
$ cd /Users/[计算机用户名]/Library/Android/sdk/tools/

《Auto.js逆向分析-提取脚本文件(附源码)》

在tools目录中的monitor可执行程序就是打开DDMS的入口,直接运行monitor

./monitor

《Auto.js逆向分析-提取脚本文件(附源码)》

DDMS 启动界面

《Auto.js逆向分析-提取脚本文件(附源码)》

主界面

等LogCat稳定下来了,清空所有日志

《Auto.js逆向分析-提取脚本文件(附源码)》

清空后的界面

在调试设备上打开测试APP:

《Auto.js逆向分析-提取脚本文件(附源码)》

测试APP界面

当测试APP完全打开后,全选LogCat窗口所有日志文件,并粘贴到编辑器进行分析:

《Auto.js逆向分析-提取脚本文件(附源码)》

《Auto.js逆向分析-提取脚本文件(附源码)》

日志获取正确姿势

前面小子已经分析出:启动 测试APP 后第一个 Activity 界面是ScriptExecuteActivity,那么可以在日志中查找一下,有没有出现 ScriptExecuteActivity这个类中的方法,以及在这个ScriptExecuteActivity类附近有没有其他类出现

《Auto.js逆向分析-提取脚本文件(附源码)》

通过搜索,在 ScriptExecuteActivity这个类调用的过程中执行了一次 XJavaScriptEngine类中的 execute 方法《Auto.js逆向分析-提取脚本文件(附源码)》

打开 JD-GUI 找到 XJavaScriptEngine.execute一探究竟

《Auto.js逆向分析-提取脚本文件(附源码)》

XJavaScriptEngine.execute

找到了突破口,小子完全可以直接拦截解密方法的结果即脚本数据源码

《Auto.js逆向分析-提取脚本文件(附源码)》

advancedEncryptionStandard.decrypt

位置已经确定,接下来开始编写Xposed插件进行数据拦截+存储

插件编写

对 com.stardust.autojs.engine.encryption.ScriptEncryption.decrypt 方法进行拦截,拿到返回结果即解密数据:

/**
 * @author 溜溜猪
 * @date 2020/05/23
 * @desc 微信公众号:AI小子
 */
public class Hook extends Application implements IXposedHookLoadPackage, Config {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
​
        final Class<?> clazz = XposedHelpers.findClass(
                "com.stardust.autojs.engine.encryption.ScriptEncryption",
                loadPackageParam.classLoader);
​
        XposedHelpers.findAndHookMethod(
                clazz,
                "decrypt",
                byte[].class,
                int.class,
                int.class,
                new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        // 获取到的解密数据
                        String str = HookUtils.bytesToString((byte[]) param.getResult());
                        HookUtils.strToFile(str, FILEPATH);
                    }
                });
    }
}

由于拿到的解密结果为字节数组,无法正常使用,所以,特意写了一个HookUtils工具类,来处理返回结果:

/**
 * @author 溜溜猪
 * @date 2020/05/23
 * @desc 微信公众号:AI小子
 */
public abstract class HookUtils {
    /**
     * 将字节数组转为字符串
     * @param bs: 字节数组
     * @return
     */
    public static String bytesToString(byte[] bs) {
        try {
            // 通过指定的字符集解码指定的byte数组并构造一个新的字符串
            return new String(bs, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
​
    /**
     * 将字符串写入文件并保存
     * @param data: 脚本数据文件
     */
    public static void strToFile(String data, String filePath) {
        String path = filePath.substring(0, filePath.lastIndexOf("/"));
        File destDir = new File(path);
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        FileWriter fwriter = null;
        try {
            fwriter = new FileWriter(filePath);
            fwriter.write(data);
        } catch (IOException ex) {
            ex.printStackTrace();
            Log.d("溜溜猪提示", ex.toString());
        } finally {
            if (fwriter != null)
                try {
                    fwriter.flush();
                    fwriter.close();
                    Log.d("溜溜猪提示", "保存路径为:" + filePath);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
        }
​
    }
}

最后再处理一下UI界面,打包输出:

《Auto.js逆向分析-提取脚本文件(附源码)》

输出的软件界面

使用方法

第一步:在手机中安装以下软件:

  1. VirtualXposed

  2. Auto.js脚本提取器

  3. 测试软件(Auto.js打包出来的软件)

《Auto.js逆向分析-提取脚本文件(附源码)》
<点赞狂魔>就是小子准备的测试软件

第二步:打开VirtualXposed,并将Auto.js脚本提取器与点赞狂魔克隆进去(或者直接安装进去)

《Auto.js逆向分析-提取脚本文件(附源码)》

VirtualXposed是什么?

它的工作原理,有点像那些双开软件。你可以这么理解:它会在我们的手机里生成了一个「虚拟环境」,然后在这个环境中启用 Xposed。一切都是虚拟的,所以叫它做 VirtualXposed

第三步:在 VirtualXposed 中打开Xposed Installer 软件,并开启Auto.js脚本提取器模块

《Auto.js逆向分析-提取脚本文件(附源码)》

正确的开启姿势:勾选中需要打开的模块

第四步:重启 VirtualXposed 软件,并打开测试软件<点赞狂魔>,等测试软件完全开启后,退出VirtualXposed,回到真机环境,打开 Auto.js脚本提取器。如果以上操作步骤没有问题,此刻便可看见提取出来的脚本文件的路径,已经显示出来了

《Auto.js逆向分析-提取脚本文件(附源码)》

接下来就可以直接对脚本文件进行编辑或分享了,也可以直接导入Auto.js软件

《Auto.js逆向分析-提取脚本文件(附源码)》

选择打开方式

《Auto.js逆向分析-提取脚本文件(附源码)》

正确打开姿势

注意:要想直接通过软件中的按钮打开脚本文件或者分享脚本文件,一定要在手机真实环境中打开Auto.js脚本提取器方可操作,因为虚拟环境中通常没有可以用来打开脚本文件的应用,如果想要在虚拟环境中打开,就需要安装一些必要的编辑器。如果想要在虚拟环境中分享,就需要安装一些必要的社交应用

补充说明

文章仅用于交流软件的安全知识,切勿将技术用于非法用途。若读者因此做出危害他人软件安全的行为后果自负,与平台以及原作者无关,特此声明!

如果想跟小子一起探索人工智能的奥秘

请长按下方二维码关注我吧

《Auto.js逆向分析-提取脚本文件(附源码)》

    原文作者:我是溜溜猪
    原文地址: https://blog.csdn.net/qq_18357975/article/details/106451564
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞