安卓 逆向高级-人均瑞数

引言:

JS 爬虫,绕不过瑞数这道坎,卡的死死的。一般网上的教程就是补环境什么的,我尝试了,可以但是比较麻烦。 今天说一种,秒过的方式,抗并发。那就是牛逼的RPC,hook JS 技术。

前期准备:

  1. 安装nodejs

下载地址:

Node.js — Run JavaScript Everywhere

安装依赖

npm install ws

npm  install express

  1. Google浏览器

F12 调试,会反反调试

  1. 代码1,NodeJS 端

完成1,组装http服务,提供对外接口,方便其他地方直接调用. 2 ,监控websocket 服务,与hook 的js 交互,http服务连接websocket,websocket 连接hookjs, js 直接调用网站的协议。

代码:

global.navigator = {appName: 'nodejs'}; // fake the navigator object

global.window = {}; // fake the window object

const express=require('express');

const server=express();

const bodyParser = require('body-parser');

server.listen(8093,'0.0.0.0',function(){

    console.log('http://localhost:8093');

});

server.use(bodyParser.urlencoded({ extended: false })); //调用中间件

server.use(bodyParser.json())

 //import * as WebSocket from 'ws';

const WebSocket = require('ws')

const server1 = new WebSocket.Server({ port: 8013 });

console.log('begin')

server1.on('connection', (socket) => {

  console.log('New client connected');

  socket.on('message', (message) => {

    console.log(`Received message: ${message}`);

try {

    // 向所有客户端广播消息

    if(message.indexOf("ping") >=0 ) {

        server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            client.send("ping");

        }

        });

    }else if(message.indexOf("rep") >=0 ) {

       // global.retmsg = message;

       str = ` ${message}`

       var args = str.split('|');

       uuid = args[2]

       var tmpjs = JSON.parse(args[1])

       global.resps[uuid].json({code:1,message:'',data:tmpjs,uuid:uuid})

       global.resps[uuid] = null;

       // global.resp.json({code:1,message:'',data:str})

    }

}catch(error) {

console.log(error);

}

  });

  socket.on('close', () => {

    console.log('Client disconnected');

  });

});

global.resps = {}

function guid() {

    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {

        var r = Math.random() * 16 | 0,

            v = c == 'x' ? r : (r & 0x3 | 0x8);

        return v.toString(16);

    });

}

global.server = server1

server.post('/list',function(req,resp){

    console.log("list 接收参数:" + req.body + new Date());

    //global.resp = undefined;

   // uuid = guid();

   uuid = req.body.uuid;

    server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            global.retmsg = "";

            client.send("list|"+JSON.stringify(req.body) +"|" + uuid);

        }

        });       

        global.resps[uuid] =  resp

    }

 );

const WebSocket = require('ws')

const server1 = new WebSocket.Server({ port: 8013 });

监听 websocket 端口 8013

这个是心跳包,网页js 与 nodejs 保持连接,保持心跳用

  // 向所有客户端广播消息

    if(message.indexOf("ping") >=0 ) {

        server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            client.send("ping");

        }

        });

    }

// 这个是定义的websocket 返回,接收到websocket 返回,然后发送给 http 客户端。

}else if(message.indexOf("rep") >=0 ) {

       // global.retmsg = message;

       str = ` ${message}`

       var args = str.split('|');

       uuid = args[2]

       var tmpjs = JSON.parse(args[1])

       global.resps[uuid].json({code:1,message:'',data:tmpjs,uuid:uuid})

       global.resps[uuid] = null;

       // global.resp.json({code:1,message:'',data:str})

    }

// 这里定义一个对外http 服务,list就是 http://localhost:8093/list , 参数json格式

{ “data”:”11”,”uuid”:”333”}, 有一个全局变量   global.resps, 他这样存储   global.resps[uuid] =  resp 一个uuid 即一个http客户端的变量,方便从websocke他得到返回之后,直接给他发送消息。

  client.send("list|"+JSON.stringify(req.body) +"|" + uuid); ,这个是http 收到数据,直接发送给websocket 即js 客户端就行。

server.post('/list',function(req,resp){

    console.log("list 接收参数:" + req.body + new Date());

   uuid = req.body.uuid;

    server1.clients.forEach((client) => {

        if (client.readyState === WebSocket.OPEN) {

            global.retmsg = "";

            client.send("list|"+JSON.stringify(req.body) +"|" + uuid);

        }

        });       

        global.resps[uuid] =  resp

    }

 );

  1. 代码2, js hook 端
  1. 1 先来看下一个实例网站。

启动器,定位到请求位置所在。

//跟踪进去代码,是直接发送ajax,那一分钟就搞定。瑞数就是说他会hook ajax send 函数,添加头,添加cookie 之类的。我们搞不顶瑞数,但是可以写ajax 请求啊

2.2 js 端代码:

function patch_ruishu(url){

    console.log("RPC args:"+url);

    var v = [];

    v.push(window.hc_url(url));

    v.push(window.hc_cook(945, 10,false));

    return v;

}

// 闭包

!function (a) {

    // Promise是一种用于处理异步操作的机制

    // 该函数接受两个参数:resolve和reject。

    // resolve是一个函数,用于将Promise从挂起状态转换为已解决状态(fulfilled),并返回解决结果(通常是异步操作的结果)。

    // reject是一个函数,用于将Promise从挂起状态转换为已拒绝状态(rejected),并返回拒绝原因(通常是异步操作的错误信息)。

    new Promise((e, s) => {

            e(a)

        }

    ).then((myFunction) => {

            var cbb_MyId = "1001";

            // 执行下面语句之后,客户端就会与服务器进行连接。

            ws = new WebSocket("ws://127.0.0.1:8013");

            // 指定连接成功后的回调函数

            ws.onopen = function () {

                console.log("服务器连接成功!");

                // send 向服务器发送数据

             

                

               

                setInterval(function () {

                    ws.send(cbb_MyId+'ping---'+"connect");

                }, 5000)

                

            }

            ;

            window.ws = ws;

            // 收到服务器数据后的回调函数。

            ws.onmessage = function (evt) {

                if (evt.data.indexOf("ping") >= 0) {

                    console.log('ping')

                    return;

                }

                console.log('传入数据: ' + evt.data);

                if(evt.data.indexOf("list") >=0 ) {

                    //调用方法

                    var args = evt.data.split('|');

                    console.log(args[1]);

                    var reqdata = JSON.parse(args[1]);

                   try {

                    var serviceNbr = reqdata.mobile;

                    var param ="userInfo.loginType=4&userInfo.serviceNbr="+serviceNbr+"&flag=0&chargeType=undefined"

                    

                    var code = mycode(serviceNbr.replace(/ /g,""),"7");

                    param=param+"&key="+code;

                    $.ajax({

                        type:'POST',

                        url:"https://ah.189.cn/service/pay/findByUser.action",

                        data:param,

                        dataType:'json',

                        cache:false,

                        //async:false,

                        success:function (data) {

                       

                            if(data.flag == '0'){

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }else {

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }

                        }

                        });

                    }catch(e) {

                        console.log(e)

                    }

                   

$.ajax({

                    type: "POST",

                    contentType: "application/x-www-form-urlencoded;charset=utf-8",

                    url: path + "/service/index/getDistrictBargain.action",

                    dataType: "json",

                    success: function(data) {

                        var listDistrictBargain = data.listDistrictBargain;

                        var page = data.page;

                        ws.send("rep|"+ JSON.stringify(page)+ "|" + args[2])

                    },

                    error: function() {

                    }

                });

                }

            };

            // 连接关闭后的回调函数

            ws.onclose = function () {

                console.log("rpc已经断开了哦");

            };

            // 连接错误后的回调函数

            ws.onerror = function () {

                console.log("rpc已经断开了哦");

            };

        }

    )

    ;

}(patch_ruishu)  // 这里填返回加密数据的js函数名字

初始化websocket ,然后连上刚才的nodejs

   ws = new WebSocket("ws://127.0.0.1:8013");

            // 指定连接成功后的回调函数

            ws.onopen = function () {

                console.log("服务器连接成功!");

                // send 向服务器发送数据

             

                

               

                setInterval(function () {

                    ws.send(cbb_MyId+'ping---'+"connect");

                }, 5000)

                

            }

            ;

  1. 收到请求:

   if(evt.data.indexOf("list") >=0 ) {

                    //调用方法

                    var args = evt.data.split('|');

                    console.log(args[1]);

                    var reqdata = JSON.parse(args[1]);

                   try {

                    var serviceNbr = reqdata.mobile;

                    var param ="userInfo.loginType=4&userInfo.serviceNbr="+serviceNbr+"&flag=0&chargeType=undefined"

                    

                    var code = mycode(serviceNbr.replace(/ /g,""),"7");

                    param=param+"&key="+code;

                    $.ajax({

                        type:'POST',

                        url:"https://ah.189.cn/service/pay/findByUser.action",

                        data:param,

                        dataType:'json',

                        cache:false,

                        //async:false,

                        success:function (data) {

                       

                            if(data.flag == '0'){

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }else {

                                ws.send("rep|"+ JSON.stringify(data)+ "|" + args[2])

                            }

                        }

                        });

                    }catch(e) {

                        console.log(e)

                    }

                   

$.ajax({

                    type: "POST",

                    contentType: "application/x-www-form-urlencoded;charset=utf-8",

                    url: path + "/service/index/getDistrictBargain.action",

                    dataType: "json",

                    success: function(data) {

                        var listDistrictBargain = data.listDistrictBargain;

                        var page = data.page;

                        ws.send("rep|"+ JSON.stringify(page)+ "|" + args[2])

                    },

                    error: function() {

                    }

                });

                }

  1. Node js 远程
  2. C# 远程。
  3. Js websocket 注意事项 如何hook, 如何页面reload ,如何替换js

高级防止 掉线问题,Ip 问题 ,浏览器指纹问题 抗并发,抗造。 如何生产部署,快速集成到csharpcef  框架

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yijianxiangde100

你的鼓励是对我创作最大的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值