声明:
该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关
WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它允许在客户端和服务器之间建立持久的连接,使得双方可以通过这个连接实时地交换数据。
与传统的HTTP请求-响应模式不同,WebSocket提供了一个长时间运行的连接,可以在客户端和服务器之间进行双向通信。这意味着服务器可以主动向客户端发送数据,而不需要客户端发起请求。这种实时性和双向通信的特性使得WebSocket在许多应用场景下非常有用,如实时聊天应用、在线游戏、股票市场报价等。
WebSocket协议建立在HTTP协议之上,使用HTTP的握手过程来建立连接,然后协议切换到WebSocket协议进行数据交换。WebSocket使用了一种轻量级的帧格式来传输数据,可以发送文本和二进制数据。它还支持心跳机制,以保持连接的活跃状态。
在Web开发中,通常使用WebSocket API来实现WebSocket通信。浏览器提供了WebSocket API,可以在JavaScript中使用它来创建WebSocket对象,建立连接并发送和接收数据。
总结起来,WebSocket是一种在Web浏览器和服务器之间实现实时、双向通信的协议,它允许长时间运行的连接,支持服务器主动推送数据,适用于许多实时性要求较高的应用场景。
//与服务器约定的连接 以及端口本机的 hosts
const socket = new WebSocket('ws://127.0.0.1:8080/')
//连接发生错误的回调方法
socket.onerror = () => {
console.log("WebSocket连接发生错误");
};
//连接成功建立的回调方法
socket.onopen = function () {
console.log("WebSocket连接成功");
}
//接收到消息的回调方法 接收服务器的数据
socket.onmessage = function (event) {
console.log(event.data);
socket.send('浏览器')
}
//连接关闭的回调方法
socket.onclose = function () {
console.log("WebSocket连接关闭");
}
import asyncio
import websockets
async def echo(websocket):
# 使用WebSocket在客户端和服务器之间建立全双工双向连接后,就可以在连接打开时调用send()方法。
message = 'hello world'
# 发送数据
await websocket.send(message)
return True
async def recv_msg(websocket):
while 1:
# 接收数据
recv_text = await websocket.recv()
print(recv_text)
async def main_logic(websocket, path):
await echo(websocket)
await recv_msg(websocket)
start_server = websockets.serve(main_logic, '127.0.0.1', 8080)
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
# 创建了一个连接对象之后,需要不断监听返回的数据,则调用 run_forever 方法,要保持长连接即可
loop.run_forever()
import asyncio
import websockets
async def echo(websocket):
# 使用WebSocket在客户端和服务器之间建立全双工双向连接后,就可以在连接打开时调用send()方法。
message = 'socket连接成功'
# 发送数据
await websocket.send(message)
return True
async def recv_msg(websocket):
while 1:
# 接收数据
recv_text = await websocket.recv()
print(recv_text)
async def main_logic(websocket, path):
await echo(websocket)
await recv_msg(websocket)
start_server = websockets.serve(main_logic, '127.0.0.1', 8080)
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
# 创建了一个连接对象之后,需要不断监听返回的数据,则调用 run_forever 方法,要保持长连接即可
loop.run_forever()
(function () {
const websocket = new WebSocket('ws://127.0.0.1:8080');
websocket.onopen = function () {
console.log("WebSocket连接成功");
};
// 接收服务端发送的信息
websocket.onmessage = function (event) {
const data = window.reponse_decrypt(event.data);
console.log("发送数据")
// 发送解密数据给服务端
websocket.send(data)
}
})();
RPC 在逆向中,简单来说就是将本地和浏览器,看做是服务端和客户端,二者之间通过 WebSocket 协议进行 RPC 通信,在浏览器中将加密函数暴露出来,在本地直接调用浏览器中对应的加密函数,从而得到加密结果,不必去在意函数具体的执行逻辑,也省去了扣代码、补环境等操作,可以省去大量的逆向调试时间。
这里使用 Sekiro-RPC 说明RPC在爬虫中的应用, Sekiro-RPC 官网:https://sekiro.iinti.cn/sekiro-doc/,
// 生成唯一标记uuid编号
function guid() {
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
// 连接服务端
var client = new SekiroClient("ws://127.0.0.1:5620/business-demo/register?group=ws-group&clientId="+guid());
// 业务接口
client.registerAction("clientTime",function(request, resolve, reject){
resolve(""+new Date());
})
// ==UserScript==
// @name Sekiro-RPC
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Sekiro-RPC爬虫应用
// @author You
// @match https://extfans.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=extfans.com
// @grant none
// @require http://file.virjar.com/sekiro_web_client.js?_=123
// @run-at document-start
// @author CC11001100
// @match *://*/*
// ==/UserScript==
(function() {
'use strict';
function guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}
var client = new SekiroClient("ws://127.0.0.1:5620/business-demo/register?group=sekiro&clientId=" + guid());
client.registerAction("rpc", function (request, resolve, reject) {
resolve(window.reponse_decrypt(request.param));
})
})();