最近想用微信开发者工具运行别人开发好的小游戏。    其实是可以运行的,但是登录验证失败, 别人开发的小游戏appid, 和自己测试appid不一样就导致登录失败了。

如果强行设置别人的appid, 开发者工具会报错, 类似的错误提示为:你不是别人的appid的开发者,  无法设置。

登录是用wx.login API登录, 把这个API破解不久好了, 不必一定要设置成别人的appid. 

将wxapkg解压出的game.js 进行拆分成多个文件。

#coding:utf8 
import os
import re

def writeFile(o):
  print(o[0])
  path = os.path.dirname(o[0])
  if path!='' and not os.path.exists(path):
    os.makedirs(path)

  with open(o[0], 'wb') as f:
    f.write(bytes(o[1], 'utf8'))

def splitGame(filecon):
  if filecon is None:
    print ('文件内容为空')
    return ;
  obj = re.findall(r'W+define("(.*?)",Wfunction(require,Wmodule,Wexports){ 			
(.*?)W			});
', filecon, re.M|re.DOTALL)
  if obj:
    for o in obj:
      writeFile(o)
  else:
    print ('没有匹配到')

def readCon(name):
  with open(name, 'r') as f:
    return f.read()

splitGame(readCon('game2.js'))
# splitGame(readCon('subContext.js'))

通过一系列断点, 找到了两处appid的地方, 

asdebug.js文件:

__devtoolsConfig.appid.     

微信开发者工具分析-风君雪科技博客

 __wxConfig.accountInfo.appid

微信开发者工具分析-风君雪科技博客

看到这里,我已经懒得跟踪asdebug.js在哪了,  因为是全局变量,登录时候hook一下这两个变量就OK了.

============

通过实际测试,发现该方案不行, 原因是asdebug是在VM中运行的,此window非game.js中的window。

微信开发者工具分析-风君雪科技博客

 执行之后, hook的实际是 Window.0.  实际全局: __global.parent

==========

通过一通捣腾之后, 发现即使hook修改了appid, 还不能通过验证, 原因调用wx.login的时候压根就没有appid信息。 

调用wx.login的时候发送了一个websocket请求。 截图时返回的结果。

微信开发者工具分析-风君雪科技博客

服务进程:/Applications/wechatwebdevtools.app/Contents/Frameworks/nwjs Framework.framework/Versions/86.0.4240.111/Helpers/wechatwebdevtools Helper (Renderer).app/Contents/MacOS/wechatwebdevtools Helper (Renderer)

有时间再调试下这个进程。 

core.wxvpkg 文件有RSA-SHA1签名验证。理论上不可以修改。 但是把签名验证的方法hook掉,  还是可以的。  通过此法我修改了core.wxvpkg文件,发现可以正常运行了。

wx.login本质上是调用http post接口

微信开发者工具分析-风君雪科技博客

获取code码:

curl -H 'host: servicewechat.com' --data-binary '{"scope":["snsapi_base"]}' 'https://servicewechat.com/wxa-dev-logic/jslogin?_r=0.700034971603429&newticket=tl1MUNfnG4w1C9n8DyWnxbJB1XrdZuhXDwuC3FrmZag&appid=wx418ad5760dd5bcba&platform=0&ext_appid=&os=darwin&clientversion=1052102020'

hook 输出日志

  setTimeout((function(){
    const request = require("request");
    var exec = require('child_process').exec;

    function dzqLog(m, a) {
      request({
        url: "http://localhost:3000/echo",
        method: "POST",
        json: true,
        headers: {
          "content-type": "application/json",
        },
        body: { m, a },
      });
    }

    try {
      var cmd = 'netstat -anp tcp | grep 3000 | grep LISTEN';
      exec(cmd, function(error, stdout, stderr) {
        // alert('stdout:' + stdout)
        console.log(String(stdout));
        if(String(stdout) !== ''){
          console.log = function () {
            dzqLog("log", Array.from(arguments));
          };
          console.error = function () {
            dzqLog("error", Array.from(arguments));
          };
          console.info = function () {
            dzqLog("info", Array.from(arguments));
          };
        }
      });
    } catch (error) {
      console.error(error.message);
    }
    
    // var oldRe = require;
  
    // require = function(s){
    //   console.log(s);
    //   return oldRe(s);
    // };
    // window && (window.require = require);
    // global && (global.require = require);
  
    // const xxx = require("../../../core.wxvpkg/e9e6a17485b9188c4c1ecada87e6b99c.js");
    // ["checkBufferSignature", "checkSignature", "checkFileMd5Signature"].forEach(
    //   (k) => {
    //     xxx[k] = () => true;
    //   }
    // );
  }), 1000);

文件地址: /Applications/wechatwebdevtools.app/Contents/Resources/package.nw/js/unpack/hackrequire/index.js

日志效果图:

微信开发者工具分析-风君雪科技博客

结论:

wx.login 不可能破解,原因是code码是从服务器拿的,传入的appid.   服务器会校验你的微信和appid有没有开发或者测试权限(这个是项目管理员维护的), 也就是只能拿到你有权限的code码。想获取其他的appid的code码一律失败,

报错:

DEV_APP_NOT_BAND: -80002

腾讯的安全做的真牛逼