一次autojs加密脚本的探秘,附代码

本帖最后由 s1986q 于 2019-6-24 19:59 编辑

先用压缩打开目标apk,



在assets/project/project.json
[JavaScript] 纯文本查看 复制代码

{"assets": [],
  "build": {
    "build_number": 1,
    "build_time": 1553954524212,
    "build_id": "A117A8CD-1"
  },
  "encryptLevel": 1,
  "useFeatures": [],
  "icon": "res/icon.png",
  "launchConfig": {
    "displaySplash": true,
    "hideLogs": false,
    "splashIcon": "res/splashIcon.png",
    "splashText": "Powered by Auto.js Pro"
  },
  "mainScriptFile": "main.js",
  "name": "xxxxxxxx",
  "optimization": {
    "removeOpenCv": true,
    "unusedResources": false
  },
  "packageName": "com.example.xmbd",
  "scripts": {},
  "versionCode": 1,
  "versionName": "1.0.0"
}

main.js 加密
encryptLevel关键字:encrypt
定位到
com.stardust.autojs.project.ProjectConfig.toString;
[Java] 纯文本查看 复制代码

final public String ProjectConfig.toString()        //method@66d4
{
     return "ProjectConfig(name="+this.name+", versionName="+this.versionName+", versionCode="+this.versionCode+", packageName="+this.packageName+", mainScriptFile="+this.mainScriptFile+", assets="+this.assets+", launchConfig="+this.launchConfig+", buildInfo="+this.buildInfo+", icon="+this.icon+", scriptConfigs="+this.scriptConfigs+", features="+this.features+", optimization="+this.optimization+", encryptLevel="+this.encryptLevel+")";
}

找不函数
搜索方法名:encrypt
一步到位:com.stardust.autojs.engine.encryption.ScriptEncryption.encrypt.ScriptEncryption
有个方法:
[Java] 纯文本查看 复制代码

final public byte[] ScriptEncryption.encrypt(byte[] p0)        //method@6568
{
     g.b(p0, "bytes");
     p0 = new a(ScriptEncryption.mKey, ScriptEncryption.mInitVector).a(p0);
     return p0;
}

向下跟踪一下:
[Java] 纯文本查看 复制代码

final public byte[] a.a(byte[] p0)        //method@6d87
{
     g.b(p0, "plainText");
     SecretKeySpec v0 = new SecretKeySpec(this.a, "AES");
     Cipher v1 = Cipher.getInstance("AES/CBC/PKCS7Padding");
     String v2 = this.b;
     Charset v3 = d.a;
     if (v2) {        
         byte[] v2_1 = v2.getBytes(v3);
         g.a(v2_1, "(this as java.lang.String).getBytes(charset)");
         v1.init(1, v0, new IvParameterSpec(v2_1));
         p0 = v1.doFinal(p0);
         g.a(p0, "cipher.doFinal(plainText)");
         return p0;
     }        
     p0 = new d("null cannot be cast to non-null type java.lang.String");
     throw p0;
}

用反射调用,一路的小问题:
参数是用frIDA得到的:
[JavaScript] 纯文本查看 复制代码

        
Java.perform(function () {
    function bytesToString(bytes) {
        var str="";
        for (var i = 0; i < bytes.length; i++) {
                str += (bytes[i]&0xFF).toString(10)+",";
        }
        return str;
    }
            var a = Java.use('javax.crypto.Cipher');
        console.log(a);
            a.doFinal.overload('[B').implementation=function(p1){
                    console.log(bytesToString(p1));
                    return p1;
            };
 });

得到key
[JavaScript] 纯文本查看 复制代码

Java.perform(function () {
    function bytesToString(bytes) {
        var str="";
        for (var i = 0; i < bytes.length; i++) {
                str += (bytes[i]&0xFF);
        }
        return str;
    }
            var a = Java.use('com.stardust.util.a');
        console.log(a);
            a.$init.overload('[B','java.lang.String').implementation=function(){
                    console.log(bytesToString(this.a));
                    console.log(this.b);
            };
 });

得到mInitVector
[Java] 纯文本查看 复制代码

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;

import com.stardust.autojs.engine.encryption.ScriptEncryption;
public class gfghgj {
        public static void main(String[] args) {
                ScriptEncryption g=ScriptEncryption.INSTANCE;
                 Class<?> f = null;
                try {
                        f = Class.forName("com.stardust.autojs.engine.encryption.ScriptEncryption");
                } catch (ClassNotFoundException e2) {
                        // TODO Auto-generated catch block
                        e2.printStackTrace();
                }
                String mInitVector="2e853092f35c71a9";
                 byte[] mKey = new byte[]{99,49,50,57,99,102,97,101,56,100,101,100,52,98,56,98};
                try {
                        //Field f1 = f.getField("mInitVector");
                        Field f2 = f.getDeclaredField("mKey");
                        try {
                                //f1.set(f,mInitVector);
                                f2.setAccessible(true);
                                f2.set(g,mKey);
                                
                        } catch (IllegalArgumentException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        } catch (IllegalAccessException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
                } catch (NoSuchFieldException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                } catch (SecurityException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                }
                byte[] aa = null;
                try {
                        aa = getContent("C:/main.js");
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                byte[] bb = g.decrypt(aa,8,aa.length);
                try {
                        createFile("C:/main11.js", bb);
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
        public static void createFile(String path, byte[] content) throws IOException {
                         FileOutputStream fos = new FileOutputStream(path);
                 
                         fos.write(content);
                         fos.close();
    }
             public static byte[] getContent(String filePath) throws IOException
             {
                 FileInputStream in=new FileInputStream(filePath);
                 
                 ByteArrayOutputStream out=new ByteArrayOutputStream(1024);
                 
                 System.out.println("bytes available:"+in.available());
                 
                 byte[] temp=new byte[1024];
                 
                 int size=0;
                 
                 while((size=in.read(temp))!=-1)
                 {
                     out.write(temp,0,size);
                 }
                 
                 in.close();
                 
                 byte[] bytes=out.toByteArray();
                 System.out.println("bytes size got is:"+bytes.length);
                 
                 return bytes;
             }
}

未成功,java8 不支持解密类型
手机不报错,没内容。
既然已经搭建frida,hook encrypt函数(加密js,解密的开始位置,加密js的数据长度)
gda反编译的不一样
用jd-gui反编译
[Java] 纯文本查看 复制代码

public final byte[] decrypt(byte[] paramArrayOfByte, int paramInt1, int paramInt2)

写frida hook脚本
不会看例子,看官网的文档
返回值是解密的js脚本
send了好几次
看到了16进制的字符串,高兴

python文件太长后面补:链接

frida 脚本太长后面补:链接
例子可以到
https://pan.baidu.com/s/1zyq1mw1C9NnyksEXjllqFQ
7kmc
autojsjiemi.zip
开始是用小程序写的
用autojs写的
bingdu.zip

bingdu.zip

2019-6-24 19:48 上传

点击文件名下载附件

下载积分: 吾爱币 -1 CB

1.98 KB, 下载次数: 0, 下载积分: 吾爱币 -1 CB

autojsjiemi.zip

2019-6-24 19:20 上传

点击文件名下载附件

下载积分: 吾爱币 -1 CB

3.26 KB, 下载次数: 2, 下载积分: 吾爱币 -1 CB

THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
  • 管埋员

    昵称

  • 取消
    昵称