cr4n5 / XiaoYuanKouSuan

小猿口算_已达到0.00s
1.39k stars 180 forks source link

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

Closed ulua3809 closed 1 month ago

ulua3809 commented 1 month ago

注意:此方法练习无效,因为练习不是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速,剪的有点意识流,见谅

https://github.com/user-attachments/assets/1dff746c-3646-405e-9700-37dc1ac2ccea

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;
}
bigsk05 commented 1 month ago

66666

cr4n5 commented 1 month ago

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

可以 尝试下

kanade521 commented 1 month ago

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

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

ulua3809 commented 1 month ago

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

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

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

moemmo commented 1 month ago

没有效果

ulua3809 commented 1 month ago

没有效果

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

masknull commented 1 month ago

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

cr4n5 commented 1 month ago

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

ulua3809 commented 1 month ago

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()
}

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

cr4n5 commented 1 month ago

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()
}

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

好的,我试试,谢谢

iFleey commented 1 month ago

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