top

微信小程序代码混淆(代码被扒盗用上架,如何保证代码安全)

写在前面的话
小编前段时间刷博客的时候看到了一篇这样的文章,大概的内容是开发者辛辛苦苦开发小半年的作品,上线没几天,就被人盗版上线了,甚至连代码都是扒的自己的,有兴趣的朋友可以去看看。点我查看

至于说怎么去扒微信小程序的源码,小编在这里不做过多的阐述,自行百度“小程序代码反编译

今天咱们来讲讲如何在提交审核之前,给自己的小程序代码做混淆,代码安全加固。

核心思路

  • javascript-obfuscator对小程序的代码进行混淆
  • bat脚本对项目下所有的js文件进行混淆操作

首先咱们来介绍一下javascript-obfuscator

在百度上对它的定义是这样的“javascript-obfuscator是一个免费的JavaScript代码混淆工具,它功能强大,可以把你的源代码变得“面目全非”,完全没有可读性。还具有部分防调试功能,给JavaScript代码多一层保护。”

事实上也确实是这样,小编通过它来对项目进行混淆之后,代码的可读性变得极其差。

const a0_0x1cf1 = ['getStorageSync', 'scope.userInfo', 'getSystemInfo', 'now', 'userInfo', 'unshift', 'getSystemInfo:ok', 'log', 'getSetting', 'logs', 'setStorageSync', 'systemInfo', 'userInfoReadyCallback', 'authSetting', 'errMsg'];
(function (_0x371ccf, _0x1cf103) {
const _0x5d052b = function (_0x13fa3f) {
while (--_0x13fa3f) {
_0x371ccf['push'](_0x371ccf['shift']());
}
};
_0x5d052b(++_0x1cf103);
}(a0_0x1cf1, 0x14b));
const a0_0x5d05 = function (_0x371ccf, _0x1cf103) {
_0x371ccf = _0x371ccf - 0x0;
let _0x5d052b = a0_0x1cf1[_0x371ccf];
return _0x5d052b;
};
App({
'onLaunch': function () {
let _0x2e1d11 = this;
var _0x451dd8 = wx[a0_0x5d05('0xe')]('logs') || [];
_0x451dd8[a0_0x5d05('0x4')](Date[a0_0x5d05('0x2')]()), wx[a0_0x5d05('0x9')](a0_0x5d05('0x8'), _0x451dd8), wx[a0_0x5d05('0x1')]({
'complete': _0x1f36a4 => {
console[a0_0x5d05('0x6')](_0x1f36a4, a0_0x5d05('0x1')), (_0x1f36a4[a0_0x5d05('0xd')] = a0_0x5d05('0x5')) && (_0x2e1d11[a0_0x5d05('0xa')] = _0x1f36a4);
}
}), wx[a0_0x5d05('0x7')]({
'success': _0x3eebf4 => {
_0x3eebf4[a0_0x5d05('0xc')][a0_0x5d05('0x0')] && wx['getUserInfo']({
'success': _0x306423 => {
this['globalData'][a0_0x5d05('0x3')] = _0x306423[a0_0x5d05('0x3')], this[a0_0x5d05('0xb')] && this['userInfoReadyCallback'](_0x306423);
}
});
}
});
},
'globalData': {
'userInfo': null
},
'systemInfo': {}
});
const a0_0x1cf1 = ['getStorageSync', 'scope.userInfo', 'getSystemInfo', 'now', 'userInfo', 'unshift', 'getSystemInfo:ok', 'log', 'getSetting', 'logs', 'setStorageSync', 'systemInfo', 'userInfoReadyCallback', 'authSetting', 'errMsg']; (function (_0x371ccf, _0x1cf103) { const _0x5d052b = function (_0x13fa3f) { while (--_0x13fa3f) { _0x371ccf['push'](_0x371ccf['shift']()); } }; _0x5d052b(++_0x1cf103); }(a0_0x1cf1, 0x14b)); const a0_0x5d05 = function (_0x371ccf, _0x1cf103) { _0x371ccf = _0x371ccf - 0x0; let _0x5d052b = a0_0x1cf1[_0x371ccf]; return _0x5d052b; }; App({ 'onLaunch': function () { let _0x2e1d11 = this; var _0x451dd8 = wx[a0_0x5d05('0xe')]('logs') || []; _0x451dd8[a0_0x5d05('0x4')](Date[a0_0x5d05('0x2')]()), wx[a0_0x5d05('0x9')](a0_0x5d05('0x8'), _0x451dd8), wx[a0_0x5d05('0x1')]({ 'complete': _0x1f36a4 => { console[a0_0x5d05('0x6')](_0x1f36a4, a0_0x5d05('0x1')), (_0x1f36a4[a0_0x5d05('0xd')] = a0_0x5d05('0x5')) && (_0x2e1d11[a0_0x5d05('0xa')] = _0x1f36a4); } }), wx[a0_0x5d05('0x7')]({ 'success': _0x3eebf4 => { _0x3eebf4[a0_0x5d05('0xc')][a0_0x5d05('0x0')] && wx['getUserInfo']({ 'success': _0x306423 => { this['globalData'][a0_0x5d05('0x3')] = _0x306423[a0_0x5d05('0x3')], this[a0_0x5d05('0xb')] && this['userInfoReadyCallback'](_0x306423); } }); } }); }, 'globalData': { 'userInfo': null }, 'systemInfo': {} });
const a0_0x1cf1 = ['getStorageSync', 'scope.userInfo', 'getSystemInfo', 'now', 'userInfo', 'unshift', 'getSystemInfo:ok', 'log', 'getSetting', 'logs', 'setStorageSync', 'systemInfo', 'userInfoReadyCallback', 'authSetting', 'errMsg'];
(function (_0x371ccf, _0x1cf103) {
  const _0x5d052b = function (_0x13fa3f) {
    while (--_0x13fa3f) {
      _0x371ccf['push'](_0x371ccf['shift']());
    }
  };
  _0x5d052b(++_0x1cf103);
}(a0_0x1cf1, 0x14b));
const a0_0x5d05 = function (_0x371ccf, _0x1cf103) {
  _0x371ccf = _0x371ccf - 0x0;
  let _0x5d052b = a0_0x1cf1[_0x371ccf];
  return _0x5d052b;
};
App({
  'onLaunch': function () {
    let _0x2e1d11 = this;
    var _0x451dd8 = wx[a0_0x5d05('0xe')]('logs') || [];
    _0x451dd8[a0_0x5d05('0x4')](Date[a0_0x5d05('0x2')]()), wx[a0_0x5d05('0x9')](a0_0x5d05('0x8'), _0x451dd8), wx[a0_0x5d05('0x1')]({
      'complete': _0x1f36a4 => {
        console[a0_0x5d05('0x6')](_0x1f36a4, a0_0x5d05('0x1')), (_0x1f36a4[a0_0x5d05('0xd')] = a0_0x5d05('0x5')) && (_0x2e1d11[a0_0x5d05('0xa')] = _0x1f36a4);
      }
    }), wx[a0_0x5d05('0x7')]({
      'success': _0x3eebf4 => {
        _0x3eebf4[a0_0x5d05('0xc')][a0_0x5d05('0x0')] && wx['getUserInfo']({
          'success': _0x306423 => {
            this['globalData'][a0_0x5d05('0x3')] = _0x306423[a0_0x5d05('0x3')], this[a0_0x5d05('0xb')] && this['userInfoReadyCallback'](_0x306423);
          }
        });
      }
    });
  },
  'globalData': {
    'userInfo': null
  },
  'systemInfo': {}
});

话不多说,上干货

javascript-obfuscator的安装

  • 官网地址 点我进入
  • 民间安装方式(建议用cnpm安装)
npm init -f
npm install formidable --save
npm install -g javascript-obfuscator
  • 官网安装方式
npm install --save-dev javascript-obfuscator

javascript-obfuscator的用法

  • 默认不用参数的加密直接执行
javascript-obfuscator input.js --output output.js
  • 也可以使用部分自定义参数
--target 'browser-no-eval'
--disable-console-output true
--debug-protection true
--debug-protection-interval true
--identifier-names-generator 'hexadecimal'
--string-array true
--rotate-string-array true
--string-array-encoding 'rc4'
--string-array-threshold 0.8
  • 当然还能直接读取配置json文件
javascript-obfuscator a.js --config test.json --output b.js

官方推荐的三种配置

  • 性能将比没有混淆的情况下慢50-100%
  • {
    compact: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 1,
    deadCodeInjection: true,
    deadCodeInjectionThreshold: 1,
    debugProtection: true,
    debugProtectionInterval: true,
    disableConsoleOutput: true,
    identifierNamesGenerator: 'hexadecimal',
    log: false,
    renameGlobals: false,
    rotateStringArray: true,
    selfDefending: true,
    stringArray: true,
    stringArrayEncoding: 'rc4',
    stringArrayThreshold: 1,
    transformObjectKeys: true,
    unicodeEscapeSequence: false
    }
    { compact: true, controlFlowFlattening: true, controlFlowFlatteningThreshold: 1, deadCodeInjection: true, deadCodeInjectionThreshold: 1, debugProtection: true, debugProtectionInterval: true, disableConsoleOutput: true, identifierNamesGenerator: 'hexadecimal', log: false, renameGlobals: false, rotateStringArray: true, selfDefending: true, stringArray: true, stringArrayEncoding: 'rc4', stringArrayThreshold: 1, transformObjectKeys: true, unicodeEscapeSequence: false }
    {
        compact: true,
        controlFlowFlattening: true,
        controlFlowFlatteningThreshold: 1,
        deadCodeInjection: true,
        deadCodeInjectionThreshold: 1,
        debugProtection: true,
        debugProtectionInterval: true,
        disableConsoleOutput: true,
        identifierNamesGenerator: 'hexadecimal',
        log: false,
        renameGlobals: false,
        rotateStringArray: true,
        selfDefending: true,
        stringArray: true,
        stringArrayEncoding: 'rc4',
        stringArrayThreshold: 1,
        transformObjectKeys: true,
        unicodeEscapeSequence: false
    }
    
    • 性能会比没有混淆的情况稍微慢一些
    • {
      compact: true,
      controlFlowFlattening: false,
      deadCodeInjection: false,
      debugProtection: false,
      debugProtectionInterval: false,
      disableConsoleOutput: true,
      identifierNamesGenerator: 'hexadecimal',
      log: false,
      renameGlobals: false,
      rotateStringArray: true,
      selfDefending: true,
      stringArray: true,
      stringArrayEncoding: false,
      stringArrayThreshold: 0.75,
      unicodeEscapeSequence: false
      }
      { compact: true, controlFlowFlattening: false, deadCodeInjection: false, debugProtection: false, debugProtectionInterval: false, disableConsoleOutput: true, identifierNamesGenerator: 'hexadecimal', log: false, renameGlobals: false, rotateStringArray: true, selfDefending: true, stringArray: true, stringArrayEncoding: false, stringArrayThreshold: 0.75, unicodeEscapeSequence: false }
      {
          compact: true,
          controlFlowFlattening: false,
          deadCodeInjection: false,
          debugProtection: false,
          debugProtectionInterval: false,
          disableConsoleOutput: true,
          identifierNamesGenerator: 'hexadecimal',
          log: false,
          renameGlobals: false,
          rotateStringArray: true,
          selfDefending: true,
          stringArray: true,
          stringArrayEncoding: false,
          stringArrayThreshold: 0.75,
          unicodeEscapeSequence: false
      }
      

      当然以上所说,都只是针对单个js文件的处理方法,要想针对整个项目中的js文件,则还需要借助bat脚本来实现

      思路

      • 获取小程序项目名,复制到新的混淆文件夹
      • 对混淆文件夹下所有的js文件执行 混淆命令

      小编亲测混淆后代码正常审核通过

THE END
icon
0
icon
打赏
icon
分享
icon
二维码
icon
海报