一、目標(biāo)
李老板: 奮飛呀,光Debug一下沒啥意思,有沒有可能把這個(gè)反編譯出來的小程序跑起來?還是說反編譯的代碼有缺漏,不好使?
奮飛:一城一策,具體App具體分析,具體到這個(gè)App還是可以玩的。

二、步驟
先跑一下
我們先跑一下上篇教程反編譯出來的代碼。
很可惜,白屏,木有我們期待的內(nèi)容。
不過還好有提示: #登錄失敗#
搜索一下:
/Users/fenfei/Downloads/wx/_2089237937_16/3AAE21D3932643BF5CC849D4DA8F8236.js
79,51: title: e.data.msg || "登錄失敗",
/Users/fenfei/Downloads/wx/_2089237937_16/app-service.js
2613,1520: showToast({title:e.data.msg||"登錄失敗",icon:"none"}),
這個(gè)提示有兩處,具體是哪一處呢?
我們把前一個(gè)改成 "登錄失敗1",后一個(gè)改成 “登錄失敗2”。
再跑一下, 提示 “登錄失敗1”。
好了,就是你了。
分析代碼
wx.request({
url: "".concat(n, "/s/user/account/openlogin"),
method: "POST",
dataType: "json",
data: (0, t.default)({
openkey: e.code
}, u),
success: function(e) {
// console.log(e);
if (e.data.ret > 0) {
var n = e.data, r = n.data, s = n.data.member_info, c = getApp(), u = s.isreg ? 2 : 1;
c && (c.globalData = (0, t.default)({}, s, {
userstatus: u
})), a.h_did = r.did, a.h_m = r.mid, a.mid = r.mid, a.token = r.token, a.userstatus = u,
wx.setStorage({
key: "userInfo",
data: (0, t.default)({}, r, s, {
userstatus: u
})
}),
o(e.data.data);
} else wx.reportAnalytics("login fail request success", JSON.stringify(e)), wx.showToast({
title: e.data.msg || "登錄失敗1",
icon: "none"
}), i();
},
fail: function(t) {
wx.reportAnalytics("login fail request fail", JSON.stringify(t)), i();
}
});
這段代碼的意思是給服務(wù)器發(fā)一個(gè)登錄請(qǐng)求,然后判斷返回值 e.data.ret > 0 的時(shí)候把返回的一些did token之類的值保存下來(估計(jì)后面會(huì)用),如果 e.data.ret 小于等于0,就提示 “登錄失敗1”。
我去,這不就是送分題嗎?我們抓個(gè)包看看真機(jī)上 openlogin 這個(gè)請(qǐng)求返回什么值,然后直接賦值給 e 變量,不就ok了。
我們先加個(gè) console.log(e); 打印一下目前e變量的值是什么?
從 調(diào)試器->Console 中可以看到我們的輸出

返回值是 -101 ,那肯定是登錄失敗了。
改改代碼
按照之前的分析,我們抓包看看真機(jī)上 openlogin 這個(gè)請(qǐng)求的返回值。不過詭異的是,怎么搞都抓不到這個(gè)包。
這也難不倒我們,再分析下代碼,登錄成功之后,會(huì)把一堆返回值保存下來,這樣我們從別的請(qǐng)求包里面把 did mid token 等等這些值找到,然后直接賦值不就行了。
if (e.data.ret < 0) { // 改成小于0
// var n = e.data, r = n.data, s = n.data.member_info, c = getApp(), u = s.isreg ? 2 : 1;
var n = e.data, r = n.data, s = "123456", c = getApp(), u = 2;
c && (c.globalData = (0, t.default)({}, s, {
userstatus: u
})),
// a.h_did = r.did, a.h_m = r.mid, a.mid = r.mid, a.token = r.token, a.userstatus = u,
a.h_did = "eccdb12b68fd755fb52b2763f69aaa00", a.h_m = 257167182, a.mid = 257167182, a.token = "TeKeNJiAKQ3YqxMms7yw2n4gGgkzEWG7SMGoLCSUM6P2hs3N6DyhyGURt-ZA6ZC1j2Uw5w9ur4EXVhLURS7xqnjZd9IbgLPtt5QFJRaMzFVi82yk=", a.userstatus = u,
。。。。。。
}
再跑一下

可以了,跑起來了。
還沒完
還沒高興一會(huì),又出問題了,再跑就怎么也跑不起來了。而且連 “登錄失敗” 的報(bào)錯(cuò)都沒有了。

難道被App發(fā)現(xiàn)了,跨省禁用了, 太流弊了吧。
鼓搗了老半天,無意中點(diǎn)了一下 IDE上的 清緩存
光明又來了,肯定是登錄成功之后把信息存了緩存。
/*
wx.setStorage({
key: "userInfo",
data: (0, t.default)({}, r, s, {
userstatus: u
})
}),
*/
把保存這塊注釋掉就行了,這下就可以更方便的調(diào)試了。
回想起之前真機(jī)上抓不到 openlogin 的包,一定也是這個(gè)緩存搞的鬼。
不過真機(jī)如何請(qǐng)緩存呢? 炒雞簡(jiǎn)單,把這個(gè)小程序刪掉,然后再裝一下。

完美,抓到 openlogin 的包了。
漂亮的改法
既然都抓到包了,那就可以換個(gè)漂亮的改法了,就是我們開始的想法, 直接給 e 變量賦值。
success: function(e) {
e= JSON.parse(`{"data": {"ret":1,"errcode":1,"data":{"member_info":123456,"mid":257167182,"register":0,"passwd":"98227e90298d0711","token":"TeKeNJiAKQ3YqxMms7yw2n4gGgkzEWG7SMGoLCSUM6P2hs3N6DyhyGURt-ZA6ZC1j2Uw5w9ur4EXVhLURS7xqnjZd9IbgLPtt5QFJRaMzFVi82yk=","member_info":{"id":257167182,"isreg":1,"ct":1630931968,"rt":1630931968,"pw":"98417e90298d0757","name":"W8a\xbd\xe5\xad\x90J","gender":0,"sign":"","avatar":3,"cover":0,"isbind":0,"opentype":4,"zyid":"46120279","vip_info":{"mid":257167182,"rev_bubble_cnt":0},"you_age":3},"did":"eccdb12b68fd755fb52b2763f69aaa00"}} }`)
console.log(e);
if (e.data.ret > 0) { // 別忘了把這個(gè)改回來 大于0
}
這下流程比較優(yōu)雅了,可以收工了。
三、總結(jié)
是不是別的小程序也可以這么跑起來?
醒醒吧,大廠的小程序要是這么容易被你跑起來了,那他們的碼農(nóng)哥哥就都要失業(yè)了。一城一策,具體情況再具體分析。我們搞逆向分析,就是在不可能中發(fā)現(xiàn)可能。
還是要有點(diǎn)追求,盡量保障原始程序的流程,能優(yōu)雅搞定的不要粗魯。 當(dāng)然必要時(shí)還是可以動(dòng)粗的。
微信開發(fā)者工具很好用的,調(diào)試器->Sources 下個(gè)斷點(diǎn),絲滑流暢。
搞逆向還是要有點(diǎn)正向開發(fā)基礎(chǔ),這樣就能早意識(shí)到是緩存的問題。
不要神化你的對(duì)手,跨省禁用已經(jīng)是魔法的范疇了。

你不懂得安排自己的人生,會(huì)有很多人幫你安排,他們需要你做的事。