很久没写技术型博文了,最近一直在研究java的第三方jar包jpacp。想研究研究这玩意是否能实现局域网搜索。经过20多天的努力,将几个技术难点通通解决,最终得出结论,完全可以用它来实现局域网互连,只是如果做出来后,没有著名的WarSeacher那么简洁,精巧,方便。因为它比较依赖于安装环境,1,必须装wincacp 2、必须装jdk。3.界面的美观与操作性也是个问题。
下面我将列出这些天攻克的技术难点。
第一。怎么抓war发送的搜索包,地图包,与建主包。是需要用java写,还是利用开源的项目。
第二。抓到包以后需不需要自己解析,然后发给war,告诉它这是我解析后的包。
第三。抓到以后在局域网里能看到,但你点击它就是无法加入游戏。
很幸运的,我在网上找到了java语言的第三方jar包,后来经过仔细研究源代码,发现可以干很多底层的事情,比如,发送带ip报头的数据包,修改,ip报头的ip地址。
先说解决的难点。利用jpacp抓网络上的包。先声明下,以下的所有环节,都是建立在先装好wincacp,jdk,jpacp的环境上的。(有些图片不能即时插入到对应的文字下面,就只好都放到附件里面了,大家对应着看吧)
利用jpacp的抓包程序
package com.lyh.test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import com.lyh.common.Util;
import jpcap.*;
import jpcap.packet.IPPacket;
import jpcap.packet.Packet;
import jpcap.packet.UDPPacket;
class Tcpdump implements PacketReceiver {
public static Packet packet ;
public static NetworkInterface[] devices = JpcapCaptor.getDeviceList();
public static JpcapSender jp;
public void receivePacket(Packet packet) {
this.packet = packet;
System.out.println("======================================");
System.out.println(packet);
System.out.println("sec --"+packet.sec);
System.out.println("uec --"+packet.usec);
System.out.println("datalink dst_mac[]--"+packet.datalink);
System.out.println("datalink src_mac[]--"+packet.datalink);
System.out.println("header --" +" length--"+ packet.header.length + "--" + Arrays.toString(packet.header));
System.out.println("data --"+" length--" +packet.data.length + " --"+ Arrays.toString(packet.data));
System.out.println("len --" + packet.len);
System.out.println("caplen -- " + packet.caplen);
System.out.println("header[] --"+Util.bytesToHexString(packet.header));
System.out.println("data[] --"+Util.bytesToHexString(packet.data));
System.out.println("======================================");
System.out.println();
try {
Thread.sleep(1);
IPPacket ip = (IPPacket)packet ;
try {
ip.setIPv4Parameter(ip.priority, ip.d_flag, ip.t_flag, ip.r_flag, ip.rsv_tos, ip.rsv_frag, ip.dont_frag, ip.more_frag, ip.offset, ip.ident, ip.hop_limit, ip.protocol, InetAddress.getByName("172.29.31.202"), ip.dst_ip);
} catch (UnknownHostException e) {
e.printStackTrace();
}
jp.sendPacket(ip);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
if(args.length>1){
for (int i = 0; i < devices.length; i++) {
System.out.println("the index '"+i+"' :"+devices[i].name + "(" + devices[i].description+")");
System.out.println(" data link:"+devices[i].datalink_name + "("
+ devices[i].datalink_description+")");
System.out.print(" MAC address:");
for (byte b : devices[i].mac_address)
System.out.print(Integer.toHexString(b&0xff) + ":");
System.out.println();
for (NetworkInterfaceAddress a : devices[i].addresses)
System.out.println(" address:"+a.address + " " + a.subnet + " "
+ a.broadcast);
}
}else{
JpcapCaptor jpcap = JpcapCaptor.openDevice(devices[0], 1024 * 10 , false, 20);
jpcap.setFilter("host 172.29.31.211", true);
jp = JpcapSender.openDevice(devices[0]);
jpcap.loopPacket(-1, new Tcpdump());
}
}
}
这段代码我整了好久的,主要是分析抓到的包里面的data是什么东西,因为都是16进制的,所以,在网上查了好多资料,才弄明白对应的都是什么意思。这是我用txt文档记录的一些日志。
客户端收到从主机发来的包: f7 32 10 00 03 00 00 00 01 00 00 00 0a 00 00 00 (我建主了)
客户端向主机发送的搜索包: F7 2F 10 00 50 58 33 57 15 00 00 00 00 00 00 00 (我看看你建的什么主)
Dota /6.74c 版本的地图包:
f7 30 9e 00 50 58 33 57 0-7
18 00 00 00 02 00 00 00 8-15
e2 1c fd 0d 74 65 73 74 16-23
20 70 6c 61 79 20 64 6f 24-31
74 61 20 62 79 20 6c 69 32-39
79 61 68 75 69 2e 8f 20 40-47
28 77 77 00 00 01 03 49 48-55
07 01 01 77 01 91 79 01 56-63
e3 f1 8f 87 4d cb 61 71 64-71
73 5d 45 6f 77 19 6f 6d 72-79
6f 61 65 5d 45 0b 6f 75 80-87
41 21 77 37 2f 6b 37 35 88-95
63 2f 77 33 79 9d 01 77 96-103
77 77 63 63 73 f1 01 01 104-111
ff 19 e7 f1 71 73 d1 e5 112-119
07 8b 97 e1 27 07 b3 c7 120-127
1f 1f 89 9d a5 01 f1 00 128-135
0a 00 00 00 01 00 00 00 136-143
01 00 00 00 0a 00 00 00 144-151
63 00 00 00 e0 17 152-157
地图包的byte类型 :
-9, 48, -98, 0, 80, 88, 51, 87, 24, 0, 0-9
0, 0, 1, 0, 0, 0, 114, -27, 101, 11, 10-19
116, 101, 115, 116, 32, 112, 108, 97, 121, 32, 20-29 // 从第二十个开始,32个 游戏信息,大部分是:“当地局域网内游戏(X……”
100, 111, 116, 97, 32, 98, 121, 32, 108, 105, 30-39
121, 97, 104, 117, 105, 46, -113, 32, 40, 119, 40-49
119, 0, 0, 1, 3, 73, 7, 1, 1, 119, 50-59
1, -111, 121, 1, -29, -15, -113, -121, 77, -53, 60-69 // 从69个开始,地图路径,大概32个
97, 113, 115, 93, 69, 111, 119, 25, 111, 109, 70-79
111, 97, 101, 93, 69, 11, 111, 117, 65, 33, 80-89
119, 55, 47, 107, 55, 53, 99, 47, 119, 51, 90-99
121, -99, 1, 119, 119, 119, 99, 99, 115, -15, 100-109
1, 1, -1, 25, -25, -15, 113, 115, -47, -27, 110-119
7, -117, -105, -31, 39, 7, -77, -57, 31, 31, 120-129
-119, -99, -91, 1, -15, 0, 10, 0, 0, 0, 130-139
1, 0, 0, 0, 1, 0, 0, 0, 10, 0, 140-149
0, 0, -71, 0, 0, 0, -32, 23 150-157
不过后来我才发现,有现成的东西去截取网络数据包,并能很好的分析它。CommView就是一款很好的IP包捕获,分析软件。我后来就都是用它来监测的,非常好用,非常方便。附件里有CommView的截图
报文截取到了,当时那个兴奋啊。。好了,有数据了我就天天分析那些16进制代码,发现有地图包,但是打开war.exe后,在局域网里怎么也看不到我用javaw.exe程序发送的地图包,经过网上的资料搜索后,发现原来是地图版本的问题,在报文头里面有一个字节是代表war版本的,如果对不上,当然就看不到,所以我就改,改成了正确的版本。
public static byte[] warSearch = { (byte) 0xf7, 0x2f, 0x10, 0x00, 0x50,
0x58, 0x33, 0x57, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
这个0x18是1.24的版本,原来是0x14(是比较早的1.20的版本),改过来后,在魔兽局域网里代开一看,我了个擦,看到了发java建的主,也就是过javaw.exe发过来的数据包,那个兴奋劲哦。真过瘾。
好了,到了这一步,就碰到了最难,解决时间最长的问题。在局域网里点击那个java建的主之后,显示“无法加入游戏”。
我到网上查了资料,说是因为那个IP包里的IP是本机的IP,war收到后,相当于用本机的ip连本机的ip,所以当然不行。解决办法是,必须把那个src_ip也就是来源ip改掉,改成真正建主的ip。
经过一番努力,发现jpacp可以改,并且改成功了。
至于这个过程是比较辛苦,就不谈了,因为毕竟是一个人在干,什么都不明白,只能摸着石头过河,靠网上找资料,自己分析,实验,来检验网上的程序正确性。
我就直接贴代码吧。这是利用jpacp改IP包头的程序。经过测试,利用两台机器,一台机器建主,一台机器连主机,主机跑这个java程序,实验结果是可以连上。连上之后,我在公司控制主自己的兴奋,写了这篇文章。
package com.lyh.test;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Arrays;
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;
import jpcap.PacketReceiver;
import jpcap.packet.EthernetPacket;
import jpcap.packet.Packet;
import jpcap.packet.UDPPacket;
class TestWar4 implements PacketReceiver {
public static Packet packet ;
public static NetworkInterface[] devices = JpcapCaptor.getDeviceList();
public static JpcapSender jp;
static byte[] data;
static boolean t_flag = false;
public static byte[] warSearch = { (byte) 0xf7, 0x2f, 0x10, 0x00, 0x50,
0x58, 0x33, 0x57, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
public static byte[] replaceDataHead = { 0x00, 0x0B, 0x2F, 0x76, (byte) 0x8D,
0x21, 0x00, 0x23, (byte) 0xAE, (byte) 0xB4, (byte) 0xE0,
(byte) 0xD3, 0x08, 0x00, 0x45, 0x00, 0x00, (byte) 0xBA, 0x5B, 0x57,
0x00, 0x00, 0x40, 0x11, (byte) 0x86, (byte) 0xF0, (byte) 0xAC,
0x1D, 0x1F, (byte) 0xE7, (byte) 0xAC, 0x1D, 0x1F, (byte) 0xCA,
0x17, (byte) 0xE1, 0x17, (byte) 0xE0, 0x00, (byte) 0xA6, 0x0C, 0x6F };
public static byte[] src_mac = { 0x00,0x23, (byte)0xAE, (byte)0xB4,(byte)0xE0, (byte)0xD3};
public static byte[] dst_mac = { 0x00, 0x0B, 0x2F, 0x76, (byte)0x8D, 0x21};
public static byte[] src_port = {0x17,(byte) 0xE1};
public static byte[] dst_port = {0x17,(byte) 0xE0};
public static int len = 42;
DatagramSocket server;
DatagramPacket p;
void init() throws Exception{
server = new DatagramSocket(6113);
p = new DatagramPacket(warSearch, 16, InetAddress.getByName("172.29.31.202"), 6112);
server.send(p);
data = new byte[1024];
p = new DatagramPacket(data, data.length);
server.receive(p);
System.out.println("data[]:" + Arrays.toString(data));
t_flag = true;
}
public void receivePacket(Packet packet) {
try {
if (packet.toString().endsWith("6112") && t_flag) {
this.packet = packet;
Thread.sleep(1000);
UDPPacket udp = (UDPPacket) packet;
//1.改以太网头
EthernetPacket ep = (EthernetPacket)udp.datalink;
ep.src_mac = dst_mac;
ep.dst_mac = src_mac;
//2.修改IP头,将发包地址变为建主的IP。
udp.length = 187;
udp.setIPv4Parameter(udp.priority, udp.d_flag, udp.t_flag,
udp.r_flag, udp.rsv_tos, udp.rsv_frag, udp.dont_frag,
udp.more_frag, 0, 23383, udp.hop_limit,
udp.protocol, InetAddress.getByName("172.29.31.202"),
InetAddress.getByName("172.29.31.211"));
byte[] t_data = new byte[168];
for (int i = 0; i < t_data.length; i++) {
t_data[i] = data[i];
}
//3.改udp头
udp.dst_port = 6112;
udp.src_port = 6113;
udp.data = t_data;
udp.datalink = ep;
jp.sendPacket(udp);
System.out.println("发送完毕!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
JpcapCaptor jpcap = JpcapCaptor.openDevice(devices[0], 1024 * 10 , false, 20);
jpcap.setFilter("host 172.29.31.211", true);
jp = JpcapSender.openDevice(devices[0]);
TestWar4 t = new TestWar4();
t.init();
jpcap.loopPacket(-1, t);
}
}
以上几个关键点都解决了,相信开发出一个java写的魔兽局域网搜索器不是问题。
在这里先做个总结吧,以后有时间了,再开发出一套完整的客户端来。
还有,以上内容都是在工作时间写,由于近来公司刚结束完一个项目,所以一直比较闲,也没学公司的资料,就一直在偷偷的搞这个。写的比较粗糙,以后慢慢再改,仅供对jpacp,udp的学习参考。
- 大小: 7.6 KB
- 大小: 4.3 KB
- 大小: 32.4 KB
- 大小: 16.8 KB
- 大小: 91.6 KB
- 大小: 421.9 KB
- 大小: 607 KB
分享到:
相关推荐
局域网连接器的使用场景广泛,尤其在教育环境中,例如“校园网魔兽平台湖大专版”这样的应用,它可能是指在校园网络中搭建的魔兽争霸多人对战平台。通过局域网连接器,学生们无需依赖互联网,即可在校内快速组建游戏...
实现局域网连接,资源共享。如何实现局域网连接.
【魔兽局域网搜索器】是一款专为魔兽争霸玩家设计的实用工具,它允许用户在局域网环境中快速发现并连接到其他正在运行魔兽争霸游戏的服务器。这款搜索器的强大之处在于其高效的搜索算法和简单易用的界面,使得用户...
VBA 中调用 API 实现局域网连接的常用操作 在局域网中,经常需要访问其他机器上的文件,但是每次访问都需要打开固定路径的文件夹,这样非常不方便。使用 VBA 连接读取文件,可以解决这个问题。本文将介绍如何使用 ...
“局域网连接器 无需验证”正是为解决这一痛点而设计。它提供了一种快速连接局域网内设备的方式,使得用户不必担心复杂配置。该连接器的工作原理可能基于系统内置的网络发现和共享服务,如Windows系统的“网络发现”...
总的来说,局域网游戏连接器是局域网游戏社交的重要辅助工具,它解决了玩家在连接游戏时遇到的技术难题,使得局域网内的多人游戏变得更加便捷和愉快。对于喜欢线下聚会玩游戏的朋友们来说,这种工具无疑是提高游戏...
局域网连接方案 实用 局域网连接方案 实用 局域网连接方案 实用 局域网连接方案 实用
VS2008版的C#通过局域网连接Access数据库,www.codefans.net截图所示,跨局域网的连接是通过查找数据源开始的。第一步配置数据源,先输入局域网电脑IP地址、登录名及密码,然后进入下一步,输入本机数据源用户名和...
在IT领域,尤其是在网络管理和数据库应用中,"一键解决局域网共享,SQL2000局域网连接"是一个常见的需求,特别是对于中小企业和办公室环境。以下将详细阐述涉及的知识点。 首先,我们来理解局域网(LAN,Local Area...
根据自己设置打印机连接共享心得,记录设置步骤,供大家参考设置; 1、windows共享打印机设置图文教程 2、windows同一局域网连接打印机设置图文教程 3、windows不同局域网连接打印机设置图文教程
解决局域网共享方案解决局域网共享方案解决局域网共享方案解决局域网共享方案解决局域网共享方案
SQlSEVER2000 远程局域网连接数据库详细设置。
下面将详细介绍局域网连接数据库的基本原理、实现方法及关键知识点。 首先,我们要理解局域网的概念。局域网是一种在小范围内(如办公室、校园或建筑物内)构建的高速、高带宽的计算机网络,它提供了一种高效、便捷...
基于Qt实现局域网Socket通信系统源码。分别有服务端(Server)和客户端(Client) 服务端默认监听本机IP的6666端口 本人实测在linux(需防火墙开启端口)和windows下完美运行。基于Qt实现局域网Socket通信系统源码。...
以MFC为架构实现简单局域网聊天,输入对方的IP,直接和对方连接,从而实现通信
解决局域网共享.rar 解决局域网共享解决局域网共享
通过内网连另外一台机器的mysql服务, 确发现速度N慢! 等了大约几十秒才等到提示输入密码。非常急人,有没有办法可以解决局域网内mysql数据库连接慢呢?下面小编带领大家来解决此问题,感兴趣的朋友一起看看吧
STM项目_基于STM32通过ESP826实现WIFI局域网连接手机APP_实现温湿度检测+人体红外感应等功能_附项目源码+学习资料_优质项目实战
本文将深入探讨使用易语言进行局域网连接监控的技术细节,包括子程序的设计与实现。 首先,我们要明白“局域网连接监控”的核心目标是检测和记录局域网内的设备连接状态、网络流量、通信异常等信息。易语言局域网...
为了解决这个问题,WFilter的“局域网DHCP服务器扫描”插件提供了一种有效的解决方案。 一、DHCP服务器的作用和原理 DHCP服务器是一种网络服务,它可以动态地为客户机分配IP地址、子网掩码、网关地址、DNS服务器...