integrate chrome extension with g-earth

This commit is contained in:
sirjonasxx 2020-12-25 04:12:30 +01:00
parent 118e7587ac
commit 3e111d3ccc
21 changed files with 545 additions and 231 deletions

View File

@ -12,6 +12,7 @@
<properties>
<javafx.version>1.8</javafx.version>
<jettyVersion>9.2.14.v20151106</jettyVersion>
</properties>
<parent>
@ -123,6 +124,7 @@
</plugins>
</build>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.openjfx</groupId>-->
@ -172,6 +174,24 @@
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jettyVersion}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>${jettyVersion}</version>
</dependency>
</dependencies>
<repositories>

View File

@ -7,6 +7,7 @@ import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.connection.proxy.flash.FlashProxyProvider;
import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
import gearth.protocol.connection.proxy.unity.UnityProxyProvider;
import gearth.services.extensionhandler.ExtensionHandler;
import java.io.IOException;
@ -60,6 +61,12 @@ public class HConnection {
startMITM();
}
public void startUnity() {
HConnection selff = this;
proxyProvider = new UnityProxyProvider(proxy -> selff.proxy = proxy, selff::setState, this);
startMITM();
}
private void startMITM() {
try {
if (proxyProvider != null) {

View File

@ -1,7 +1,8 @@
package gearth.protocol.connection;
import gearth.protocol.packethandler.IncomingPacketHandler;
import gearth.protocol.packethandler.OutgoingPacketHandler;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
import java.net.ServerSocket;
@ -15,8 +16,8 @@ public class HProxy {
private volatile ServerSocket proxy_server = null; //listener for the client
private volatile IncomingPacketHandler inHandler = null; //connection with client (only initialized when verified habbo connection)
private volatile OutgoingPacketHandler outHandler = null; //connection with server (only initialized when verified habbo connection)
private volatile PacketHandler inHandler = null; //connection with client (only initialized when verified habbo connection)
private volatile PacketHandler outHandler = null; //connection with server (only initialized when verified habbo connection)
private volatile String hotelVersion = "";
private volatile AsyncPacketSender asyncPacketSender = null;
@ -33,7 +34,7 @@ public class HProxy {
this.proxy_server = socket;
}
public void verifyProxy(IncomingPacketHandler incomingHandler, OutgoingPacketHandler outgoingHandler, String hotelVersion) {
public void verifyProxy(PacketHandler incomingHandler, PacketHandler outgoingHandler, String hotelVersion) {
this.inHandler = incomingHandler;
this.outHandler = outgoingHandler;
this.hotelVersion = hotelVersion;
@ -64,11 +65,11 @@ public class HProxy {
return intercept_host;
}
public IncomingPacketHandler getInHandler() {
public PacketHandler getInHandler() {
return inHandler;
}
public OutgoingPacketHandler getOutHandler() {
public PacketHandler getOutHandler() {
return outHandler;
}

View File

@ -7,9 +7,9 @@ import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.memory.Rc4Obtainer;
import gearth.protocol.packethandler.IncomingPacketHandler;
import gearth.protocol.packethandler.OutgoingPacketHandler;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
import gearth.protocol.packethandler.flash.FlashPacketHandler;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
@ -45,9 +45,9 @@ public abstract class FlashProxyProvider implements ProxyProvider {
if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables(), outgoingHandler, hConnection.getExtensionHandler());
rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler);
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
IncomingFlashPacketHandler incomingHandler = new IncomingFlashPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables(), outgoingHandler, hConnection.getExtensionHandler());
rc4Obtainer.setFlashPacketHandlers(outgoingHandler, incomingHandler);
Semaphore abort = new Semaphore(0);
@ -78,7 +78,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
}
}
private void handleInputStream(Socket socket, PacketHandler packetHandler, Semaphore abort) {
private void handleInputStream(Socket socket, FlashPacketHandler flashPacketHandler, Semaphore abort) {
new Thread(() -> {
try {
int readLength;
@ -86,7 +86,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
while (!socket.isClosed() &&
(hConnection.getState() == HState.WAITING_FOR_CLIENT || hConnection.getState() == HState.CONNECTED) &&
(readLength = socket.getInputStream().read(buffer)) != -1) {
packetHandler.act(Arrays.copyOf(buffer, readLength));
flashPacketHandler.act(Arrays.copyOf(buffer, readLength));
}
}
catch (IOException ignore) {

View File

@ -1,4 +0,0 @@
package gearth.protocol.connection.proxy.unity;
public class ProxyProvider {
}

View File

@ -0,0 +1,86 @@
package gearth.protocol.connection.proxy.unity;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.protocol.connection.HProxy;
import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.packethandler.unity.UnityPacketHandler;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
@ServerEndpoint(value = "/packethandler")
public class UnityCommunicator {
private final HProxySetter proxySetter;
private final HStateSetter stateSetter;
private final HConnection hConnection;
private final ProxyProvider proxyProvider;
HProxy hProxy = null;
public UnityCommunicator(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, ProxyProvider proxyProvider) {
this.proxySetter = proxySetter;
this.stateSetter = stateSetter;
this.hConnection = hConnection;
this.proxyProvider = proxyProvider;
}
@OnOpen
public void onOpen(Session session) throws IOException {
}
@OnMessage
public void onMessage(byte[] b, Session session) throws IOException {
// session.getBasicRemote().sendText(message.toUpperCase());
// session.getBasicRemote().sendBinary(ByteBuffer.wrap(b));
// System.out.println("received " + new HPacket(b).toString());
byte[] packet = Arrays.copyOfRange(b, 1, b.length);
if (hProxy == null && b[0] == 1) {
HPacket maybe = new HPacket(packet);
if (maybe.getBytesLength() > 6 && maybe.headerId() == 4000) {
String hotelVersion = maybe.readString();
hProxy = new HProxy("", "", -1, -1, "");
hProxy.verifyProxy(
new UnityPacketHandler(hConnection.getExtensionHandler(), hConnection.getTrafficObservables(), session, HMessage.Direction.TOCLIENT),
new UnityPacketHandler(hConnection.getExtensionHandler(), hConnection.getTrafficObservables(), session, HMessage.Direction.TOSERVER),
hotelVersion
);
proxySetter.setProxy(hProxy);
stateSetter.setState(HState.CONNECTED);
}
}
if (hProxy != null && b[0] == 0) {
hProxy.getInHandler().act(packet);
}
else if (hProxy != null && b[0] == 1) {
hProxy.getOutHandler().act(packet);
}
else {
proxyProvider.abort();
}
}
@OnClose
public void onClose(Session session) throws IOException {
proxyProvider.abort();
}
@OnError
public void onError(Session session, Throwable throwable) {
proxyProvider.abort();
}
}

View File

@ -0,0 +1,27 @@
package gearth.protocol.connection.proxy.unity;
import gearth.protocol.HConnection;
import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider;
import javax.websocket.server.ServerEndpointConfig;
public class UnityCommunicatorConfig extends ServerEndpointConfig.Configurator {
private final HProxySetter proxySetter;
private final HStateSetter stateSetter;
private final HConnection hConnection;
private final ProxyProvider proxyProvider;
public UnityCommunicatorConfig(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, ProxyProvider proxyProvider) {
this.proxySetter = proxySetter;
this.stateSetter = stateSetter;
this.hConnection = hConnection;
this.proxyProvider = proxyProvider;
}
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
return (T)new UnityCommunicator(proxySetter, stateSetter, hConnection, proxyProvider);
}
}

View File

@ -0,0 +1,81 @@
package gearth.protocol.connection.proxy.unity;
import gearth.protocol.HConnection;
import gearth.protocol.connection.HProxySetter;
import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;
import java.io.IOException;
public class UnityProxyProvider implements ProxyProvider {
private final HProxySetter proxySetter;
private final HStateSetter stateSetter;
private final HConnection hConnection;
private Server server;
public UnityProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection) {
this.proxySetter = proxySetter;
this.stateSetter = stateSetter;
this.hConnection = hConnection;
}
@Override
public void start() throws IOException {
// https://happyhyppo.ro/2016/03/21/minimal-websockets-communication-with-javajetty-and-angularjs/
server = new Server(8025);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/ws");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { context });
server.setHandler(handlers);
ServerContainer wscontainer = null;
try {
wscontainer = WebSocketServerContainerInitializer.configureContext(context);
wscontainer.addEndpoint(ServerEndpointConfig.Builder
.create(UnityCommunicator.class, "/packethandler") // the endpoint url
.configurator(new UnityCommunicatorConfig(proxySetter, stateSetter, hConnection, this))
.build());
server.start();
stateSetter.setState(HState.WAITING_FOR_CLIENT);
} catch (Exception e) {
stateSetter.setState(HState.NOT_CONNECTED);
e.printStackTrace();
}
}
@Override
public synchronized void abort() {
if (server == null) {
return;
}
final Server abortThis = server;
stateSetter.setState(HState.ABORTING);
new Thread(() -> {
try {
abortThis.stop();
} catch (Exception e) {
e.printStackTrace();
} finally {
stateSetter.setState(HState.NOT_CONNECTED);
}
}).start();
server = null;
}
}

View File

@ -7,7 +7,9 @@ import gearth.protocol.HPacket;
import gearth.protocol.crypto.RC4;
import gearth.protocol.memory.habboclient.HabboClient;
import gearth.protocol.memory.habboclient.HabboClientFactory;
import gearth.protocol.packethandler.*;
import gearth.protocol.packethandler.flash.BufferChangeListener;
import gearth.protocol.packethandler.flash.FlashPacketHandler;
import gearth.protocol.packethandler.PayloadBuffer;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
@ -25,17 +27,17 @@ public class Rc4Obtainer {
public static final boolean DEBUG = false;
private HabboClient client;
private List<PacketHandler> packetHandlers;
private List<FlashPacketHandler> flashPacketHandlers;
public Rc4Obtainer(HConnection hConnection) {
client = HabboClientFactory.get(hConnection);
}
public void setPacketHandlers(PacketHandler... packetHandlers) {
this.packetHandlers = Arrays.asList(packetHandlers);
public void setFlashPacketHandlers(FlashPacketHandler... flashPacketHandlers) {
this.flashPacketHandlers = Arrays.asList(flashPacketHandlers);
for (PacketHandler handler : packetHandlers) {
for (FlashPacketHandler handler : flashPacketHandlers) {
BufferChangeListener bufferChangeListener = new BufferChangeListener() {
@Override
public void act() {
@ -53,10 +55,10 @@ public class Rc4Obtainer {
private void onSendFirstEncryptedMessage(PacketHandler packetHandler) {
private void onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler) {
if (!HConnection.DECRYPTPACKETS) return;
packetHandlers.forEach(PacketHandler::block);
flashPacketHandlers.forEach(FlashPacketHandler::block);
new Thread(() -> {
@ -67,8 +69,8 @@ public class Rc4Obtainer {
int i = 0;
while (!worked && i < 4) {
worked = (i % 2 == 0) ?
onSendFirstEncryptedMessage(packetHandler, client.getRC4cached()) :
onSendFirstEncryptedMessage(packetHandler, client.getRC4possibilities());
onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4cached()) :
onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4possibilities());
i++;
}
@ -107,16 +109,16 @@ public class Rc4Obtainer {
System.out.println("Cracked RC4 in " + (endTime - startTime) + "ms");
}
packetHandlers.forEach(PacketHandler::unblock);
flashPacketHandlers.forEach(FlashPacketHandler::unblock);
}).start();
}
private boolean onSendFirstEncryptedMessage(PacketHandler packetHandler, List<byte[]> potentialRC4tables) {
private boolean onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler, List<byte[]> potentialRC4tables) {
for (byte[] possible : potentialRC4tables) {
byte[] encBuffer = new byte[packetHandler.getEncryptedBuffer().size()];
byte[] encBuffer = new byte[flashPacketHandler.getEncryptedBuffer().size()];
for (int i = 0; i < encBuffer.length; i++) {
encBuffer[i] = packetHandler.getEncryptedBuffer().get(i);
encBuffer[i] = flashPacketHandler.getEncryptedBuffer().get(i);
}
for (int i = 0; i < 256; i++) {
@ -124,7 +126,7 @@ public class Rc4Obtainer {
byte[] keycpy = Arrays.copyOf(possible, possible.length);
RC4 rc4Tryout = new RC4(keycpy, i, j);
if (packetHandler.getMessageSide() == HMessage.Direction.TOSERVER) rc4Tryout.undoRc4(encBuffer);
if (flashPacketHandler.getMessageSide() == HMessage.Direction.TOSERVER) rc4Tryout.undoRc4(encBuffer);
if (rc4Tryout.couldBeFresh()) {
byte[] encDataCopy = Arrays.copyOf(encBuffer, encBuffer.length);
RC4 rc4TryCopy = rc4Tryout.deepCopy();
@ -135,7 +137,7 @@ public class Rc4Obtainer {
HPacket[] checker = payloadBuffer.pushAndReceive(decoded);
if (payloadBuffer.peak().length == 0) {
packetHandler.setRc4(rc4Tryout);
flashPacketHandler.setRc4(rc4Tryout);
return true;
}

View File

@ -0,0 +1,12 @@
package gearth.protocol.packethandler;
public class ByteArrayUtils {
public static byte[] combineByteArrays(byte[] arr1, byte[] arr2) {
byte[] combined = new byte[arr1.length + arr2.length];
System.arraycopy(arr1,0,combined,0 ,arr1.length);
System.arraycopy(arr2,0,combined,arr1.length,arr2.length);
return combined;
}
}

View File

@ -1,125 +1,32 @@
package gearth.protocol.packethandler;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.protocol.crypto.RC4;
import gearth.services.extensionhandler.ExtensionHandler;
import gearth.services.extensionhandler.OnHMessageHandled;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public abstract class PacketHandler {
protected static final boolean DEBUG = false;
protected final ExtensionHandler extensionHandler;
private final Object[] trafficObservables; //get notified on packet send
protected final PayloadBuffer payloadBuffer;
protected volatile int currentIndex = 0;
protected final Object sendLock = new Object();
private volatile PayloadBuffer payloadBuffer = new PayloadBuffer();
private volatile OutputStream out;
private volatile ExtensionHandler extensionHandler;
private volatile Object[] trafficObservables; //get notified on packet send
private volatile boolean isTempBlocked = false;
volatile boolean isDataStream = false;
private volatile int currentIndex = 0;
private final Object manipulationLock = new Object();
private final Object sendLock = new Object();
private RC4 decryptcipher = null;
private RC4 encryptcipher = null;
private volatile List<Byte> tempEncryptedBuffer = new ArrayList<>();
volatile boolean isEncryptedStream = false;
PacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
this.trafficObservables = trafficObservables;
protected PacketHandler(ExtensionHandler extensionHandler, Object[] trafficObservables) {
this.extensionHandler = extensionHandler;
out = outputStream;
}
public boolean isDataStream() {return isDataStream;}
public void setAsDataStream() {
isDataStream = true;
}
public boolean isEncryptedStream() {
return isEncryptedStream;
}
public void act(byte[] buffer) throws IOException {
if (!isDataStream) {
out.write(buffer);
return;
}
bufferChangeObservable.fireEvent();
if (!isEncryptedStream) {
payloadBuffer.push(buffer);
}
else if (!HConnection.DECRYPTPACKETS) {
synchronized (sendLock) {
out.write(buffer);
}
}
else if (decryptcipher == null) {
for (int i = 0; i < buffer.length; i++) {
tempEncryptedBuffer.add(buffer[i]);
}
}
else {
byte[] tm = decryptcipher.rc4(buffer);
if (DEBUG) {
printForDebugging(tm);
}
payloadBuffer.push(tm);
}
if (!isTempBlocked) {
flush();
}
this.trafficObservables = trafficObservables;
this.payloadBuffer = new PayloadBuffer();
}
public void setRc4(RC4 rc4) {
this.decryptcipher = rc4.deepCopy();
this.encryptcipher = rc4.deepCopy();
public abstract void sendToStream(byte[] buffer);
byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
encrbuffer[i] = tempEncryptedBuffer.get(i);
}
public abstract void act(byte[] buffer) throws IOException;
try {
act(encrbuffer);
} catch (IOException e) {
e.printStackTrace();
}
tempEncryptedBuffer = null;
}
public void block() {
isTempBlocked = true;
}
public void unblock() {
try {
flush();
} catch (IOException e) {
e.printStackTrace();
}
isTempBlocked = false;
}
/**
* LISTENERS CAN EDIT THE MESSAGE BEFORE BEING SENT
* @param message
*/
private void notifyListeners(int i, HMessage message) {
protected void notifyListeners(int i, HMessage message) {
((Observable<TrafficListener>) trafficObservables[i]).fireEvent(trafficListener -> {
message.getPacket().resetReadIndex();
trafficListener.onCapture(message);
@ -127,72 +34,4 @@ public abstract class PacketHandler {
message.getPacket().resetReadIndex();
}
public void sendToStream(byte[] buffer) {
synchronized (sendLock) {
try {
out.write(
(!isEncryptedStream)
? buffer
: encryptcipher.rc4(buffer)
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void flush() throws IOException {
synchronized (manipulationLock) {
HPacket[] hpackets = payloadBuffer.receive();
for (HPacket hpacket : hpackets){
HMessage hMessage = new HMessage(hpacket, getMessageSide(), currentIndex);
boolean isencrypted = isEncryptedStream;
OnHMessageHandled afterExtensionIntercept = hMessage1 -> {
if (isDataStream) {
notifyListeners(2, hMessage1);
}
if (!hMessage1.isBlocked()) {
synchronized (sendLock) {
out.write(
(!isencrypted)
? hMessage1.getPacket().toBytes()
: encryptcipher.rc4(hMessage1.getPacket().toBytes())
);
}
}
};
if (isDataStream) {
notifyListeners(0, hMessage);
notifyListeners(1, hMessage);
extensionHandler.handle(hMessage, afterExtensionIntercept);
}
else {
afterExtensionIntercept.finished(hMessage);
}
currentIndex++;
}
}
}
public abstract HMessage.Direction getMessageSide();
public List<Byte> getEncryptedBuffer() {
return tempEncryptedBuffer;
}
protected abstract void printForDebugging(byte[] bytes);
private Observable<BufferChangeListener> bufferChangeObservable = new Observable<>(BufferChangeListener::act);
public Observable<BufferChangeListener> getBufferChangeObservable() {
return bufferChangeObservable;
}
public int getCurrentIndex() {
return currentIndex;
}
}

View File

@ -14,7 +14,7 @@ public class PayloadBuffer {
return receive();
}
public void push(byte[] tcpData) {
buffer = buffer.length == 0 ? tcpData.clone() : combineByteArrays(buffer, tcpData);
buffer = buffer.length == 0 ? tcpData.clone() : ByteArrayUtils.combineByteArrays(buffer, tcpData);
}
public HPacket[] receive() {
if (buffer.length < 6) return new HPacket[0];
@ -30,14 +30,6 @@ public class PayloadBuffer {
}
private byte[] combineByteArrays(byte[] arr1, byte[] arr2) {
byte[] combined = new byte[arr1.length + arr2.length];
System.arraycopy(arr1,0,combined,0 ,arr1.length);
System.arraycopy(arr2,0,combined,arr1.length,arr2.length);
return combined;
}
public byte[] peak() {
return buffer;
}

View File

@ -1,4 +1,4 @@
package gearth.protocol.packethandler;
package gearth.protocol.packethandler.flash;
public interface BufferChangeListener {

View File

@ -0,0 +1,182 @@
package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.protocol.crypto.RC4;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.PayloadBuffer;
import gearth.services.extensionhandler.ExtensionHandler;
import gearth.services.extensionhandler.OnHMessageHandled;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public abstract class FlashPacketHandler extends PacketHandler {
protected static final boolean DEBUG = false;
private volatile OutputStream out;
private volatile boolean isTempBlocked = false;
volatile boolean isDataStream = false;
private final Object manipulationLock = new Object();
private RC4 decryptcipher = null;
private RC4 encryptcipher = null;
private volatile List<Byte> tempEncryptedBuffer = new ArrayList<>();
volatile boolean isEncryptedStream = false;
FlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
super(extensionHandler, trafficObservables);
out = outputStream;
}
public boolean isDataStream() {return isDataStream;}
public void setAsDataStream() {
isDataStream = true;
}
public boolean isEncryptedStream() {
return isEncryptedStream;
}
public void act(byte[] buffer) throws IOException {
if (!isDataStream) {
out.write(buffer);
return;
}
bufferChangeObservable.fireEvent();
if (!isEncryptedStream) {
payloadBuffer.push(buffer);
}
else if (!HConnection.DECRYPTPACKETS) {
synchronized (sendLock) {
out.write(buffer);
}
}
else if (decryptcipher == null) {
for (int i = 0; i < buffer.length; i++) {
tempEncryptedBuffer.add(buffer[i]);
}
}
else {
byte[] tm = decryptcipher.rc4(buffer);
if (DEBUG) {
printForDebugging(tm);
}
payloadBuffer.push(tm);
}
if (!isTempBlocked) {
flush();
}
}
public void setRc4(RC4 rc4) {
this.decryptcipher = rc4.deepCopy();
this.encryptcipher = rc4.deepCopy();
byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
encrbuffer[i] = tempEncryptedBuffer.get(i);
}
try {
act(encrbuffer);
} catch (IOException e) {
e.printStackTrace();
}
tempEncryptedBuffer = null;
}
public void block() {
isTempBlocked = true;
}
public void unblock() {
try {
flush();
} catch (IOException e) {
e.printStackTrace();
}
isTempBlocked = false;
}
public void sendToStream(byte[] buffer) {
synchronized (sendLock) {
try {
out.write(
(!isEncryptedStream)
? buffer
: encryptcipher.rc4(buffer)
);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void flush() throws IOException {
synchronized (manipulationLock) {
HPacket[] hpackets = payloadBuffer.receive();
for (HPacket hpacket : hpackets){
HMessage hMessage = new HMessage(hpacket, getMessageSide(), currentIndex);
boolean isencrypted = isEncryptedStream;
OnHMessageHandled afterExtensionIntercept = hMessage1 -> {
if (isDataStream) {
notifyListeners(2, hMessage1);
}
if (!hMessage1.isBlocked()) {
synchronized (sendLock) {
out.write(
(!isencrypted)
? hMessage1.getPacket().toBytes()
: encryptcipher.rc4(hMessage1.getPacket().toBytes())
);
}
}
};
if (isDataStream) {
notifyListeners(0, hMessage);
notifyListeners(1, hMessage);
extensionHandler.handle(hMessage, afterExtensionIntercept);
}
else {
afterExtensionIntercept.finished(hMessage);
}
currentIndex++;
}
}
}
public abstract HMessage.Direction getMessageSide();
public List<Byte> getEncryptedBuffer() {
return tempEncryptedBuffer;
}
protected abstract void printForDebugging(byte[] bytes);
private Observable<BufferChangeListener> bufferChangeObservable = new Observable<>(BufferChangeListener::act);
public Observable<BufferChangeListener> getBufferChangeObservable() {
return bufferChangeObservable;
}
public int getCurrentIndex() {
return currentIndex;
}
}

View File

@ -1,4 +1,4 @@
package gearth.protocol.packethandler;
package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage;
@ -6,13 +6,11 @@ import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.services.extensionhandler.ExtensionHandler;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
public class IncomingPacketHandler extends PacketHandler {
public class IncomingFlashPacketHandler extends FlashPacketHandler {
public IncomingPacketHandler(OutputStream outputStream, Object[] trafficObservables, OutgoingPacketHandler outgoingHandler, ExtensionHandler extensionHandler) {
public IncomingFlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, OutgoingFlashPacketHandler outgoingHandler, ExtensionHandler extensionHandler) {
super(outputStream, trafficObservables, extensionHandler);
TrafficListener listener = new TrafficListener() {

View File

@ -1,4 +1,4 @@
package gearth.protocol.packethandler;
package gearth.protocol.packethandler.flash;
public interface OnDatastreamConfirmedListener {

View File

@ -1,4 +1,4 @@
package gearth.protocol.packethandler;
package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage;
@ -7,13 +7,10 @@ import gearth.services.extensionhandler.ExtensionHandler;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class OutgoingPacketHandler extends PacketHandler {
public class OutgoingFlashPacketHandler extends FlashPacketHandler {
public OutgoingPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
public OutgoingFlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
super(outputStream, trafficObservables, extensionHandler);
}

View File

@ -0,0 +1,59 @@
package gearth.protocol.packethandler.unity;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.protocol.packethandler.ByteArrayUtils;
import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.PayloadBuffer;
import gearth.services.extensionhandler.ExtensionHandler;
import gearth.services.extensionhandler.OnHMessageHandled;
import javax.websocket.Session;
import java.io.IOException;
import java.nio.ByteBuffer;
public class UnityPacketHandler extends PacketHandler {
private final Session session;
private final HMessage.Direction direction;
public UnityPacketHandler(ExtensionHandler extensionHandler, Object[] trafficObservables, Session session, HMessage.Direction direction) {
super(extensionHandler, trafficObservables);
this.session = session;
this.direction = direction;
}
@Override
public void sendToStream(byte[] buffer) {
synchronized (sendLock) {
try {
byte[] prefix = new byte[]{(direction == HMessage.Direction.TOCLIENT ? ((byte)0) : ((byte)1))};
byte[] combined = ByteArrayUtils.combineByteArrays(prefix, buffer);
session.getBasicRemote().sendBinary(ByteBuffer.wrap(combined));
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void act(byte[] buffer) throws IOException {
HPacket[] packets = payloadBuffer.pushAndReceive(buffer);
for (HPacket hPacket : packets) {
HMessage hMessage = new HMessage(hPacket, direction, currentIndex);
OnHMessageHandled afterExtensionIntercept = hMessage1 -> {
notifyListeners(2, hMessage1);
sendToStream(hMessage1.getPacket().toBytes());
};
notifyListeners(0, hMessage);
notifyListeners(1, hMessage);
extensionHandler.handle(hMessage, afterExtensionIntercept);
currentIndex++;
}
}
}

View File

@ -0,0 +1,4 @@
package gearth.services.g_chrome_tools;
public class UnityFileServer {
}

View File

@ -0,0 +1,4 @@
package gearth.services.g_chrome_tools;
public class UnitywebModifyer {
}

View File

@ -168,12 +168,19 @@ public class ConnectionController extends SubForm {
btnConnect.setDisable(true);
new Thread(() -> {
if (cbx_autodetect.isSelected()) {
getHConnection().start();
if (useFlash()) {
if (cbx_autodetect.isSelected()) {
getHConnection().start();
}
else {
getHConnection().start(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
}
}
else {
getHConnection().start(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
getHConnection().startUnity();
}
if (HConnection.DEBUG) System.out.println("connecting");
}).start();