cr4n5/XiaoYuanKouSuan

不用破解接口加密,重写判断js可过本地判题

Closed this issue · 11 comments

注意:此方法练习无效,因为练习不是webview页面,只对pk有用,想冲榜的可以看看之前的老方法

有人反馈在3.93.3版本方法无效,详情见这里,实测在3.93.2版本还有效,截至10/13 10:03,不行的话可以降级试试,还不行的话大概是热更新修了

或许3.93.3版本改pk_*.js有用(仅个人猜想未验证),还是推荐用3.93.2版本,能用一天是一天

实测3.93.3版本
版本号3930399
安装包MD5784c4683d6bae83ddbbc1bcf17d7006c
方法依旧有效,测试过程3.93.2升级至3.93.3,pk场有效,清除所有数据后重新登录,依然有效,但还是推荐用旧版

示例视频

视频剪辑了一下,压缩一下大小,PK部分4x速,剪的有点意识流,见谅

studio_video_1728699248331.mp4

url是
https://leo.fbcontent.cn/bh5/leo-web-oral-pk/exercise_*.js
其中*为一串16进制的值
找到响应中isRight后面的函数,本例为
cs(t)
把js中的所有cs(t)替换成cs(t)||true

不要直接照抄,本例中是cs(t),脚本会混淆,认准isRight后面的函数!!!

替换前

Za.value && o().prototype.$addFrog("/time/oral/onRecognize", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                recognizeResult: t,
                answers: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t) || "false",
                stokeCount: e
            });
            cs(t) ? is(t, e) : (window.clearTimeout(Xa.value),
            Xa.value = setTimeout((function() {
                Ya.value.length === e && is(t, e)
            }
            ), 700))
        }
          , is = function(t, e) {
            var r, n, i, a = {
                recognizeResult: t,
                pathPoints: Ya.value,
                answer: cs(t) ? 1 : 0,
                showReductionFraction: !cs(t) && as(t) ? 1 : 0
            };
            (ts.value(a),
            Za.value) && (o().prototype.$addFrog("/time/oral/singleQuestion", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                stokeCount: e,
                result: t,
                answer: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t) || "false"
            }),
            Za.value = !1);
            ls()
        }

替换后

Za.value && o().prototype.$addFrog("/time/oral/onRecognize", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                recognizeResult: t,
                answers: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t)||true || "false",
                stokeCount: e
            });
            cs(t)||true ? is(t, e) : (window.clearTimeout(Xa.value),
            Xa.value = setTimeout((function() {
                Ya.value.length === e && is(t, e)
            }
            ), 700))
        }
          , is = function(t, e) {
            var r, n, i, a = {
                recognizeResult: t,
                pathPoints: Ya.value,
                answer: cs(t)||true ? 1 : 0,
                showReductionFraction: !cs(t)||true && as(t) ? 1 : 0
            };
            (ts.value(a),
            Za.value) && (o().prototype.$addFrog("/time/oral/singleQuestion", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                stokeCount: e,
                result: t,
                answer: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t)||true || "false"
            }),
            Za.value = !1);
            ls()
        }

注意,js经过混淆,函数名字可能会不同
任意答案都判对,但是会提示注意约分

关于小学生验证题库

小学生验证题库也在这个js里,目前只有几道题,(应该是临时编的)

image

10/11 20:55 更新

js貌似是按时轮换的,固定的替换没有什么用
另外最好配合webviewpp模块和电脑上的chrome inspect使用(实测强行停止应用,并清除缓存就行了)
选择这个页面
image
勾上这个
image
ctrl+r强制刷新,不然有缓存抓包抓不到,找个工具重写响应就ok了

实现流程

没有在Python上验证过,可能有问题,但思路应该是对的

# 1. 正则匹配,拿到函数名

funname = re.search(r"(?<=isRight:)[^,]*?\(.*?\).*?(?=\|)",responsetext).group()

# 2. 替换响应并返回

responsetext = responsetext.replace(funname,funname +"||true")

# 3. 最后responsetext就是改写好的js响应了

10/12 03:11更新

方案基本定型了,除非官方又整活,之后不更新了,官方整活也不更了

如果发现没有包,多半是缓存没过期,可以到设置 应用详情 清除应用缓存,然后开始重写

proxypin重写js脚本示例

url填https://leo.fbcontent.cn/bh5/leo-web-oral-pk/exercise_*.js

另外发现同path的pk_*.js,结构和上面那个类似,实测只要改exercise_*.js就好了

async function onRequest(context, request) {
   console.log(request.url);
   return request;
}

async function onResponse(context, request, response) {
   var funname = response.body.match(/(?<=isRight:)[^,]*?\(.*?\).*?(?=\|)/);
   console.log("替换函数名为:", funname);
   if (funname) {
      console.log("找到函数,开始替换")
      response.body = response.body.replaceAll(funname, funname + "||true");
   }
   return response;
}

66666

url是 https://leo.fbcontent.cn/bh5/leo-web-oral-pk/exercise_b42a8d9babd67a4e.js 把响应中的 us(t) 替换成 us(t)||true 任意答案都判对

可以 尝试下

url是 https://leo.fbcontent.cn/bh5/leo-web-oral-pk/exercise_b42a8d9babd67a4e.js 把响应中的 us(t) 替换成 us(t)||true 任意答案都判对

这个us的位置在哪啊 响应体里面没找到

url是 https://leo.fbcontent.cn/bh5/leo-web-oral-pk/exercise_b42a8d9babd67a4e.js 把响应中的 us(t) 替换成 us(t)||true 任意答案都判对

这个us的位置在哪啊 响应体里面没找到

js混淆过的,名字不一定一样,issue改了,可以看看
js可能是按时轮换的

没有效果

没有效果

要配合webviewpp模块和电脑上的chrome inspect使用,取消缓存强制刷新,不然抓包抓不到

老哥牛,研究加密函数搞到现在过来issues一看天亮了😋
微信截图_20241011214149

image
你好,为什么我已做出劫持更改,还是不行

image 你好,为什么我已做出劫持更改,还是不行

不是只改isRight:后面
before

Za.value && o().prototype.$addFrog("/time/oral/onRecognize", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                recognizeResult: t,
                answers: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t) || "false",
                stokeCount: e
            });
            cs(t) ? is(t, e) : (window.clearTimeout(Xa.value),
            Xa.value = setTimeout((function() {
                Ya.value.length === e && is(t, e)
            }
            ), 700))
        }
          , is = function(t, e) {
            var r, n, i, a = {
                recognizeResult: t,
                pathPoints: Ya.value,
                answer: cs(t) ? 1 : 0,
                showReductionFraction: !cs(t) && as(t) ? 1 : 0
            };
            (ts.value(a),
            Za.value) && (o().prototype.$addFrog("/time/oral/singleQuestion", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                stokeCount: e,
                result: t,
                answer: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t) || "false"
            }),
            Za.value = !1);
            ls()
        }

after

Za.value && o().prototype.$addFrog("/time/oral/onRecognize", {
	duration: Date.now() - $a.value,
	keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
	ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
	isOralPk: !0,
	recognizeResult: t,
	answers: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
	isRight: cs(t)||true || "false",
	stokeCount: e
});
cs(t)||true ? is(t, e) : (window.clearTimeout(Xa.value),
	Xa.value = setTimeout((function () {
		Ya.value.length === e && is(t, e)
	}
	), 700))
        }
          , is = function (t, e) {
	var r, n, i, a = {
		recognizeResult: t,
		pathPoints: Ya.value,
		answer: cs(t)||true ? 1 : 0,
		showReductionFraction: !cs(t)||true && as(t) ? 1 : 0
	};
	(ts.value(a),
		Za.value) && (o().prototype.$addFrog("/time/oral/singleQuestion", {
			duration: Date.now() - $a.value,
			keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
			ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
			isOralPk: !0,
			stokeCount: e,
			result: t,
			answer: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
			isRight: cs(t)||true || "false"
		}),
			Za.value = !1);
	ls()
}

注意一下原来的响应是压缩过的,示例是格式化之后的,替换的时候注意一下

image 你好,为什么我已做出劫持更改,还是不行

不是只改isRight:后面 before

Za.value && o().prototype.$addFrog("/time/oral/onRecognize", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                recognizeResult: t,
                answers: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t) || "false",
                stokeCount: e
            });
            cs(t) ? is(t, e) : (window.clearTimeout(Xa.value),
            Xa.value = setTimeout((function() {
                Ya.value.length === e && is(t, e)
            }
            ), 700))
        }
          , is = function(t, e) {
            var r, n, i, a = {
                recognizeResult: t,
                pathPoints: Ya.value,
                answer: cs(t) ? 1 : 0,
                showReductionFraction: !cs(t) && as(t) ? 1 : 0
            };
            (ts.value(a),
            Za.value) && (o().prototype.$addFrog("/time/oral/singleQuestion", {
                duration: Date.now() - $a.value,
                keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
                ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
                isOralPk: !0,
                stokeCount: e,
                result: t,
                answer: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
                isRight: cs(t) || "false"
            }),
            Za.value = !1);
            ls()
        }

after

Za.value && o().prototype.$addFrog("/time/oral/onRecognize", {
	duration: Date.now() - $a.value,
	keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
	ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
	isOralPk: !0,
	recognizeResult: t,
	answers: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
	isRight: cs(t)||true || "false",
	stokeCount: e
});
cs(t)||true ? is(t, e) : (window.clearTimeout(Xa.value),
	Xa.value = setTimeout((function () {
		Ya.value.length === e && is(t, e)
	}
	), 700))
        }
          , is = function (t, e) {
	var r, n, i, a = {
		recognizeResult: t,
		pathPoints: Ya.value,
		answer: cs(t)||true ? 1 : 0,
		showReductionFraction: !cs(t)||true && as(t) ? 1 : 0
	};
	(ts.value(a),
		Za.value) && (o().prototype.$addFrog("/time/oral/singleQuestion", {
			duration: Date.now() - $a.value,
			keypointId: null === (r = Ka.value) || void 0 === r ? void 0 : r.keypointId,
			ruleType: null === (n = Ka.value) || void 0 === n ? void 0 : n.ruleType,
			isOralPk: !0,
			stokeCount: e,
			result: t,
			answer: null === (i = Ka.value) || void 0 === i ? void 0 : i.answers,
			isRight: cs(t)||true || "false"
		}),
			Za.value = !1);
	ls()
}

注意一下原来的响应是压缩过的,示例是格式化之后的,替换的时候注意一下

好的,我试试,谢谢

感谢方法,已在 #80 进行实现。