李恒道 发表于 2021-8-21 23:43:34

[油猴脚本开发指南]XHR实战百度自定义分享码

# FBI WARNING

这个例子是临时写的,没有做关键的判断以及匹配,请不要用于实际,否则会极大的影响百度网盘的使用体验(虽然50KB也没什么体验了)

# 正文

我们在使用之前可以先看一下代码

```javascript
function addXMLRequestCallback(callback){
    var oldSend, i;
    if( XMLHttpRequest.callbacks ) {
      // we've already overridden send() so just add the callback
      XMLHttpRequest.callbacks.push( callback );
    } else {
      // create a callback queue
      XMLHttpRequest.callbacks = ;
      // store the native send()
      oldSend = XMLHttpRequest.prototype.send;
      // override the native send()
      XMLHttpRequest.prototype.send = function(){
            // process the callback queue
            // the xhr instance is passed into each callback but seems pretty useless
            // you can't tell what its destination is or call abort() without an error
            // so only really good for logging that a request has happened
            // I could be wrong, I hope so...
            // EDIT: I suppose you could override the onreadystatechange handler though
            for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                XMLHttpRequest.callbacks( this );
            }
            // call the native send()
            if(arguments.length!==0){
                if(arguments!==null&&arguments.indexOf!==undefined){
                  if(arguments.indexOf('pwd')!==-1&&arguments.indexOf('vcode')===-1){
                        var number=prompt("输入默认修改的四位分享码,默认:8888","8888")
                        if(number.length!==4)
                        {
                            number='8888'
                        }
                        arguments=arguments.replace(/pwd={0,4}&/i,"pwd="+number+"&")
                  }
                }
            }
                console.log('arguments',arguments)
            oldSend.apply(this, arguments);
      }
    }
}

// e.g.
addXMLRequestCallback( function( xhr ) {
      xhr.addEventListener("load", function(){
      if ( xhr.readyState == 4 && xhr.status == 200 ) {
            console.log( xhr.responseURL );
      }
    });

});
```

这里依然是使用我们的js劫持例子,通常我喜欢直接贴上xhr劫持的demo然后在基础上修改

传入那个没用的函数是为了方便打印出劫持到的url,更好的分析我们的代码执行

## 小提示

通常我们运行劫持脚本后在堆栈跟踪里看到了我们的脚本名字就是代表已经成功劫持了,如果发现没有成功劫持,可能是在脚本劫持之前已经被网页获取到了xhr,这个时候我们可以考虑使用runat抢先执行试图(让我们比比谁的剑更快!)

![图片.png](data/attachment/forum/202108/21/233214ilfusfllsfzhaewv.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

那我们如何判断一个post是否是xhr呢?

![图片.png](data/attachment/forum/202108/21/233410xu4993g5dckgcjm2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

好了!你学会了!

我们这里代码最核心的部分就是

```javascript
if(arguments.length!==0){
                if(arguments!==null&&arguments.indexOf!==undefined){
                  if(arguments.indexOf('pwd')!==-1&&arguments.indexOf('vcode')===-1){
                        var number=prompt("输入默认修改的四位分享码,默认:8888","8888")
                        if(number.length!==4)
                        {
                            number='8888'
                        }
                        arguments=arguments.replace(/pwd={0,4}&/i,"pwd="+number+"&")
                  }
                }
            }
                console.log('arguments',arguments)
```

arguments是对send传入的参数,我们首先判断长度是否为0,如果不为0就执行

arguments纯属我多此一举进行判断的,这里的判断条件大家可以根据自己的需求逐渐的修正判断条件。大家不要在意细节

判断是否存在indexOf函数则是接下来我们使用了indexOf函数,他是一个属于字符串对象使用的函数,一些其他对象是不存在这个函数的,所以我们最好对使用的函数进行判断。

arguments.indexOf('pwd')!==-1&&arguments.indexOf('vcode')===-1

如果判断存在pwd和vcode,就执行下一步,这是我们在f12抓包的提交数据里看到的,我挑了几个关键的字符进行判断,但是依然可能在其他功能上出现错误,其实更好的办法可以通过url判断。
var number=prompt("输入默认修改的四位分享码,默认:8888","8888")
if(number.length!==4)
{
number='8888'
}

提示用户输入分享码,如果长度不为4或不输入默认8888

arguments=arguments.replace(/pwd={0,4}&/i,"pwd="+number+"&")

这里我对提交的字符串使用了replace,replace是字符串的替换函数,/pwd={0,4}&/i 是什么意思的,这个是一个正则表达式,因为不涉及教程的内容,所以我大概对这条进行讲解,前后的/和/i可以忽略,/i是忽略大小写的意思,pwd=和&都是一个固定的字符串,唯一变动搜索的就是{0,4}

[]内表示搜索字符可以是括号内的任意一个字符,A-Z表示大写A到Z,a-z表示小写a-z,0-9表示数字0-9,说明我们匹配的字符可以是A到Z,a-z,0-9之中的任意一个字符,而{0,4}表示我们会匹配到0个到4个这样的字符,将pwd={0,4}&匹配的内容替换成"pwd="+number+"&",其实这里非常简单,就是把默认的提取码替换成用户自定义的提取码并且提交就没了。

那到这里我们就大概学习了xhr的各种劫持姿势

通常对原型链进行劫持,可以获取xhr返回的内容,以及篡改xhr提交的内容

而使用proxy或object.defineproperty可以对函数返回的内容进行一个劫持。

# 结语

撒花~

李恒道 发表于 2021-8-22 00:31:05

关于正则我挑了一个不错的教程
https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md

fai1988 发表于 2021-8-22 08:42:18

谢谢你的分享!

李恒道 发表于 2021-8-23 01:32:45

fai1988 发表于 2021-8-22 08:42
谢谢你的分享!

哥哥牛逼!

李恒道 发表于 2021-8-23 01:32:50

fai1988 发表于 2021-8-22 08:42
谢谢你的分享!

哥哥早点睡

rubinTime 发表于 2021-12-2 14:53:01

问下哥哥这个自定义百度提取码有什么作用,是我提交xhr前弹出prompt让我输入提取码替换我在文本框中输入的提取码吗,可是后端的返回的提取码难倒不是固定的吗,我改前端的xhr参数有什么用,还是我理解错了

李恒道 发表于 2021-12-2 15:26:37

rubinTime 发表于 2021-12-2 14:53
问下哥哥这个自定义百度提取码有什么作用,是我提交xhr前弹出prompt让我输入提取码替换我在文本框中输入的 ...

他是前端生成提取码传给后端,也就是说你hook掉提取码,设置什么,到时候提取码就是什么

rubinTime 发表于 2021-12-2 15:32:55

李恒道 发表于 2021-12-2 15:26
他是前端生成提取码传给后端,也就是说你hook掉提取码,设置什么,到时候提取码就是什么 ...

那是不是别人分享资源定义的提取码可以被我修改,我可以直接访问他的资源

李恒道 发表于 2021-12-2 15:39:25

rubinTime 发表于 2021-12-2 15:32
那是不是别人分享资源定义的提取码可以被我修改,我可以直接访问他的资源 ...

不可以,这个是在生成的时候修改的提取码
验证的时候禁止修改提取码的

rubinTime 发表于 2021-12-2 15:46:54

李恒道 发表于 2021-12-2 15:39
不可以,这个是在生成的时候修改的提取码
验证的时候禁止修改提取码的

生成提取码的时候自己不就已经知道提取码了吗
页: [1] 2
查看完整版本: [油猴脚本开发指南]XHR实战百度自定义分享码