网页雷达:如何将web和逆向结合了
huarui网页雷达
写在前面
本项目完成于2025年9月,但是由于某些原因没有写成博客发不出来。现在风头过去了可以发了,所以把这篇文章发出来,也是记录一下学习。今后可能会回归web安全相关内容,暂时不搞逆向了。
项目
这里用一个前几年比较火的游戏————荒野行动 作为例子
效果图:

目录
|—–GameMaps
|–ConnectController.py
|–hy_web.e
|–XLC.html
|–XLC.png
hy_web.e
本地端:hy_web.e
本地端用e语言,主要是有现成的驱动,本人也是很早学过的,正好能熟练运用
这里主要是两个额外线程:读取数据线程和矩阵线程
数据读取模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| .版本 2
PlayerControler = 读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (模块地址 + #PlayerAddr) + 88) + 192) + 984) + 96) + 56) + 984) + 96) ' 调试输出 (“playcontroler”, PlayerControler, 进制_十到十六 (PlayerControler))
.判断循环首 (真) count = 读整数型 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (模块地址 + #PlayerAddr) + 88) + 192) + 984) + 96) + 56) + 984) + 104) ' 调试输出 (“count”, count, PlayerControler)
.计次循环首 (count, i) playerOffset = 读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (读长整数 (PlayerControler + 0 + (i - 1) × 8) + 224) + 48) + 64) + 64) + 8) + 208) ' 调试输出 (“player”, playerOffset, 进制_十到十六 (playerOffset))
playerPos = GetPos (playerOffset) ' 调试输出 (“playerpos”, playerPos.x, playerPos.y, playerPos.z)
加入成员 (临时数组, playerOffset)
.计次循环尾 ()
全_对象数组 = 临时数组 ' 调试输出 (全_对象数组)
清除数组 (临时数组) 延时 (1000)
.判断循环尾 ()
|
矩阵读取:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| .版本 2 .版本 2
.子程序 Matrix .局部变量 head, 长整数型 .局部变量 矩阵集合, 字节集 .局部变量 临时矩阵, 小数型, , "4,4" .局部变量 Martixaddr, 长整数型
.判断循环首 (真) Martixaddr = 进制_十六到十 (“0C7EF728”) 矩阵集合 = 读字节集 (Martixaddr, 64)
临时矩阵 [1] [1] = 取字节集数据 (矩阵集合, #小数型, 1) 临时矩阵 [1] [2] = 取字节集数据 (矩阵集合, #小数型, 5) 临时矩阵 [1] [3] = 取字节集数据 (矩阵集合, #小数型, 9) 临时矩阵 [1] [4] = 取字节集数据 (矩阵集合, #小数型, 13)
临时矩阵 [2] [1] = 取字节集数据 (矩阵集合, #小数型, 17) 临时矩阵 [2] [2] = 取字节集数据 (矩阵集合, #小数型, 21) 临时矩阵 [2] [3] = 取字节集数据 (矩阵集合, #小数型, 25) 临时矩阵 [2] [4] = 取字节集数据 (矩阵集合, #小数型, 29)
临时矩阵 [3] [1] = 取字节集数据 (矩阵集合, #小数型, 33) 临时矩阵 [3] [2] = 取字节集数据 (矩阵集合, #小数型, 37) 临时矩阵 [3] [3] = 取字节集数据 (矩阵集合, #小数型, 41) 临时矩阵 [3] [4] = 取字节集数据 (矩阵集合, #小数型, 45)
临时矩阵 [4] [1] = 取字节集数据 (矩阵集合, #小数型, 49) 临时矩阵 [4] [2] = 取字节集数据 (矩阵集合, #小数型, 53) 临时矩阵 [4] [3] = 取字节集数据 (矩阵集合, #小数型, 57) 临时矩阵 [4] [4] = 取字节集数据 (矩阵集合, #小数型, 61)
矩阵数组 = 临时矩阵
延时 (1)
' 调试输出 (“矩阵”, 临时矩阵)
.判断循环尾 ()
|
主线程负责转换成json并分发数据,这里采用tcp连接。按照需求应该用udp更好,不过这里对udp不太支持,所以只能略微牺牲一下速度了。
主线程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| .版本 2
.子程序 Drew .局部变量 Aaary, 长整数型, , "0" .局部变量 count, 整数型 .局部变量 i, 整数型 .局部变量 Object, 长整数型 .局部变量 pos, Vector3D .局部变量 rect, Vector4D .局部变量 数据, 类_json
' 绘制文本 (50, 50, “花蕊绘制-开源版”, #绿色, 30) 移动窗口 (句柄, 窗口矩形.左边, 窗口矩形.顶边, 窗口矩形.宽度 - 窗口矩形.左边, 窗口矩形.高度 - 窗口矩形.顶边, 假) 取窗口矩形_ (窗口句柄, 窗口矩形)
屏幕X = (窗口矩形.宽度 - 窗口矩形.左边) ÷ 2 屏幕Y = (窗口矩形.高度 - 窗口矩形.顶边) ÷ 2
Aaary = 全_对象数组 count = 取数组成员数 (Aaary) .计次循环首 (count, i) Object = Aaary [i] pos = GetPos (Object) 数据.清除 () 数据.置属性数值 (“id”, Object) 数据.置属性数值 (“x”, pos.x) 数据.置属性数值 (“y”, pos.y)
客户1.发送数据 (数据.取数据文本 () + #换行符)
.计次循环尾 ()
|
COnnectController.py
服务端,比较简陋,用ssti搭建,用于接受json并且返回给前端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| import asyncio import json import websockets
web_clients = set()
async def websocket_handler(websocket): print("前端连接成功") web_clients.add(websocket) try: async for _ in websocket: pass finally: web_clients.remove(websocket) print("前端断开连接")
async def handle_tcp(reader, writer): addr = writer.get_extra_info('peername') print(f"TCP客户端连接: {addr}")
buffer = "" try: while True: data = await reader.read(1024) if not data: break
buffer += data.decode()
while "\n" in buffer: msg, buffer = buffer.split("\n", 1) msg = msg.strip() if not msg: continue
print(f"收到 TCP 消息: {msg}")
try: player_data = json.loads(msg)
if web_clients: await asyncio.gather(*[ ws.send(json.dumps(player_data)) for ws in web_clients ])
except json.JSONDecodeError: print("收到的不是有效 JSON:", msg)
except Exception as e: print("TCP错误:", e) finally: print("TCP客户端断开:", addr) writer.close() await writer.wait_closed()
async def main():
ws_server = await websockets.serve(websocket_handler, "0.0.0.0", 8765)
tcp_server = await asyncio.start_server(handle_tcp, "0.0.0.0", 9000)
print("✅ WebSocket 服务器运行在 ws://0.0.0.0:8765") print("✅ TCP 服务器运行在 tcp://0.0.0.0:9000")
async with ws_server, tcp_server: await asyncio.gather(ws_server.wait_closed(), tcp_server.serve_forever())
if __name__ == "__main__": asyncio.run(main())
|
前端
前端这一块主要使用leaflet.js作为地图引擎。这个还真挺不错的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>游戏实时地图</title> <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/> <style> #map { height: 100vh; width: 100vw; } .player-marker { width: 12px; height: 12px; background: red; border-radius: 50%; border: 2px solid white; } </style> </head> <body> <div id="map"></div> <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script> <script>
const minX = -3989, maxX = -3563; const minY = -21, maxY = 405;
const map = L.map('map', { crs: L.CRS.Simple, minZoom: -2, maxZoom: 4, zoomSnap: 0.1, });
const imageUrl = 'XLC.png'; const imageBounds = [[minY, minX], [maxY, maxX]]; L.imageOverlay(imageUrl, imageBounds).addTo(map); map.fitBounds(imageBounds);
const players = {}; function updatePlayer(id, x, y) { if (players[id]) { players[id].setLatLng([y, x]); } else { const marker = L.marker([y, x], { icon: L.divIcon({ className: 'player-marker' }) }).addTo(map); players[id] = marker; } }
const ws = new WebSocket("ws://localhost:8765");
ws.onmessage = (event) => { const data = JSON.parse(event.data); updatePlayer(data.id, data.x, data.y); };
</script> </body> </html>
|
最后呈现效果如图:

写在后面
Q:为什么不用绘制,而是写成网页雷达呢?
A:因为弥赛亚引擎是闭源引擎,目前找到的矩阵是尼玛3*4矩阵,市面上没有开源的转屏幕算法。我们这种散修师傅只能另寻出路,搞点简单的。
另外感谢网友车神,我和他一起研究的弥赛亚引擎,也是交上共同学习的好友了哈哈