admin管理员组

文章数量:1639684

使用场景

加密autojs

感谢群内大佬指点

@Tsing Yi @沐泠 @ProjectXero @抠脚本人 @I’m zz 等

效果展示



autojs版本

本教程大概的加密步骤

  1. js转dex
  2. 压缩项目
  3. 切割项目, 文件名用 . 开头, 使其不可见
  4. 创建新的入口文件和project.json
  5. 混淆入口文件

以上步骤均使用autojs一键完成

不需要电脑, 除非你想要修改加密方法,

跑通本加密工程, 只需要替换你的工程名字即可, 其他的都不用动

就可以一键完成

let projectName = "autojs-dex-first";
let projectDir = files.join(files.getSdcardPath(), "脚本", projectName);

js转dex原理

js --> class --> jar --> dex

步骤

  1. js --> class

    let filePath = "/sdcard/脚本/yashu.js";
    if (!files.exists(filePath)) {
      throw new Error("文件不存在: " + filePath);
    }
    // class文件所在文件夹
    let dir = "/sdcard/脚本/ayashu";
    files.create(dir + "/");
    args = ["-version", "200", "-opt", "1", "-encoding", "UTF-8", "-nosource", "-o", "yashu", "-d", dir, filePath];
    org.mozilla.javascript.tools.jsc.Main.main(args);
    toastLog("js转class完成");
    

    各个菜单的意思, 请查看Rhino官网文档

    https://developer.mozilla/en-US/docs/Mozilla/Projects/Rhino/JavaScript_Compiler

    https://developer.mozilla/en-US/docs/Mozilla/Projects/Rhino/Optimization

  1. class --> jar

    let classFilePath = "/sdcard/脚本/ayashu/yashu.class";
    let jarFilePath = "/sdcard/脚本/ayashu/yashu.jar";
    let r = zipFile(classFilePath, jarFilePath);
    log(r);
    
    function zipFile(classFilePath, jarFilePath) {
      jarFilePath = new java.io.File(jarFilePath);
      jarFilePath.delete();
      var mArrayList = new java.util.ArrayList();
      mArrayList.add(new java.io.File(classFilePath));
      new net.lingala.zip4j.core.ZipFile(jarFilePath).addFiles(mArrayList, new net.lingala.zip4j.model.ZipParameters());
      return jarFilePath;
    }
    
  2. jar --> dex
    去maven官网下载dx.jar, 该文件可以把jar转为dex

    https://mvnrepository/artifact/com.google.android.tools/dx/1.7

    let jarFilePath = "/sdcard/脚本/ayashu/yashu.jar";
    let dexFilePath = "/sdcard/脚本/ayashu/yashu.dex";
    com.android.dx.command.Main.main(["--dex", "--output", dexFilePath, jarFilePath]);
    

js调用dex化的js文件

js文件分为两种

  • 普通文件
  • 模块文件

普通dex文件的调用, 文件入口一般就是这种形式

let dexFilePath = "/sdcard/脚本/ayashu/yashu.dex";
runtime.loadDex(dexFilePath);
new Packages["yashu"]()();

模块dex文件调用

假设模块文件是yashu.js, 文件内容为

module.exports = {
  hello: (name) => {
    toastLog("hello" + name);
  },
};

调用模块方法

let dexFilePath = "/sdcard/脚本/ayashu/yashu.dex";
runtime.loadDex(dexFilePath);
new Packages["yashu"]()();

没错, 跟普通dex文件调用一样样的, 只是要在引入用的地方requrie一下

main.js, 文件内容如下

let yashu = require("./ysshu");
aaa.hello("牙叔");

以上是单个js文件变为dex的方法, 下面我们来详细看看dex加密一个项目

dex加密项目

1. 初始化一些工具类

let yashuUtil = require("./yashuUtil");
let js2class = require("./dex加密三步曲/js2class");
let class2jar = require("./dex加密三步曲/class2jar");
let jar2dex = require("./dex加密三步曲/jar2dex");

2. 备份项目

yashuUtil.backupProject(projectDir);

3. 提取项目文件中所有js文件

let jsFilePathList = yashuUtil.getJsFilePathList(projectDir);

4, 批量将js转为dex

jsFilePathList.map((filepath) => {
  changeJsFileToDexFile(filepath);
});

5. 压缩项目

let encryptedZipFile = yashuUtil.compressProject();

6. 切割文件

let childFilePathList = yashuUtil.separateFile(encryptedZipFile);

7. 移除多余文件

yashuUtil.finalRemoveIntermediateFile(jsFilePathList);

8. 创建新的mainDex文件

yashuUtil.createMainDex(childFilePathList, encryptedZipFile, projectDir, changeJsFileToDexFile);

9. 创建新的project.json文件

yashuUtil.createNewProject(projectDir);

10. 加密完成

toastLog("牙叔加密完成");
alert("牙叔加密完成");

经过以上步骤, 我们的项目就加密完成了,

项目文件压缩包被切割, 合并函数在入口文件中,

我们来加密入口文件, 也就是上面的第8个步骤: 创建新的mainDex文件

加密入口文件

1. 入口文件原始内容

eval("runtime.unloadAll(true);");
let encryptedZipFile = "===encryptedZipFile===";
let filePathList = "===filePathList===";

mergeFile(filePathList, encryptedZipFile);
let zipOutDir = unzipProject(encryptedZipFile);

let scriptFilePath = files.join(zipOutDir, "===projectName===", "main.js");

engines.execScriptFile(scriptFilePath, { path: getDir(scriptFilePath) });

2. 我们先使用UglifyJS压缩一下

// UglifyJS online

// https://skalman.github.io/UglifyJS-online/

// https://andrewsun/tools/javascript-minifier/

上面两个都可以, 第一个访问速度快一点;

如果网站无法访问, 请关掉代理, 或者更改host;

host需要域名和ip对应

域名查ip

http://ping.chinaz/dl.google

UglifyJS压缩后的代码

eval("runtime.unloadAll(true);");let encryptedZipFile="===encryptedZipFile===",filePathList="===filePathList===";mergeFile(filePathList,encryptedZipFile);let zipOutDir=unzipProject(encryptedZipFile),scriptFilePath=files.join(zipOutDir,"===projectName===","main.js");function getDir(e){let i=e.split("/");return i.splice(-1,1),i.join("/")}function unzipProject(e,i,t){return i=i||"yashu",t=t||context.getCacheDir(),$zip.unzip(e,t+"/",{password:i}),t}function mergeFile(e,i){e=e.map(e=>new java.io.File(files.path(e))),files.createWithDirs(i);let t=new java.io.BufferedOutputStream(new java.io.FileOutputStream(i)),r=null,a=util.java.array("byte",1048576),l=-1;for(let i=0;i<e.length;i++)for(r=new java.io.BufferedInputStream(new java.io.FileInputStream(e[i]));-1!=(l=r.read(a));)t.write(a,0,l);return r.close(),t.close(),i}engines.execScriptFile(scriptFilePath,{path:getDir(scriptFilePath)});

3. 我们再使用webpack混淆一下

开源项目 webpack-autojs

https://github/snailuncle/webpack-autojs

webpack混淆后的代码

var _0x1879=['object','create','default','bind','hasOwnProperty','unloadAll','===encryptedZipFile===','join','===projectName===','split','yashu','getCacheDir','File','path','createWithDirs','BufferedOutputStream','FileOutputStream','java','array','length','BufferedInputStream','FileInputStream','write','close','exports','call','undefined','toStringTag','defineProperty','__esModule'];(function(_0x845909,_0x258a15){var _0x3f0090=function(_0x4164fc){while(--_0x4164fc){_0x845909['push'](_0x845909['shift']
......
[(_0x3943('0x1b'))](_0x1e78de[_0x426513]));-0x1!=(_0x551275=_0x5359bc['read'](_0x27360d));)_0x5c2c80[_0x3943('0x1c')](_0x27360d,0x0,_0x551275);return _0x5359bc[_0x3943('0x1d')](),_0x5c2c80[_0x3943('0x1d')](),_0x426513;}engines['execScriptFile'](_0xdf190b,{'path':_0x353d18(_0xdf190b)});}]);

上面的混淆效果对应的配置文件scriptConfig.js

var config = {
  uiMode: false,
  entry: entry,
  scriptNamePrefix: "",
  base64: false,
  advancedEngines: true,
  base64RandomStrLength: 100,
  target: "node", // web || node
};

4. 替换一些变量, 为生成新的入口文件做准备

  str = str
    .replace("===encryptedZipFile===", encryptedZipFile)
    .replace("===projectName===", projectName)
    .replace('"===filePathList==="', JSON.stringify(childFilePathList));

5. 生成新的入口文件

  let newMainFilePath = files.join(projectDir, "yashu.js");
  files.write(newMainFilePath, str);
  changeJsFileToDexFile(newMainFilePath);

经过上面的操作, 我们的入口文件就不是明文了

小技巧

在创建新的入口文件时, 我们要用js处理webpack混淆过的js代码,

要将整个文件内容放到代码里, 替换一些变量字符串,

但是混淆过的代码各种符号都有, 我们可以使用typescript快速将一段代码变为字符串

比如我们要把以下代码变为字符串

_0x5359bc[_0x3943("0x1d")](),_0x5c2c80[_0x3943('0x1d')]()

两边加双引号是不行的, 因为代码本身就有单引号, 也有双引号

口当口当口当, 技巧来了

首先我们新建一个ts文件1.ts

let str = `
`; // 这是反引号

再把上面混淆的代码放到反引号中间

let str = `
_0x5359bc[_0x3943("0x1d")](),_0x5c2c80[_0x3943('0x1d')]()
`; // 这是反引号

然后在中断输入以下代码

(tsc是需要配置typescript环境, 请百度ts教程)

tsc 1.ts

运行之后, 就生成1个1.js文件, 文件内容

var str = "\n_0x5359bc[_0x3943(\"0x1d\")](),_0x5c2c80[_0x3943('0x1d')]()\n"; // 这是反引号

经过以上步骤, 我们就可以把代码变为字符串了

总结

经过以上加密, 就可以防止小白破解了,

加密方式公开了, 就不安全了,

自己想办法加强吧

声明

部分内容来自网络

加密工程完整源码下载


微信公众号 AutoJsPro教程

QQ群

747748653

本文标签: 一键autojs