上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
1234下一页
返回列表 发新帖

[油猴脚本开发指南]实战videojs极限注入

[复制链接]
  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-9 11:42:44 | 显示全部楼层 | 阅读模式

    前文

    超星更新后的网页

    这次在beforesetup和setup的钩都给强制return了

    导致无法再次使用钩子

    所以我观察源码搞了一个极限注入的操作

    本质上学习观察源码的过程也是提升自我的一个过程

    只要忍过第一个阵痛期,后面其实能看懂源码很爽的

    很多时候你比只会看文档的程序员更了解执行原理!

    开始

    之前的hooks已经失效了,那我们在初始化阶段几乎没有什么可以插手的地方了

          hooks('beforesetup').forEach(function (hookFunction) {
            var opts = hookFunction(el, mergeOptions$3(options));
    
            if (!isObject$1(opts) || Array.isArray(opts)) {
              log$1.error('please return an object in beforesetup hooks');
              return;
            }
    
            options = mergeOptions$3(options, opts);
          }); // We get the current "Player" component here in case an integration has
          // replaced it with a custom player.
    
          var PlayerComponent = Component$1.getComponent('Player');
          player = new PlayerComponent(el, options, ready);
          hooks('setup').forEach(function (hookFunction) {
            return hookFunction(player);
          });

    hooks钩的地方可以全部排除了

    那我们唯一能下手的地方就是更核心的地方

    也就是Component$1.getComponent函数

    我们先观察一下他的源码

          Component.getComponent = function getComponent(name) {
            if (!name || !Component.components_) {
              return;
            }
    
            return Component.components_[name];
          };

    这里判断是否为空,或者保存组件的位置是否为空,如果都不为空,则返回对应的名字

    也就是说Player保存在Component.components_['Player']中

    那我们需要设置的,就是对components_进行设置

    全局搜索Component.components_以及查阅官方文档

    可以找到这里

    图片.png

    查阅官方文档可以发现,这里是注册组件的地方

    那么思路来了,我们可不可以注册Player函数?

    阅读源码开始!

            if (typeof name !== 'string' || !name) {
              throw new Error("Illegal component name, \"" + name + "\"; must be a non-empty string.");
            }

    判断名字异常,可以跳过

            var Tech = Component.getComponent('Tech'); // We need to make sure this check is only done if Tech has been registered.
    
            var isTech = Tech && Tech.isTech(ComponentToRegister);
            var isComp = Component === ComponentToRegister || Component.prototype.isPrototypeOf(ComponentToRegister.prototype);
    
            if (isTech || !isComp) {
              var reason;
    
              if (isTech) {
                reason = 'techs must be registered using Tech.registerTech()';
              } else {
                reason = 'must be a Component subclass';
              }
    
              throw new Error("Illegal component, \"" + name + "\"; " + reason + ".");
            }

    这里通过原型链判断是否继承与Comp组件或者继承于Tech组件

            name = toTitleCase$1(name);
    
            if (!Component.components_) {
              Component.components_ = {};
            }

    name函数经过某些处理,然后对components_如果不存在则进行初始化

            var Player = Component.getComponent('Player');

    获取Player组件

            if (name === 'Player' && Player && Player.players) {
              var players = Player.players;
              var playerNames = Object.keys(players); // If we have players that were disposed, then their name will still be
              // in Players.players. So, we must loop through and verify that the value
              // for each item is not null. This allows registration of the Player component
              // after all players have been disposed or before any were created.
    
              if (players && playerNames.length > 0 && playerNames.map(function (pname) {
                return players[pname];
              }).every(Boolean)) {
                throw new Error('Can not register Player component after player has been created.');
              }
            }

    这里判断了Player地方进行了处理,可以看到首先判断名字是否是Player

    然后判断Player是否为空,如果不为空,则继续判断players是否存在

    三者都存在的时候才禁止替换Player组件

    也就是说我们可以对其进行组件替换

    这里可以看出来Vidoejs的设计非常优秀,对大部分的功能做了一个组件化的抽离和替换。

            Component.components_[name] = ComponentToRegister;
            Component.components_[toLowerCase(name)] = ComponentToRegister;
            return ComponentToRegister;

    然后非常简单,对其组件进行赋值了

    理论建立完毕,开始实战

    let OriginPlayer = _videojs.getComponent('Player')
    let woailiyinhe=function(tag, options, ready){这里做原OriginPlayer的对象生成,返回,处理}
    woailiyinhe.prototype=Object.create(OriginPlayer.prototype)
    videojs.registerComponent('Player',woailiyinhe)

    这里因为是tm脚本,所以我直接上了一个prototype替换,按道理其实官方更推荐用class类,但是那就要做语法转换了,所以hook偷了个懒

    劫持完毕之后我们就可以完美的劫持Player初始化前后的操作了!

    结语

    其实阅读源码对个人提升帮助真的很大,所以偶尔会带领大家一起拆解一些流行的框架或者库的源码

    至于给我爱李银河改成我爱破解,真的蛮无聊的

    写李银河只是因为我个人非常崇尚王小波

    我经常翻读王小波的著作,其中面朝大海,春暖花开那一段非常经典,

    我看了不下十遍,至今仍能倒背如流,所以建议如果不懂李银河瞎改建议先提高文学素养

    我认为写代码不仅仅是写代码,也是一个表达自我精神的一个机会

    代码上的喜好能直接体现出人的性格,希望大家写出属于自己的代码

    李银河

    李银河(1952年2月4日-),女,北京人,中国大陆社会学家、社会活动家,性学家、LGBT权利活动家,已故中国当代作家王小波的遗孀。
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    擦汗
    2024-3-25 15:30
  • 签到天数: 135 天

    [LV.7]常住居民III

    4

    主题

    109

    回帖

    206

    积分

    荣誉开发者

    积分
    206

    荣誉开发者油中2周年

    发表于 2022-3-9 14:38:09 | 显示全部楼层
    ggnb
    收藏 = 学废了
    可恃唯我
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-9 14:46:53 | 显示全部楼层
    cocang 发表于 2022-3-9 14:38
    ggnb
    收藏 = 学废了

    给我学!你不是最喜欢videojs的吗!
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    2022-10-13 11:41
  • 签到天数: 1 天

    [LV.1]初来乍到

    0

    主题

    6

    回帖

    9

    积分

    助理工程师

    积分
    9
    发表于 2022-3-14 12:39:48 | 显示全部楼层
    ggnb!!!!!
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    1

    回帖

    13

    积分

    助理工程师

    积分
    13
    发表于 2022-3-16 13:47:08 | 显示全部楼层

    大哥 今天网站更新了 用不了了 能更新下插件吗
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-16 14:03:39 | 显示全部楼层
    nimo 发表于 2022-3-16 13:47
    大哥 今天网站更新了 用不了了 能更新下插件吗

    超星之前连续三次都是针对我更新的
    没法玩了
    暂时没更新计划了哦
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    1

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2022-3-18 14:32:14 | 显示全部楼层
    道哥,学这个需要什么语言作为基础呢
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-18 15:15:44 | 显示全部楼层
    arootwzz 发表于 2022-3-18 14:32
    道哥,学这个需要什么语言作为基础呢

    一般来说会js就够了
    按指南目录看到哪不会查哪其实也可以的
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    回帖

    15

    积分

    助理工程师

    积分
    15
    发表于 2022-3-26 17:35:13 | 显示全部楼层
    虽然看不懂,但能被超星针对打补丁的,牛的不说了
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2022-3-26 18:13:25 | 显示全部楼层
    815132496 发表于 2022-3-26 17:35
    虽然看不懂,但能被超星针对打补丁的,牛的不说了

    呜呜呜
    牌面就完事了!
    谢谢哥哥!
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表