参数跟丢了之JS生成器和包装器

如需转载请注明出处.欢迎小伙伴一起讨论技术.

逆向网址:aHR0cHM6Ly91bmlvbi5qZC5jb20vcHJvTWFuYWdlci9pbmRleD9wYWdlTm89MQ==

跟踪接口:aHR0cHM6Ly9hcGkubS5qZC5jb20vYXBp

跟踪参数:h5st

本文目标:记录学习下自定义的生成器和包装器,不做具体的参数加密逻辑分析

直接启动器进入,跟战后找到以下代码位置.

问题:跟栈的时候在case20的位置找到最终h5st的结果值,再往上跟栈找不到生成和拼接h5st的位置

那么就尝试理解下这段代码

function X() {return (X = (0,u.Z)(h().mark((function e(t) {var n, o, a, i, r, l, s, c, d, u, p, f, g, v, m, b, x, w, _, y, C;return h().wrap((function (e) {for (; ;)switch (e.prev = e.next) {case 0:return n = t.functionId,o = t.method,a = void 0 === o ? "GET" : o,i = t.params,r = t.isEncode,l = void 0 === r || r,s = t.needCode,c = void 0 !== s && s,d = t.appid,u = void 0 === d ? M.ZP.APP_ID.UNION_PC : d,p = t.payload,f = void 0 === p ? {} : p,g = "https://api.m.jd.com/api?",v = $().get("__jda"),m = null == v ? void 0 : v.split(".")[1],b = {functionId: n,appid: u,_: Date.now(),loginType: "3",uuid: m,"x-api-eid-token": Q},e.prev = 5,x = new window.ParamsSign({appId: "586ae"}),i = H(H({}, i), {}, {clientPageId: "jingfen_pc"}),w = {functionId: n,appid: u,body: F()(k()(i)).toString()},e.next = 12,x.sign(w);case 12:_ = e.sent,y = _.h5st,b = H(H({}, b), {}, {h5st: encodeURI(y)}),e.next = 20;break;case 17:e.prev = 17,e.t0 = e.catch(5),console.log(e.t0);case 20:"POST" === a ? (C = "body=".concat(l ? encodeURIComponent(k()(i)) : k()(i)),f.data = C) : b.body = l ? encodeURIComponent(k()(i)) : i,g += (0,Z.L7)(b),f.extendParams || (f.extendParams = {});try {n && (f.extendParams.functionId = n),i && i.funName && (f.extendParams.funName = i.funName)} catch (e) {console.log("error: ", e)}return e.next = 26,J(H(H({method: a,url: g}, f), {}, {withCredentials: !0,needCode: c})).then((function (e) {return !e.page && e.pageNo && (e.page = {pageNo: e.pageNo,pageSize: e.pageSize,hasNext: e.hasNext,totalCount: e.total || e.totalNum}),e}));case 26:return e.abrupt("return", e.sent);case 27:case "end":return e.stop()}}), e, null, [[5, 17]])})))).apply(this, arguments)
}

知识点1:    (0,u.Z),这种写法;

        作用1,在 JavaScript 中,u.Z 是一个函数。如果你直接调用 u.z(),那么 u将成为函数 Z的上下文(即 this),而 (0, u.Z) 的写法可以确保 u.Z 在全局上下文或其他上下文中被调用,避免 this 被意外改变

        作用2,如果代码经过工具(比如 Babel)处理,它可能将一些较复杂的函数调用转化为 (0, u.Z) 形式。这样做的目的是保证代码在不同环境下都能正常工作,特别是在模块系统中,有时需要显式地调用函数而不是通过方法调用

知识点2:h().mark函数,进入mark函数,扣下主要代码

var h = "suspendedStart", d = "suspendedYield", f = "executing", p = "completed", v = {};
function g() { }
function m() { }
function b() { }
var y = {};
s(y, i, (function () {return this
}
));
//E的原型是一个数组
var w = Object.getPrototypeOf, _ = w && w(w(M([])));
_ && _ !== n && o.call(_, i) && (y = _);
var E = b.prototype = g.prototype = Object.create(y);
//...省略一大段
t.mark = function (t) {return Object.setPrototypeOf ? Object.setPrototypeOf(t, b) : (t.__proto__ = b,s(t, l, "GeneratorFunction")),//返回一个对象,设置该对象继承E的原型t.prototype = Object.create(E),t
}

从上面可以看出,最终t是返回一个生成器函数

知识点3:h().wrap,扣下主要代码

//包装器
function c(t, e, n, o) {var r = e && e.prototype instanceof g ? e : g, i = Object.create(r.prototype), a = new C(o || []);//生成器的核心逻辑return i._invoke = function (t, e, n) {//o为记录状态,next、throw 或 returnvar o = h;return function (r, i) {if (o === f)throw new Error("Generator is already running");if (o === p) {if ("throw" === r)throw i;return A()}for (n.method = r,n.arg = i; ;) {var a = n.delegate;if (a) {var l = O(a, n);if (l) {if (l === v)continue;return l}}if ("next" === n.method)n.sent = n._sent = n.arg;else if ("throw" === n.method) {if (o === h)throw o = p,n.arg;n.dispatchException(n.arg)} else"return" === n.method && n.abrupt("return", n.arg);o = f;//代用传下来的函数,在u中调用var s = u(t, e, n);if ("normal" === s.type) {if (o = n.done ? p : d,s.arg === v)continue;return {value: s.arg,done: n.done}}"throw" === s.type && (o = p,n.method = "throw",n.arg = s.arg)}}}(t, n, a),i
}
function u(t, e, n) {try {return {type: "normal",//最终调用位置,使用call方法arg: t.call(e, n)}} catch (t) {return {type: "throw",arg: t}}
}
//把包装器暴露c函数,让外部使用wrap方法调用
t.wrap = c;

wrap方法是一个包装器,里面封装了一个生成器

那么理解了关键的两个函数mark和wrap,大概就知道wrap里面的参数中的匿名函数什么时候执行

a 使用next方法每次调用生成器,进入生成器i._invoke

b 生成器内部调用u函数,最后使用call方法调用匿名函数

c 在匿名函数中每个case的结尾都会定义下一次执行的case

最后推测h5st参数是在匿名函数中case0位置生成,但是在case0代码块并没有发现拼接h5st参数的位置,而关键点是在window.ParamsSign这个类中,关键的加密逻辑都在里面

最终的生成结果会在s对象的PromiseResult属性中,这也是很坑的,很容易看不到导致跟丢了参数;

就可以回答开始提出的问题,在case20处可以看到h5st的结果,case处没有找到拼接h5st处的地

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/466019.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis集群——针对实习面试

目录 Redis集群Redis集群解决了什么问题?Redis集群是如何分片的?什么是Sentinel?Redis如何使用哨兵(Sentinel)系统?集群如何进行故障转移?Redis集群中的主从复制模型是怎样的?Redis集…

【种完麦子,我就往南走,去西双版纳,过个冬天!】

麦子奶奶:冰哥,你好。 大冰:你好,咱俩不定谁大呢。 麦子奶奶:嗯,我大,我60多了,你各方面都是哥。 大冰:阿姨好 麦子奶奶:我想出去看看祖国的大好河山&…

长亭那个检测能力超强的 WAF,出免费版啦

告诉你们一个震撼人心的消息,那个检测能力超强的 WAF——长亭雷池,他推出免费社区版啦,体验地址见文末。 八年前我刚从学校毕业,在腾讯做安全研究,看到宇森在 BlackHat 上演讲的议题 《永别了,SQL 注入》 …

Elasticsearch+kibana+filebeat的安装及使用

版本7.6.0 自己去官网下载或者私信找我要,jdk是8版本 1.ES安装 网上有好多安装教程可以自己去搜索 这个是我的es文件路径: { “name” : “node-1”, “cluster_name” : “elasticsearch”, “cluster_uuid” : “NIepktULRfepkje3JHw8NA”, “ve…

NVR小程序接入平台/设备EasyNVR多品牌NVR管理工具/设备汇聚公共资源场景方案全析

随着信息技术的飞速发展,视频监控已经成为现代社会安全管理和业务运营不可或缺的一部分。特别是在公共资源管理方面,视频监控的应用日益广泛,涵盖了智慧城市、智能交通、大型企业以及校园安防等多个领域。NVR小程序接入平台EasyNVR作为一款功…

ThingsBoard规则链节点:RPC Call Reply节点详解

引言 1. RPC Call Reply 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 设备控制 3.2 状态查询 3.3 命令执行 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台,提供了设备管理…

【论文复现】基于图卷积网络的轻量化推荐模型

本文所涉及所有资源均在这里可获取。 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐、摄影的一位博主。 📗本文收录于论文复现系列,大家有兴趣的可以看一看…

sql数据库-DQL-基本查询

目录 举例表emp 查询多个字段 查询整张表所有数据 给字段名起别名(更方便阅读) 去除重复的数据 举例表emp 查询多个字段 SELECT 字段1,字段2,字段3...FROM 表名; 举例查询emp表中的name,workno,age字段返回 查询整张表所有数据 …

OpenCV通过指针裁剪图像

OpenCV 中mat 格式的像素数值都是连续排列的。为了深入了解cuda 编程。我们来写一个简单的小程序测试一下。 1 不裁剪 cv::Mat crop_image(int(height), int(width), CV_8UC3, image.data);2 只保留图像1/3 cv::Mat crop_image(int(height/3), int(width), CV_8UC3, image.da…

Perforce《2024游戏技术现状报告》Part2:游戏引擎、版本控制、IDE及项目管理等多种开发工具的应用分析

游戏开发者一直处于创新前沿。他们的实践、工具和技术受到各行各业的广泛关注,正在改变着组织进行数字创作的方式。 近期,Perforce发布了《2024游戏技术现状报告》,通过收集来自游戏、媒体与娱乐、汽车和制造业等高增长行业的从业者、管理人…

软件测试面试题及答案

以下是软件测试相关的面试题及答案! 1、测试分为哪几个阶段? 一般来说分为5个阶段:单元测试、集成测试、确认测试、系统测试、验收测试 2、软件测试的流程是什么? 需求调查:全面了解系统概况、应用领域、软件开发周期、软件开发环境、开发组织、时…

Python实例:爱心代码

前言 在编程的奇妙世界里,代码不仅仅是冰冷的指令集合,它还可以成为表达情感、传递温暖的独特方式。今天,我们将一同探索用 Python 语言绘制爱心的神奇之旅。 爱心,这个象征着爱与温暖的符号,一直以来都在人类的情感世界中占据着特殊的地位。而通过 Python 的强大功能,…

TypeError: can‘t multiply sequence by non-int of type ‘float‘

通过python程序编写excel表格中的数据,在计算数值时出现数值类型错误: TypeError: cant multiply sequence by non-int of type float 问题分析: 读取的Excel文件中的单元格数据,读取的数值有可能不是数值类型,而是含…

行业人才缺口达百万,无人机“飞手”之渴如何解?0基础无人机学习技术详解

针对无人机“飞手”行业人才缺口达百万的问题,以下是对如何缓解这一缺口以及0基础学习无人机技术的详细解析: 一、缓解无人机“飞手”人才缺口的方法 1. 产教融合: 通过校企合作、产教融合等方式,培养具备实战能力的无人机“飞手…

D60【python 接口自动化学习】- python基础之数据库

day60 数据库定义 学习日期:20241106 学习目标:MySQL数据库-- 128:数据库定义 学习笔记: 无处不在的数据库 数据库如何存储数据 数据库管理系统(数据库软件) 数据库和SQL的关系 总结 数据库就是指数据…

React中类组件和函数组件的理解和区别

react代码模块分为类组件和函数组件。 从语法和定义、内部状态管理、生命周期、性能、可读性和维护性、上下文、集成状态管理库等角度对比React中类组件和函数组件。 1、语法和定义 类组件: 使用 ES6 的类(class)语法定义的 React 组件。…

苹果 CMS 原生 Java 白菜影视 App 源码

源码介绍 苹果 CMS 原生 Java 白菜影视 App 源码是一款功能强大的影视应用程序,支持画中画、投屏、点播、播放前广告和支持普通解析等多种功能。与萝卜 App 源码相比,该套源码更加稳定,且拥有画中画投屏和自定义广告等功能,提高了…

三菱MR-J4-B系列伺服参数一览

要点 与伺服系统控制器连接后,同服系统控制器的伺服参数的值即被写入各参数中。根据伺服系统控制器的机种和伺服放大器软件版本及MRConfigurator2的软件版本,存在无法设定的参数或范围。详细内容请参照伺服系统控制器的用户手册。请使用MR Configurator2…

做遥感算法?GIS开发?新型测绘?哪个专业更注重编程能力?

遥感、地信、测绘三大地理行业,编程能力的重视程度各有不同: 遥感:编程服务算法 遥感行业通常与卫星、航空摄影和无人机等技术密切相关,遥感对编程的要求更多注重AI算法、机器学习、大数据等方面,包括神经网络,高斯过…

scala set训练

Set实训内容: 1.创建一个可变Set,用于存储图书馆中的书籍信息(假设书籍信息用字符串表示),初始化为包含几本你喜欢的书籍 2.添加两本新的书籍到图书馆集合中,使用操作符 3.删除一本图书馆集合中的书籍&…