diff --git a/src/main/protocol/memory/Rc4Obtainer.java b/src/main/protocol/memory/Rc4Obtainer.java index 62d5f7e..606456b 100644 --- a/src/main/protocol/memory/Rc4Obtainer.java +++ b/src/main/protocol/memory/Rc4Obtainer.java @@ -35,10 +35,13 @@ public class Rc4Obtainer { } }); } + + public void setIncomingHandler(IncomingHandler handler) { incomingHandler = handler; } + private void onSendFirstEncryptedMessage() { outgoingHandler.block(); incomingHandler.block(); diff --git a/src/main/protocol/packethandler/Handler.java b/src/main/protocol/packethandler/Handler.java index fd12dff..e6160d3 100644 --- a/src/main/protocol/packethandler/Handler.java +++ b/src/main/protocol/packethandler/Handler.java @@ -1,6 +1,7 @@ package main.protocol.packethandler; import main.protocol.HMessage; +import main.protocol.HPacket; import main.protocol.TrafficListener; import main.protocol.crypto.RC4; @@ -20,8 +21,13 @@ public abstract class Handler { volatile boolean isDataStream = false; volatile int currentIndex = 0; - protected RC4 clientcipher = null; - protected RC4 servercipher = null; + protected final Object lock = new Object(); + + protected RC4 decryptcipher = null; + protected RC4 encryptcipher = null; + + protected volatile List tempEncryptedBuffer = new ArrayList<>(); + protected volatile boolean isEncryptedStream = false; public Handler(OutputStream outputStream, Object[] listeners) { @@ -35,10 +41,46 @@ public abstract class Handler { } public abstract void act(byte[] buffer) throws IOException; + protected void continuedAct(byte[] buffer) throws IOException { + if (!isEncryptedStream) { + payloadBuffer.push(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); + } + + notifyBufferListeners(buffer.length); + + if (!isTempBlocked) { + flush(); + } + } + public void setRc4(RC4 rc4) { - this.clientcipher = rc4.deepCopy(); - this.servercipher = rc4.deepCopy(); + 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() { @@ -68,9 +110,47 @@ public abstract class Handler { listener.onCapture(message); } } - public abstract void sendToStream(byte[] buffer); - public abstract void flush() throws IOException; + public void sendToStream(byte[] buffer) { + synchronized (lock) { + try { + out.write( + (!isEncryptedStream) + ? buffer + : encryptcipher.rc4(buffer) + ); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void flush() throws IOException { + synchronized (lock) { + HPacket[] hpackets = payloadBuffer.receive(); + + for (HPacket hpacket : hpackets){ + HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOCLIENT, currentIndex); + boolean isencrypted = isEncryptedStream; + if (isDataStream) { + notifyListeners(hMessage); + } + + if (!hMessage.isBlocked()) { + out.write( + (!isencrypted) + ? hMessage.getPacket().toBytes() + : encryptcipher.rc4(hMessage.getPacket().toBytes()) + ); + } + currentIndex++; + } + } + } + + public List getEncryptedBuffer() { + return tempEncryptedBuffer; + } protected abstract void printForDebugging(byte[] bytes); diff --git a/src/main/protocol/packethandler/IncomingHandler.java b/src/main/protocol/packethandler/IncomingHandler.java index 168a70c..636f816 100644 --- a/src/main/protocol/packethandler/IncomingHandler.java +++ b/src/main/protocol/packethandler/IncomingHandler.java @@ -2,93 +2,36 @@ package main.protocol.packethandler; import main.protocol.HMessage; import main.protocol.HPacket; -import main.protocol.memory.Rc4Obtainer; +import main.protocol.TrafficListener; import java.io.IOException; import java.io.OutputStream; +import java.util.List; public class IncomingHandler extends Handler { + private volatile boolean onlyOnce = true; public IncomingHandler(OutputStream outputStream, Object[] listeners) { super(outputStream, listeners); + + ((List)listeners[0]).add(message -> { + if (isDataStream && onlyOnce && message.getPacket().length() == 261) { + onlyOnce = false; + isEncryptedStream = message.getPacket().readBoolean(264); + } + }); } - - private final Object lock = new Object(); - - private Boolean isEncryptedStream = null; - - @Override public void act(byte[] buffer) throws IOException { if (isDataStream) { - if (DEBUG) { - printForDebugging(buffer); - } - - - if (isEncryptedStream == null || !isEncryptedStream) { - payloadBuffer.push(buffer); - } - else { - payloadBuffer.push(servercipher.rc4(buffer)); - } - - - notifyBufferListeners(buffer.length); - - if (!isTempBlocked) { - flush(); - } + continuedAct(buffer); } else { out.write(buffer); } } - @Override - public void sendToStream(byte[] buffer) { - synchronized (lock) { - try { - out.write( - (isEncryptedStream == null || !isEncryptedStream) - ? buffer - : clientcipher.rc4(buffer) - ); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @Override - public void flush() throws IOException { - synchronized (lock) { - HPacket[] hpackets = payloadBuffer.receive(); - - for (HPacket hpacket : hpackets){ - HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOCLIENT, currentIndex); - if (isDataStream) { - notifyListeners(hMessage); - } - - if (!hMessage.isBlocked()) { - out.write( - (isEncryptedStream == null || !isEncryptedStream) - ? hMessage.getPacket().toBytes() - : clientcipher.rc4(hMessage.getPacket().toBytes()) - ); - } - - if (isDataStream && isEncryptedStream == null && hpacket.length() == 261) { - isEncryptedStream = hpacket.readBoolean(264); - } - currentIndex++; - } - } - - } - @Override protected void printForDebugging(byte[] bytes) { System.out.println("-- DEBUG INCOMING -- " + new HPacket(bytes).toString() + " -- DEBUG --"); diff --git a/src/main/protocol/packethandler/OutgoingHandler.java b/src/main/protocol/packethandler/OutgoingHandler.java index 545dbe9..545e368 100644 --- a/src/main/protocol/packethandler/OutgoingHandler.java +++ b/src/main/protocol/packethandler/OutgoingHandler.java @@ -2,21 +2,13 @@ package main.protocol.packethandler; import main.protocol.HMessage; import main.protocol.HPacket; -import main.protocol.crypto.RC4; -import main.protocol.memory.Rc4Obtainer; import java.io.IOException; import java.io.OutputStream; -import java.util.ArrayList; import java.util.List; public class OutgoingHandler extends Handler { - private final Object lock = new Object(); - - private final static int encryptOffset = 3; //all packets with index < 3 aren't encrypted - private List tempEncryptedBuffer = new ArrayList<>(); - public OutgoingHandler(OutputStream outputStream, Object[] listeners) { super(outputStream, listeners); } @@ -31,86 +23,19 @@ public class OutgoingHandler extends Handler { @Override public void act(byte[] buffer) throws IOException { dataStreamCheck(buffer); + if (isDataStream) { - if (currentIndex < encryptOffset) { - payloadBuffer.push(buffer); - } - else if (clientcipher == null) { - for (int i = 0; i < buffer.length; i++) { - tempEncryptedBuffer.add(buffer[i]); - } - } - else { - byte[] tm = clientcipher.rc4(buffer); - if (DEBUG) { - printForDebugging(tm); - } - payloadBuffer.push(tm); + if (!isEncryptedStream && (new HPacket(buffer).length() < 2 || new HPacket(buffer).length() > 1000)) { + isEncryptedStream = true; } - notifyBufferListeners(buffer.length); - - if (!isTempBlocked) { - flush(); - } + continuedAct(buffer); } else { out.write(buffer); } } - @Override - public void setRc4(RC4 rc4) { - super.setRc4(rc4); - - 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; - } - - @Override - public void sendToStream(byte[] buffer) { - synchronized (lock) { - try { - out.write(servercipher.rc4(buffer)); - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - - public List getEncryptedBuffer() { - return tempEncryptedBuffer; - } - - @Override - public void flush() throws IOException { - synchronized (lock) { - HPacket[] hpackets = payloadBuffer.receive(); - for (HPacket hpacket : hpackets){ - HMessage hMessage = new HMessage(hpacket, HMessage.Side.TOSERVER, currentIndex); - if (isDataStream) notifyListeners(hMessage); - if (!hMessage.isBlocked()) { - out.write( - currentIndex < encryptOffset ? hMessage.getPacket().toBytes() : - servercipher.rc4(hMessage.getPacket().toBytes()) - ); - } - currentIndex ++; - } - } - - } - @Override protected void printForDebugging(byte[] bytes) {