From 55cf3cd475e9338f53c26d1ae4b7e884cb4f3474 Mon Sep 17 00:00:00 2001 From: UnfamiliarLegacy <74633542+UnfamiliarLegacy@users.noreply.github.com> Date: Fri, 21 Jun 2024 21:10:33 +0200 Subject: [PATCH] Simple packet injection --- .../java/gearth/protocol/HConnection.java | 2 +- .../main/java/gearth/protocol/HPacket.java | 14 ++-- .../proxy/shockwave/ShockwaveProxy.java | 6 +- .../shockwave/packets/ShockPacket.java | 78 ++++++++++++++----- .../services/always_admin/AdminService.java | 3 +- .../subforms/injection/InjectedPackets.java | 11 ++- .../injection/InjectionController.java | 18 +++-- 7 files changed, 94 insertions(+), 38 deletions(-) diff --git a/G-Earth/src/main/java/gearth/protocol/HConnection.java b/G-Earth/src/main/java/gearth/protocol/HConnection.java index 5a7d1a1..a8ac816 100644 --- a/G-Earth/src/main/java/gearth/protocol/HConnection.java +++ b/G-Earth/src/main/java/gearth/protocol/HConnection.java @@ -20,7 +20,7 @@ import java.util.function.Consumer; public class HConnection { public static volatile boolean DECRYPTPACKETS = true; - public static volatile boolean DEBUG = true; + public static volatile boolean DEBUG = false; private volatile ExtensionHandler extensionHandler = null; diff --git a/G-Earth/src/main/java/gearth/protocol/HPacket.java b/G-Earth/src/main/java/gearth/protocol/HPacket.java index a6c6d5a..bfe448f 100644 --- a/G-Earth/src/main/java/gearth/protocol/HPacket.java +++ b/G-Earth/src/main/java/gearth/protocol/HPacket.java @@ -16,9 +16,9 @@ import java.util.Optional; public class HPacket implements StringifyAble { - private boolean isEdited = false; + protected boolean isEdited = false; protected byte[] packetInBytes; - private int readIndex = 6; + protected int readIndex = 6; // if identifier != null, this is a placeholder name for the type of packet, headerId will be "-1" private String identifier = null; @@ -31,16 +31,18 @@ public class HPacket implements StringifyAble { packetInBytes = packet.packetInBytes.clone(); isEdited = packet.isEdited; } - public HPacket(String packet) { + + public HPacket(String packet) { try { HPacket packetFromString = PacketStringUtils.fromString(packet); packetInBytes = packetFromString.packetInBytes; identifier = packetFromString.identifier; identifierDirection = packetFromString.identifierDirection; - } catch (InvalidPacketException e) { - packetInBytes = new byte[0]; + } catch (InvalidPacketException e) { + packetInBytes = new byte[0]; + } } -} + public HPacket(int header) { packetInBytes = new byte[]{0,0,0,2,0,0}; replaceShort(4, (short)header); diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/shockwave/ShockwaveProxy.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/shockwave/ShockwaveProxy.java index ae35369..ca3e7f2 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/shockwave/ShockwaveProxy.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/shockwave/ShockwaveProxy.java @@ -64,9 +64,11 @@ public class ShockwaveProxy implements ProxyProvider, ConnectionInterceptorCallb @Override public void onInterceptorConnected(Socket client, Socket server, HProxy proxy) throws IOException, InterruptedException { - logger.info("Shockwave connection has been intercepted."); + logger.info("Shockwave connection has been intercepted, starting proxy thread."); startProxyThread(client, server, proxy); + + logger.info("Stopped proxy thread."); } @Override @@ -83,7 +85,7 @@ public class ShockwaveProxy implements ProxyProvider, ConnectionInterceptorCallb client.setSoTimeout(0); client.setTcpNoDelay(true); - logger.info("Connected to shockwave server {}:{}", server.getRemoteSocketAddress(), server.getPort()); + logger.info("Connected to shockwave server {}:{}", server.getInetAddress().getHostAddress(), server.getPort()); final Semaphore abort = new Semaphore(0); diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java index 4c43c27..63a338f 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java @@ -3,41 +3,30 @@ package gearth.protocol.packethandler.shockwave.packets; import gearth.encoding.Base64Encoding; import gearth.protocol.HMessage; import gearth.protocol.HPacket; +import gearth.services.packet_info.PacketInfoManager; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.security.InvalidParameterException; public class ShockPacket extends HPacket { public ShockPacket(byte[] packet) { super(packet); + readIndex = 2; } public ShockPacket(HPacket packet) { super(packet); + readIndex = 2; } public ShockPacket(String packet) { super(packet); + readIndex = 2; } public ShockPacket(int header) { - super(header); - } - - public ShockPacket(int header, byte[] bytes) { - super(header, bytes); - } - - public ShockPacket(int header, Object... objects) throws InvalidParameterException { - super(header, objects); - } - - public ShockPacket(String identifier, HMessage.Direction direction) throws InvalidParameterException { - super(identifier, direction); - } - - public ShockPacket(String identifier, HMessage.Direction direction, Object... objects) throws InvalidParameterException { - super(identifier, direction, objects); + super(Base64Encoding.encode(header, 2)); + readIndex = 2; } @Override @@ -53,8 +42,61 @@ public class ShockPacket extends HPacket { return this.packetInBytes.length; } + @Override + public HPacket appendUShort(int ushort) { + isEdited = true; + appendBytes(Base64Encoding.encode(ushort, 2)); + return this; + } + + @Override + public HPacket appendString(String s) { + return appendString(s, StandardCharsets.ISO_8859_1); + } + + @Override + public HPacket appendString(String s, Charset charset) { + isEdited = true; + + final byte[] data = s.getBytes(charset); + appendUShort(data.length); + appendBytes(data); + return this; + } + @Override public HPacket copy() { return new ShockPacket(this); } + + @Override + public boolean isCorrupted() { + return packetInBytes.length < 2; + } + + @Override + public String toExpression(HMessage.Direction direction, PacketInfoManager packetInfoManager, boolean removeShuffle) { + return ""; // Unsupported + } + + @Override + public String toExpression(PacketInfoManager packetInfoManager, boolean removeShuffle) { + return ""; // Unsupported + } + + @Override + public String toExpression() { + return ""; // Unsupported + } + + @Override + public String toString() { + return super.toString(); + } + + @Override + public void fixLength() { + // no-op + // length not needed for Shockwave packets + } } diff --git a/G-Earth/src/main/java/gearth/services/always_admin/AdminService.java b/G-Earth/src/main/java/gearth/services/always_admin/AdminService.java index 7608768..e894e39 100644 --- a/G-Earth/src/main/java/gearth/services/always_admin/AdminService.java +++ b/G-Earth/src/main/java/gearth/services/always_admin/AdminService.java @@ -3,6 +3,7 @@ package gearth.services.always_admin; import gearth.protocol.HConnection; import gearth.protocol.HMessage; import gearth.protocol.HPacket; +import gearth.protocol.connection.HClient; public class AdminService { @@ -36,7 +37,7 @@ public class AdminService { } public void onMessage(HMessage message) { - if (!enabled) return; + if (!enabled || hConnection.getClientType() == HClient.SHOCKWAVE) return; HPacket packet = message.getPacket(); if (message.getDestination() == HMessage.Direction.TOCLIENT && (originalPacket == null || packet.headerId() == originalPacket.headerId()) diff --git a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java index e0bc58c..94318f2 100644 --- a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java +++ b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java @@ -1,9 +1,10 @@ package gearth.ui.subforms.injection; -import gearth.GEarth; import gearth.misc.StringifyAble; import gearth.protocol.HMessage; import gearth.protocol.HPacket; +import gearth.protocol.connection.HClient; +import gearth.protocol.packethandler.shockwave.packets.ShockPacket; import gearth.services.packet_info.PacketInfo; import gearth.services.packet_info.PacketInfoManager; import gearth.ui.translations.LanguageBundle; @@ -15,16 +16,17 @@ import java.util.Optional; public class InjectedPackets implements StringifyAble { + private HClient client; private String packetsAsString; private String description; - public InjectedPackets(String packetsAsString, int amountPackets, PacketInfoManager packetInfoManager, HMessage.Direction direction) { + public InjectedPackets(String packetsAsString, int amountPackets, PacketInfoManager packetInfoManager, HMessage.Direction direction, HClient client) { String description; if (amountPackets > 1) { description = String.format("(%s: %d, %s: %d)", LanguageBundle.get("tab.injection.description.packets"), amountPackets, LanguageBundle.get("tab.injection.description.length"), packetsAsString.length()); } else { // assume 1 packet - HPacket packet = new HPacket(packetsAsString); + HPacket packet = client == HClient.SHOCKWAVE ? new ShockPacket(packetsAsString) : new HPacket(packetsAsString); String identifier = null; if (!packet.isPacketComplete()) { identifier = packet.packetIncompleteIdentifier(); @@ -46,6 +48,7 @@ public class InjectedPackets implements StringifyAble { } } + this.client = client; this.description = description; this.packetsAsString = packetsAsString; } @@ -67,6 +70,7 @@ public class InjectedPackets implements StringifyAble { Map info = new HashMap<>(); info.put("packetsAsString", packetsAsString); info.put("description", description); + info.put("clientType", client.toString()); return new JSONObject(info).toString(); } @@ -76,6 +80,7 @@ public class InjectedPackets implements StringifyAble { JSONObject jsonObject = new JSONObject(str); this.packetsAsString = jsonObject.getString("packetsAsString"); this.description = jsonObject.getString("description"); + this.client = jsonObject.has("clientType") ? HClient.valueOf(jsonObject.getString("clientType")) : null; } @Override diff --git a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java index aca0358..b500f7c 100644 --- a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java +++ b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java @@ -4,6 +4,8 @@ import gearth.misc.Cacher; import gearth.protocol.HConnection; import gearth.protocol.HMessage; import gearth.protocol.HPacket; +import gearth.protocol.connection.HClient; +import gearth.protocol.packethandler.shockwave.packets.ShockPacket; import gearth.ui.SubForm; import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.TranslatableString; @@ -91,7 +93,7 @@ public class InjectionController extends SubForm { return unmatchedBrace; } - private static HPacket[] parsePackets(String fullText) { + private static HPacket[] parsePackets(HClient client, String fullText) { LinkedList packets = new LinkedList<>(); String[] lines = fullText.split("\n"); @@ -100,7 +102,9 @@ public class InjectionController extends SubForm { while (isPacketIncomplete(line) && i < lines.length - 1) line += '\n' + lines[++i]; - packets.add(new HPacket(line)); + packets.add(client == HClient.SHOCKWAVE + ? new ShockPacket(line) + : new HPacket(line)); } return packets.toArray(new HPacket[0]); } @@ -113,7 +117,7 @@ public class InjectionController extends SubForm { lbl_corruption.getStyleClass().clear(); lbl_corruption.getStyleClass().add("not-corrupted-label"); - HPacket[] packets = parsePackets(inputPacket.getText()); + HPacket[] packets = parsePackets(getHConnection().getClientType(), inputPacket.getText()); if (packets.length == 0) { dirty = true; @@ -198,7 +202,7 @@ public class InjectionController extends SubForm { } public void sendToServer_clicked(ActionEvent actionEvent) { - HPacket[] packets = parsePackets(inputPacket.getText()); + HPacket[] packets = parsePackets(getHConnection().getClientType(), inputPacket.getText()); for (HPacket packet : packets) { getHConnection().sendToServer(packet); writeToLog(Color.BLUE, String.format("SS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId())); @@ -208,7 +212,7 @@ public class InjectionController extends SubForm { } public void sendToClient_clicked(ActionEvent actionEvent) { - HPacket[] packets = parsePackets(inputPacket.getText()); + HPacket[] packets = parsePackets(getHConnection().getClientType(), inputPacket.getText()); for (HPacket packet : packets) { getHConnection().sendToClient(packet); writeToLog(Color.RED, String.format("CS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId())); @@ -218,7 +222,7 @@ public class InjectionController extends SubForm { } private void addToHistory(HPacket[] packets, String packetsAsString, HMessage.Direction direction) { - InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction); + InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction, getHConnection().getClientType()); List newHistory = new ArrayList<>(); newHistory.add(injectedPackets); @@ -272,7 +276,7 @@ public class InjectionController extends SubForm { } public static void main(String[] args) { - HPacket[] packets = parsePackets("{l}{h:3}{i:967585}{i:9589}{s:\"furni_inscriptionfuckfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\"}{s:\"sirjonasxx-II\"}{s:\"\"}{i:188}{i:0}{i:0}{b:false}"); + HPacket[] packets = parsePackets(HClient.FLASH, "{l}{h:3}{i:967585}{i:9589}{s:\"furni_inscriptionfuckfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\"}{s:\"sirjonasxx-II\"}{s:\"\"}{i:188}{i:0}{i:0}{b:false}"); System.out.println(new HPacket("{l}{h:2550}{s:\"ClientPerf\"\"ormance\\\"}\"}{s:\"23\"}{s:\"fps\"}{s:\"Avatars: 1, Objects: 0\"}{i:76970180}").toExpression()); System.out.println("hi");