龙空技术网

微信 “跳一跳” 分析笔记

看雪学苑 166

前言:

此刻各位老铁们对“微信ajax返回页面跳转页面代码是什么意思”大约比较关心,看官们都需要分析一些“微信ajax返回页面跳转页面代码是什么意思”的相关内容。那么小编在网络上搜集了一些有关“微信ajax返回页面跳转页面代码是什么意思””的相关知识,希望大家能喜欢,姐妹们快快来学习一下吧!

0x00 引子

目前网上已经有模拟发包上传分数的方案了,图形识别和人肉丈量都是不错的选择,此外,也有基于安卓 adb 实现的。下面给出一些这方面的分析,没别的意思,就是纯粹好玩。

0x01 抓包

抓包通常可以用 Charles 或者 Fiddler 抓小程序 https 数据,这里说下另一种方法,从安卓代码入手,找到 https 明文发包点截取封包。

从微信的 log 中看到,每次游戏发包时都会打印 "AppBrandNetworkRequest",从 Tag 命名上猜测这是小程序代码通过微信 sdk 发包的接口,反编译微信根据该关键词定位到负责小程序 https 通信的类是 Lcom/tencent/mm/plugin/appbrand/i/c;。

分析下代码可以发现最后使用过 Lcom/tencent/mm/sdk/f/e;->post 发包的,打印调用这行代码的函数的各个参数就可以截取小程序通过 https 发送的 json 明文数据了。

0x02 改包

在 1 中明文发包点可以直接修改发送的数据,但是敏感数据是加密通信的,比如上传分数的接口 中 action_data 字段就是在小程序内加密后再通过微信发出去的。

既然数据是在本地加密的,加密算法肯定也在本地可以找到,所以"跳一跳"作弊的关键就是找到小程序源码。

0x03 寻找小程序源码

从微信小程序文档中可以知道,小程序的核心逻辑通常是用 js 写的。搜索手机中的文件并没有找到后缀为 ".js" 的源码,源码只能从内存中 dump 了。

微信 log 中搜索 ".js",可以发现有如下 log 打印:

I/MicroMsg.WxaPkgRuntimeReader(12426): [, , 12554]:openRead, appId = wx7c8d593b2c3a7703, reqURL = /game.js, null(FALSE), type = java.lang.String, cost = 6ms

从关键词 WxaPkgRuntimeReader 可以猜测这是 wxapp 源码加载的相关代码,通过该关键词反编译微信定位到加载 js 代码的类:Lcom/tencent/mm/plugin/appbrand/appcache/ai;

分析代码可知该类下的 public static String a(e eVar, String str) 方法返回的就是js源码,把返回字串 dump 下来得到 "跳一跳" 核心源码 game.js。

0x04 实现作弊功能

有了源码,就可以根据上传分数的相关代码模拟上报分数了:

{

key: "requestSettlement",

value: function() {

var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 0,

e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0,

i = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : function() {},

n = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : {};

if (a.default.sessionId) {

var r = {

score: t,

times: e,

game_data: JSON.stringify(n)

},

o = {

base_req: {

session_id: a.default.sessionId,

fast: 1

},

action_data: (0, s.encrypt)(r, a.default.sessionId)

};

wx.request({

url:

h.AJAX_URL + "/wxagame/wxagame_settlement",

method: "POST",

data: o,

success: function(t) {

i(200 === t.statusCode ? 0 === t.data.base_resp.errcode ? !0 : !1 : !1)

},

fail: function(t) {

i(!1)

}

})

} else i(!1)

}

},

加密部分:

e.encrypt = function(t, e) {

var e = e.slice(0, 16),

i = n.default.enc.Utf8.parse(e),

r = n.default.enc.Utf8.parse(e),

a = t;

a = JSON.stringify(a);

var o = n.default.AES.encrypt(a, i, {

iv: r,

mode: n.default.mode.CBC,

padding: n.default.pad.Pkcs7

});

return o = o.toString()

};

既然源码在手,直接修改源码就可以实现作弊功能了。实现的方法是修改 3 中的 js 源码载入函数的返回字符串,替换相应 js 代码。

比如修改每次跳跃加分 32,把 "this.score+=t" 替换成 "this.score+=32" 等等。

0x05 基于触动精灵来实现

想到了下面的识别办法:

1. 逐行进行扫描来识别要跳转的目标坐标。为了提高效率可以适当增加扫描步进。定义一个矩形区域,要跳转的目标相对来说位置都比较固定。

2. 获取小人的位置,通过触动精灵的查找颜色功能进行定位坐标,虽然有一定误差,但是只要能获取到坐标,用来计算还是基本没问题的。

3. 计算跳跃距离,通过直接三角形的勾股定理进行计算。按压时间需要根据距离进行修正,我在小米 5s上测试用的1.3 基本还算可以。

已知问题:

1. 通过触动精灵进行颜色匹配搜索坐标的做法效率较低,需要比较长的时间。

2. 运行一段时间之后,找色函数和获取小人坐标的函数会发生错误,导致无法获取到真正的坐标。我加了几个判断,出现问题的时候直接重新启动脚本就可以了。

3. 由于是基于颜色进行匹配的,因而相对来时识别的坐标的准确度比上面的python版本要低很多。

改进方式:

1. 针对搜索坐标的函数进行匹配,折半查找,如果小人在左侧,直接搜索右侧。如果小人在右侧直接搜索左侧。

2. 匹配到错误之后直接重启脚本,使用触动精灵的循环运行功能

3. 其他未知的功能修改?我也不知道有啥。哈哈

脚本文件:

require "TSLib"

require("math")

-----------------------------------------------

-- Auto jump scripy

-- Code by obaby

--

-- Findu App

-----------------------------------------------

-- define scan zone with (x1,y1) (x2,y2)

scanZone_x1 = 50;

scanZone_y1 = 600;

scanZone_x2 = 1000;

scanZone_y2 = 922;

-- get the target object position

function getDestXY()

-- body

mSleep(1000);

isfound = 0;

dest_x = 0;

dest_y = 0;

for y = scanZone_y1,scanZone_x2,30 do

for x =scanZone_x1,scanZone_x2,30 do

colorb = getColor(x, y)

colorc = getColor(x-30, y)

colord = getColor(x+50, y)

delta = math.abs(colorb -colorc)

delta2 = math.abs(colord - colorb)

--toast(delta.." :x:"..x.." :y:"..y,1)

--mSleep(100)

if delta >1000 then

--toast(delta.." :x:"..x.." :y:"..y,1)

nLog("COLO TO::ColorB:"..colorb.." ColorC:"..colorc);

isfound = 1;

dest_x = x;

dest_y = y;

--mSleep(5000);

break;

end

--dialog("ColorB:"..colorb.."ColorC:"..colorc, 3);

--mSleep(3000)

--x= x+10

end

--y= y+10

if isfound ==1 then

break;

end

end

return dest_x, dest_y

end

-- get the

function getDistance(dest_x, dest_y)

-- body

--mSleep(1000);

x, y = findColorInRegionFuzzy( 0x39375f , 80, 0, 926, 1070, 1370);

if x == -1 then

x, y = findColorInRegionFuzzy( 0x39375f , 70, 0, 926, 1070, 1370);

end

if x == -1 then

x, y = findColorInRegionFuzzy( 0x39375f , 80, 0, 926, 1070, 1370);

end

if x ==-1 then

return 0;

end

nLog("JUMP FR::src_x:"..x.." src_y:"..y);

distance = math.sqrt(math.pow(dest_x - x,2) + math.pow(dest_y-y,2));

if math.abs(dest_y - y) < (1116-940) then

return (1116-940)*1.4;

end

return distance;

end

while (true) do

-- body

if (isColor( 581, 1626, 0xffffff, 85) and isColor( 558, 1714, 0x262628, 85)) then

break;

end

dest_x , dest_y = getDestXY();

dist = getDistance(dest_x,dest_y);

toast("dest_x:"..dest_x.." dest_y:"..dest_y.." distance:"..math.floor(dist),3);

--toast(dist,1)

--can not get dest position or can not get the source position

nLog("JUMP TO::dst_x:"..dest_x.." dst_y:"..dest_y.." distance:"..math.floor(dist));

if dest_x ==scanZone_x1 or dist == 0 or dest_y == scanZone_y1 or dest_x ==scanZone_x2 then

toast("Get posison error",1);

nLog("ERRO ER:: Get position error")

break;

end

touchDown(dest_x, dest_y);

mSleep(dist*1.3);

touchUp(dest_x, dest_y);

end

本文由看雪论坛 洪荒之力&obaby 原创 转载请注明来自看雪社区

标签: #微信ajax返回页面跳转页面代码是什么意思