以下为我观察到的行为,不保证正确。
接口 https://wlx.tenpay.com/cgi-bin/wx/hce/ccm_hce_account_info.cgi
返回的数据存在 retcode: "912320107"
,也就是 DEVICE_IS_ROOT: "912320107"
节选自 pages/index/index.js
{
var e = require("../../utils/config.js"),
t = require("../../utils/util.js"),
o = require("../../common/request.js"),
a = require("../../utils/lib.js"),
n = requirePlugin("vfcPlugin").vfc,
i = require("../../logic/login.js"),
c = require("../../logic/uiHelper.js"),
r = require("../../logic/uiShare.js"),
s = require("../../logic/report"),
d = require("../../common/token.js"),
l = require("../../logic/location.js"),
u = require("../../logic/elementData.js"),
g = require("../../utils/thirdparty/aes.js").CryptoJS,
_ = require("../../utils/thirdparty/rsa.js"),
f = require("../../utils/thirdparty/md5.js"),
p = getApp(),
request = o.request,
h = { RIGHT: "/img/right.png", FALSE: "/img/false.png" },
w = { BAL: "余额不足", FAIL: "该城市暂不支持使用乘车卡" },
y = { normal: "刷新", refresh: "已刷新" },
C = {};
Page({
requestCardInfo: function() {
arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
var e = this;
t.compare(C.SDKVersion, "2.6.2", !0) >= 0
? wx.getWxSecData({
complete: function(t) {
e.qryAccInfo({
sec_data_enc: t.encryptedData,
sec_data_enc_iv: t.iv
});
}
})
: e.qryAccInfo({
sec_data_enc: "",
sec_data_enc_iv: "",
wx_version: C.version,
sdk_version: C.SDKVersion
});
},
qryAccInfo: function() {
var request_raw_data =
arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
o = this,
request_data = Object.assign(
{
ykt_id: o.data.ykt_id,
city_code: o.data.city_code,
card_id: i.getCardId() || ""
},
request_raw_data
);
request({
url: e.GET_CARD_INFO,
showLoading: !0,
data: request_data,
success: function(resp) {
var resp_data = resp.data;
if ((console.log(resp), "0" === resp_data.retcode))
if ("0" === resp_data.open_state) {
var n = {
cloud_card_id: resp_data.cloud_card_id,
vfc_card_id: resp_data.vfc_card_id,
vfc_user_id: resp_data.vfc_user_id,
vfc_user_name: resp_data.vfc_user_name,
acc_no: resp_data.acc_no,
card_id: resp_data.card_id
};
wx.setStorageSync(e.USER_INFO_KEY, n);
var i = resp_data.cloud_card_id || "";
o.setData({
loading: !1,
acc_no: resp_data.acc_no,
cloudCardId: i,
formatCloudCardId: i.replace(/(\d{4})/g, "$1 ")
}),
p.setGlobalData({ acc_no: resp_data.acc_no }),
wx.getStorageSync(e.HCETOKEN)
? wx.getStorageSync(e.CERT_NO)
? o.updateCardInfo()
: o.reqCertNo()
: o.requestToken();
} else
wx.redirectTo({
url: "/pages/card/pre/pre?cardImg=" + o.data.cardImg
});
else
switch (resp_data.retcode) {
case e.RETCODE.USER_NOT_EXIST:
case e.RETCODE.USER_STOPPED:
case e.RETCODE.NEW_USER_NOT_NEED_PHONE_AUTH:
wx.redirectTo({
url:
"/pages/card/pre/pre?retcode=" +
resp_data.retcode +
"&cardImg=" +
o.data.cardImg
});
break;
case e.RETCODE.OPEN_NOT_IN_WHITELIST:
case e.RETCODE.OPEN_NOT_ALLOWED:
o.setData({ loading: !1, InWhiteList: !1 });
break;
case e.RETCODE.DEVICE_IS_ROOT:
wx.redirectTo({
url: "/pages/notSupport/notSupport?type=isRoot"
});
break;
default:
c.commonModal({
confirmText: "重试",
retcode: resp_data.retcode,
success: function(e) {
e.confirm && o.render();
}
});
}
},
fail: function(e) {
wx.showModal({
title: "提示",
content: "系统繁忙,请重试",
confirmText: "重试",
success: function(e) {
e.confirm && o.render();
}
});
}
});
}
});
}
节选自 common/request.js
function request(user_query) {
function isLoginUrl() {
return real_query.url === n.LOGIN_CGI;
}
var real_query = Object.assign(
{
retry: !0,
method: "POST",
header: { "content-type": "application/x-www-form-urlencoded" },
isReport: !0
},
user_query
);
real_query.data || (real_query.data = {}),
(real_query.data.s_tk = token.getSysInfoToken()),
(real_query.data.g_tk = token.getACSRFToken()),
(real_query.data.version = n.APP_VERSION);
var l = new Date().getTime().toString();
(real_query.data.timestamp = l.substr(0, 10)),
real_query.showLoading && wx.showLoading({ title: "加载中..." });
var login_data = logic_login.getLoginData();
if (login_data && "POST" == real_query.method)
for (var d in login_data)
("wlx_app_id" !== d &&
"wlx_open_id" !== d &&
"wlx_skey" !== d &&
"wlx_skey_type" !== d) ||
(real_query.data[d] = login_data[d]);
real_query.success = function(resp) {
console.log(resp);
var a = resp.data || {};
200 == resp.statusCode
? !1 === isLoginUrl() &&
real_query.retry &&
"object" == (void 0 === a ? "undefined" : t(a)) &&
logic_login.needAutoLogin(a.retcode)
? !0 !== request.retryMap[user_query.url]
? ((request.retryMap[user_query.url] = !0),
o({
fromCache: !1,
showLoading: user_query.showLoading,
success: function(o) {
request(user_query);
}
}))
: wx.showModal({
title: "提示",
content: "登录失效,请重新登录?",
showCancel: !0,
success: function(t) {
t.confirm
? o({
fromCache: !1,
success: function(o) {
request(user_query);
}
})
: wx.navigateBack({ delta: 5 });
}
})
: (!1 === isLoginUrl() &&
!0 === request.retryMap[user_query.url] &&
(request.retryMap[user_query.url] = !1),
user_query.success(resp))
: user_query.fail && user_query.fail();
};
(real_query.complete = function(e) {
real_query.showLoading && wx.hideLoading(),
user_query.complete && user_query.complete(e);
}),
console.log(real_query),
wx.request(real_query);
}
节选自 logic/login.js
function getLoginData() {
try {
var e = wx.getStorageSync(r.LOGIN_DATA_KEY);
if (
"" !== e.wlx_app_id &&
"" !== e.wlx_open_id &&
"" !== e.wlx_skey &&
"" !== e.wlx_skey_type
) {
var n = getApp();
return n && n.globalData && (n.globalData.wlx_open_id = e.wlx_open_id), e;
}
return null;
} catch (e) {
return null;
}
}
节选自 common/token.js
{
function e() {
try {
var e = wx.getSystemInfoSync(),
t = {
model: e.model,
pixelRatio: e.pixelRatio,
screenWidth: e.screenWidth,
screenHeight: e.screenHeight
};
return r(JSON.stringify(t));
} catch (e) {
console.log("getSysInfoMd5Old");
}
}
function t() {
var e = o.getOpenIdFromStorage();
return e ? r(e + n.SYSINFO_SALT) : (console.log("getSysInfoMd5"), "");
}
var r = require("../utils/thirdparty/md5.js"),
n = require("../utils/config.js"),
o = require("../logic/login.js");
module.exports = {
getSysInfoToken: function() {
return e().substr(-4);
},
getACSRFToken: function() {
try {
var e = wx.getStorageSync(n.LOGIN_DATA_KEY);
if (e) {
for (var t = 5381, r = e.wlx_skey, o = 0, i = r.length; o < i; ++o)
t += (t << 5) + r.charAt(o).charCodeAt();
return 2147483647 & t;
}
} catch (e) {
return "";
}
return "";
},
getSysInfoMd5: t,
getGuidMd5: function() {
return t();
},
md5: r
};
}
这判断很有趣,清空数据后第一次打开就能用,再次打开就不行了。
腾讯能不能因为我 ROOT 了设备就不让我用呢?
四 服务中止 /终止
1、财付通有权基于业务调整或风险管控的需要,暂停、中断或终止向您提供本服务的全部或部分功能。
----- 乘车卡使用协议
1
lpd0155 2019-04-12 23:26:22 +08:00 via Android 1
小白问一句,压缩包里的东西怎么打开?
|
2
azh7138m OP |
3
tony601818 2019-04-13 04:00:33 +08:00 via Android
安卓系统有 SafetyNet
|
4
lpd0155 2019-04-13 07:53:47 +08:00 via Android
@tony601818 没用的,实测过了 SAFETY NET 依然被检测到 ROOT
|
5
kokutou 2019-04-13 09:38:56 +08:00 via Android
magisk+edxposed。。。
乘车码我昨天试了下开通了,今天还是可以打开。。。 |
6
azh7138m OP @kokutou 我清空数据后第一次也是可以用的,过一会就不行了,不知道微信是怎么判断的,这里只是说乘车卡是怎么判断用户是否 root,这个接口的数据是怎么来的就不清楚了。
|
7
kokutou 2019-04-13 11:51:17 +08:00 via Android
|
10
fyooo 2019-05-29 09:22:47 +08:00
@tony601818 国内的手机不支持 GMS,应该是没有 SafetyNet API 的。估计是小程序调用微信的接口检查是否 root 的,https://stackoverflow.com/questions/27291676/root-detection-methodology-in-android-which-cannot-be-bypassed
|
11
UchihaJay 2019-08-23 13:17:55 +08:00
绝对坑,用之前不说,充值开通了告诉我不能用,我为你个乘车吗换手机?行我不要了,告诉我哪里退钱
|