restructure of PacketLogger & implement packet toExpression()

This commit is contained in:
sirjonasxx 2018-04-05 02:55:38 +02:00
parent b01e0a9b07
commit 68a98a6885
16 changed files with 605 additions and 144 deletions

View File

@ -13,7 +13,9 @@ import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class HConnection {
@ -25,6 +27,20 @@ public class HConnection {
CONNECTED // CONNECTED
}
private static Set<String> autoDetectHosts;
static {
autoDetectHosts = new HashSet<>();
autoDetectHosts.add("game-us.habbo.com:38101");
autoDetectHosts.add("game-nl.habbo.com:30000");
autoDetectHosts.add("game-br.habbo.com:30000");
autoDetectHosts.add("game-es.habbo.com:30000");
autoDetectHosts.add("game-fr.habbo.com:30000");
autoDetectHosts.add("game-nl.habbo.com:30000");
autoDetectHosts.add("game-tr.habbo.com:30000");
}
public final static boolean DEBUG = false;
private static final HostReplacer hostsReplacer = HostReplacerFactory.get();
private volatile boolean hostRedirected = false;
@ -40,7 +56,6 @@ public class HConnection {
private volatile Handler inHandler = null;
private volatile Handler outHandler = null;
public final static boolean DEBUG = false;
public State getState() {
return state;
@ -277,7 +292,7 @@ public class HConnection {
* 1 = modification
* 2 = after modification ¹
*
* ¹don't modificate (block, replace)
* ¹don't edit the packet (block, replace)
*/
public void addTrafficListener(int order, TrafficListener listener) {
((List<TrafficListener>)trafficListeners[order]).add(listener);

View File

@ -46,7 +46,6 @@ public class HPacket {
return teststring;
}
/**
* returns "" if invalid expression, replaces all {} occurences except {l}
* @return
@ -490,11 +489,302 @@ public class HPacket {
isEdited = remember;
}
/**
* returns "" if not found or not sure enough
* dont hate on the coding quality in this function, its pretty effective.
*/
public String toExpression() {
if (isCorrupted()) return "";
boolean[] mask = new boolean[packetInBytes.length];
String[] resultTest = new String[packetInBytes.length];
for (int i = 0; i < 6; i++) {
mask[i] = true;
}
resultTest[0] = "{l}";
resultTest[4] = "{u:"+headerId()+"}";
outerloop:
for (int i = 6; i < packetInBytes.length - 1; i++) {
int potentialstringlength = readUshort(i);
if ((potentialstringlength >= 0 && potentialstringlength < 3) || potentialstringlength > packetInBytes.length - i - 2) continue;
for (int j = i; j < potentialstringlength+i+2; j++) {
if (mask[j]) continue outerloop;
}
for (int j = i+2; j < potentialstringlength+i+2; j++) {
if (readByte(j) >= 0 && readByte(j) < 6) continue outerloop;
}
if (i + 2 + potentialstringlength >= packetInBytes.length - 3 ||
(packetInBytes[i+2+potentialstringlength] >= 0 &&
packetInBytes[i+2+potentialstringlength] < 6 )) {
for (int j = i; j < potentialstringlength+i+2; j++) {
mask[j] = true;
}
resultTest[i] = "{s:"+readString(i)+"}";
i += (1 + potentialstringlength);
}
}
//TODO add special case for seperated 5, 6 and 7 bytes here
// long live the shitty code.
//5
out:
for (int i = 6; i < packetInBytes.length - 4; i++) {
for (int j = i; j < i+5; j++) {
if (mask[j]) {
i = j;
continue out;
}
}
if (i+5 < packetInBytes.length && !mask[i+5]) continue;
if ((readByte(i) == 0 || readByte(i) == 1) && (readInteger(i+1) > 1 || readInteger(i+1) < 0)) {
//decide the first byte to be the a boolean
resultTest[i] = "{b:"+(readBoolean(i) ? "true" : "false")+"}";
resultTest[i+1] = "{i:"+readInteger(i+1)+"}";
for (int j = i; j < i+5; j++) {
mask[j] = true;
}
}
}
// //6
// out:
// for (int i = 6; i < packetInBytes.length - 5; i++) {
// for (int j = i; j < i+6; j++) {
// if (mask[j]) {
// i = j;
// continue out;
// }
// }
// if (i+6 < packetInBytes.length && !mask[i+6]) continue;
//
//
//
// }
//
// //7
// out:
// for (int i = 6; i < packetInBytes.length - 6; i++) {
// for (int j = i; j < i+7; j++) {
// if (mask[j]) {
// i = j;
// continue out;
// }
// }
// if (i+7 < packetInBytes.length && !mask[i+7]) continue;
//
//
//
// }
lp22:
for (int i = 6; i < packetInBytes.length - 3; i++) {
for (int j = i; j < i + 4; j++) {
if (mask[j]) {
continue lp22;
}
}
int num = readInteger(i);
if (num == -1 || (num >= 0 && num < 256)) {
for (int j = i; j < i+4; j++) {
mask[j] = true;
}
resultTest[i] = "{i:"+num+"}";
i += 3;
}
}
boolean changed = true;
boolean isfirst = true;
while (changed) {
changed = false;
// filtering strings
outerloop:
for (int i = 6; i < packetInBytes.length - 1; i++) {
int potentialstringlength = readUshort(i);
if ((potentialstringlength >= 0 && potentialstringlength < 3) || potentialstringlength > packetInBytes.length - i - 2) continue;
for (int j = i; j < potentialstringlength+i+2; j++) {
if (mask[j]) continue outerloop;
}
for (int j = i+2; j < potentialstringlength+i+2; j++) {
if (readByte(j) >= 0 && readByte(j) < 6) continue outerloop;
}
if (i + 2 + potentialstringlength >= packetInBytes.length - 3 ||
(packetInBytes[i+2+potentialstringlength] >= 0 &&
packetInBytes[i+2+potentialstringlength] < 6 )) {
for (int j = i; j < potentialstringlength+i+2; j++) {
mask[j] = true;
}
changed = true;
resultTest[i] = "{s:"+readString(i)+"}";
i += (1 + potentialstringlength);
}
}
if (isfirst) {
int count = 0;
for (int i = 6; i < packetInBytes.length; i++) {
if (!mask[i]) count++;
}
if (count > 300) return "";
}
isfirst = false;
// filtering integers
boolean hasfoundsomtin = true;
while (hasfoundsomtin) {
hasfoundsomtin = false;
outerloop2:
for (int i = 6; i < packetInBytes.length - 3; i++) {
for (int j = i; j < i + 4; j++) {
if (mask[j]) {
continue outerloop2;
}
}
if (i + 4 == packetInBytes.length || mask[i+4] || mask[i-1]) {
if (packetInBytes[i+1] == 2) { //could be an unfiltered string; don't filter yet
if (((packetInBytes[i+2] >= '0' && packetInBytes[i+2] <= '9') ||
(packetInBytes[i+2] >= 'a' && packetInBytes[i+2] <= 'z') ||
(packetInBytes[i+2] >= 'A' && packetInBytes[i+2] <= 'Z')) &&
((packetInBytes[i+3] >= '0' && packetInBytes[i+3] <= '9') ||
(packetInBytes[i+3] >= 'a' && packetInBytes[i+3] <= 'z') ||
(packetInBytes[i+3] >= 'A' && packetInBytes[i+3] <= 'Z'))) {
changed = true;
for (int j = i; j < i + 4; j++) {
mask[j] = true;
}
hasfoundsomtin = true;
resultTest[i] = "{i:"+readInteger(i)+"}";
continue;
}
continue ;
}
else {
for (int j = i; j < i + 4; j++) {
mask[j] = true;
}
hasfoundsomtin = true;
changed = true;
resultTest[i] = "{i:"+readInteger(i)+"}";
continue;
}
}
if (readInteger(i) < 65536) {
for (int j = i; j < i + 4; j++) {
mask[j] = true;
}
hasfoundsomtin = true;
resultTest[i] = "{i:"+readInteger(i)+"}";
changed = true;
continue;
}
}
}
// filtering strings
outerloop3:
for (int i = 6; i < packetInBytes.length - 1; i++) {
int potentialstringlength = readUshort(i);
if (potentialstringlength > packetInBytes.length - i - 2) continue;
for (int j = i; j < potentialstringlength+i+2; j++) {
if (mask[j]) continue outerloop3;
}
for (int j = i+2; j < potentialstringlength+i+2; j++) {
if (readByte(j) >= 0 && readByte(j) < 6) continue outerloop3;
}
for (int j = i; j < potentialstringlength+i+2; j++) {
mask[j] = true;
}
resultTest[i] = "{s:"+readString(i)+"}";
i += (1 + potentialstringlength);
changed = true;
}
}
int opeenvolging = 0;
for (int i = 6; i < packetInBytes.length; i++) {
if (!mask[i]) {
opeenvolging++;
if (opeenvolging == 4) return "";
if (i+1 == packetInBytes.length || mask[i+1]) {
for (int j = i - opeenvolging + 1; j <= i; j++) {
mask[j] = true;
if (packetInBytes[j] == 1 || packetInBytes[j] == 0) {
resultTest[j] = "{b:"+(packetInBytes[j] == 1 ? "true" : "false")+"}";
}
else {
resultTest[j] = "{b:"+packetInBytes[j]+"}";
}
}
opeenvolging = 0;
}
}
}
// if all values in mask are true, go further
for (boolean bool : mask) {
if (!bool) return "";
}
StringBuilder expression = new StringBuilder();
for (int i = 0; i < resultTest.length; i++) {
if (resultTest[i] != null) expression.append(resultTest[i]);
}
return expression.toString();
}
public static void main(String[] args) {
HPacket packet = new HPacket("[0][0][0]4[15] [0]!PRODUCTION-201802201205-141713395[0][5]FLASH[0][0][0][1][0][0][0][0]");
packet.replaceFirstString("FLASH", "HTML");
System.out.println(packet);
// HPacket packet = new HPacket("[0][0][0]4[15] [0]!PRODUCTION-201802201205-141713395[0][5]FLASH[0][0][0][1][0][0][0][0]");
// packet.replaceFirstString("FLASH", "HTML");
// System.out.println(packet);
HPacket packet = new HPacket("[0][0][0]![14][134][0][21]99% kans je leest dit[0][0][0][0][0][0][0][29]");
System.out.println(packet.toExpression());
packet = new HPacket("[0][0][0]+[0]µ[0][10]Navigation[0][0][0][11]go.official[0][8]27636336[0][0][0][0]");
System.out.println(packet.toExpression());
packet = new HPacket("[0][0][0][11][7]/[0][0][0][2][0][0][0][0][0]");
System.out.println(packet.toExpression());
packet = new HPacket("[0][0][4]ÿ[5]×[0][0][0]<[0][7]new_ads[0][14]friend_finding[0][10]staffpicks[0][15]campaign_target[0][13]friends_rooms[0][6]groups[0][8]metadata[0][12]history_freq[0][13]highest_score[0][11]competition[0][21]category__Habbo Leven[0] category__Global Chat & Discussi[0] category__GLOBAL BUILDING AND DE[0][25]category__global official[0][22]category__global party[0][22]category__global games[0][22]category__global trade[0][24]category__global fansite[0][21]category__global help[0][31]category__global personal space[0][24]category__global reviews[0][19]category__global bc[0][31]category__global personal space[0] eventcategory__Vetste Evenemente[0][31]eventcategory__Feesten & Muziek[0][25]eventcategory__Rollenspel[0][24]eventcategory__Help Desk[0][21]eventcategory__Ruilen[0][20]eventcategory__Games[0][22]eventcategory__Bouwers[0] eventcategory__Debatten & Discus[0][24]eventcategory__Friending[0][25]eventcategory__Habbo Werk[0][24]eventcategory__Evenement[0] eventcategory__Groepsevenementen[0][9]favorites[0][16]eventcategory__2[0][15]official_134070[0][15]official_134072[0][15]official_134073[0][15]official_134074[0][15]official_134910[0][15]official_134912[0][15]official_134913[0][15]official_135420[0][15]official_135422[0][15]official_135423[0][15]official_135424[0][16]eventcategory__5[0][15]official_144124[0][15]official_144126[0][15]official_144127[0][16]category__Ruilen[0] category__Global Chat & Discussi[0] category__GLOBAL BUILDING AND DE[0][15]official_148980[0][15]official_148981[0][15]official_148982[0][15]official_148984[0][15]official_148985");
System.out.println(packet.toExpression());
packet = new HPacket("[0][0][0][18][2][144][0][12]myworld_view[0][0]");
System.out.println(packet.toExpression());
packet = new HPacket("[0][0][0]ã[4]Ù[0][0][0][12][0][0][0][1][0][18]Vetste Evenementen[0][0][0][0][2][0][16]Feesten & Muziek[1][0][0][0][3][0][10]Rollenspel[1][0][0][0][4][0][9]Help Desk[1][0][0][0][5][0][6]Ruilen[1][0][0][0][6][0][5]Games[1][0][0][0][7][0][7]Bouwers[1][0][0][0][8][0][21]Debatten & Discussies[1][0][0][0][9][0][9]Friending[1][0][0][0][10][0][10]Habbo Werk[1][0][0][0][11][0][9]Evenement[1][0][0][0][12][0][17]Groepsevenementen[0]");
System.out.println(packet.toExpression());
}
}

View File

@ -9,11 +9,10 @@ public class HostReplacerFactory {
public static HostReplacer get() {
if (OSValidator.isUnix()) return new LinuxHostReplacer();
if (OSValidator.isUnix() || OSValidator.isMac()) return new UnixHostReplacer();
if (OSValidator.isWindows()) return new WindowsHostReplacer();
if (OSValidator.isMac()) return new MacOSHostReplacer();
return new LinuxHostReplacer();
return new UnixHostReplacer();
}
}

View File

@ -1,16 +0,0 @@
package main.protocol.hostreplacer;
/**
* Created by Jonas on 04/04/18.
*/
class MacOSHostReplacer implements HostReplacer {
@Override
public void addRedirect(String original, String redirect) {
}
@Override
public void removeRedirect(String original, String redirect) {
}
}

View File

@ -6,11 +6,11 @@ import java.util.ArrayList;
/**
* Created by Jeunez on 04/04/18.
*/
class LinuxHostReplacer implements HostReplacer {
class UnixHostReplacer implements HostReplacer {
protected String hostsFileLocation;
LinuxHostReplacer() {
UnixHostReplacer() {
hostsFileLocation = "/etc/hosts";
}

View File

@ -3,7 +3,7 @@ package main.protocol.hostreplacer;
/**
* Created by Jonas on 04/04/18.
*/
class WindowsHostReplacer extends LinuxHostReplacer {
class WindowsHostReplacer extends UnixHostReplacer {
WindowsHostReplacer() {
super();

View File

@ -2,6 +2,7 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
@ -15,14 +16,14 @@
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="172.0" minHeight="10.0" prefHeight="140.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="127.0" minHeight="10.0" prefHeight="122.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane alignment="CENTER" GridPane.hgrow="SOMETIMES" GridPane.vgrow="SOMETIMES">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="364.0" minWidth="10.0" prefWidth="325.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="279.0" minWidth="10.0" prefWidth="252.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="483.0" minWidth="10.0" prefWidth="317.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="350.0" minWidth="10.0" prefWidth="248.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
@ -34,8 +35,9 @@
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="32.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="32.0" minHeight="10.0" prefHeight="29.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="45.0" minHeight="10.0" prefHeight="43.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="40.0" minHeight="10.0" prefHeight="37.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="45.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="45.0" minHeight="10.0" prefHeight="21.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<GridPane>
@ -48,7 +50,7 @@
</rowConstraints>
<children>
<Label text="Port:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpPort" editable="true" GridPane.columnIndex="1">
<ComboBox fx:id="inpPort" disable="true" editable="true" prefWidth="183.0" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
@ -65,72 +67,65 @@
</rowConstraints>
<children>
<Label text="Host:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
<ComboBox fx:id="inpHost" editable="true" GridPane.columnIndex="1">
<ComboBox fx:id="inpHost" disable="true" editable="true" GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="15.0" />
</GridPane.margin>
</ComboBox>
</children>
</GridPane>
<Button fx:id="btnConnect" alignment="CENTER" maxWidth="1.7976931348623157E308" onAction="#btnConnect_clicked" text="Connect" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets left="15.0" right="15.0" />
</GridPane.margin></Button>
<GridPane GridPane.rowIndex="2">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="185.0" minWidth="10.0" prefWidth="158.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="117.0" minWidth="10.0" prefWidth="90.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<children>
<CheckBox fx:id="cbx_autodetect" mnemonicParsing="false" selected="true" text="Auto-detect" textFill="#000000a9" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets left="-5.0" />
</GridPane.margin>
<font>
<Font size="12.0" />
</font>
</CheckBox>
<Button fx:id="btnConnect" alignment="CENTER" maxWidth="1.7976931348623157E308" onAction="#btnConnect_clicked" text="Connect" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets left="15.0" right="15.0" />
</GridPane.margin>
</Button>
</children>
</GridPane>
</children>
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets bottom="6.0" top="22.0" />
<Insets top="20.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="140.0" minWidth="10.0" prefWidth="103.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="191.0" minWidth="10.0" prefWidth="190.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="12.0" left="20.0" right="10.0" top="18.0" />
</GridPane.margin>
<children>
<Label text="Public key:" textFill="#000000cc">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<Label text="Private key:" textFill="#000000cc" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
</Label>
<TextField editable="false" GridPane.columnIndex="1">
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
<TextField editable="false" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="5.0" right="10.0" />
</GridPane.margin>
</TextField>
</children>
<padding>
<Insets bottom="7.0" top="7.0" />
</padding>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px;">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="14.0" left="20.0" right="15.0" top="17.0" />
</GridPane.margin>
</GridPane>
</children>
</GridPane>
<GridPane alignment="CENTER" GridPane.rowIndex="1">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="283.0" minWidth="10.0" prefWidth="197.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="380.0" minWidth="10.0" prefWidth="380.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="340.0" minWidth="10.0" prefWidth="208.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="380.0" minWidth="10.0" prefWidth="357.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
@ -153,10 +148,13 @@
<Font size="12.0" />
</font>
</Label>
<Label fx:id="lblState" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-border-radius: 5px;" text="Not connected" textAlignment="CENTER" textFill="#000000d1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS" />
<Label fx:id="lblState" alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: #888888; -fx-border-radius: 5px;" text="Not connected" textAlignment="CENTER" textFill="#000000d1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<GridPane.margin>
<Insets />
</GridPane.margin></Label>
</children>
<GridPane.margin>
<Insets bottom="14.0" left="20.0" />
<Insets bottom="14.0" left="20.0" right="20.0" />
</GridPane.margin>
</GridPane>
<GridPane style="-fx-border-color: #888888; -fx-border-radius: 5px; " GridPane.columnIndex="1">
@ -169,7 +167,7 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<GridPane.margin>
<Insets bottom="12.0" left="20.0" right="10.0" top="18.0" />
<Insets bottom="12.0" left="20.0" right="10.0" top="12.0" />
</GridPane.margin>
<children>
<Label text="Game host:" textFill="#000000cc">

View File

@ -7,10 +7,7 @@ import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import main.protocol.HConnection;
import main.ui.SubForm;
@ -24,6 +21,7 @@ public class Connection extends SubForm {
public Label lblState;
public TextField outHost;
public TextField outPort;
public CheckBox cbx_autodetect;
private boolean isBusy = false;
@ -37,6 +35,10 @@ public class Connection extends SubForm {
btnConnect.setDisable(true);
}
});
cbx_autodetect.selectedProperty().addListener(observable -> {
inpPort.setDisable(cbx_autodetect.isSelected());
inpHost.setDisable(cbx_autodetect.isSelected());
});
inpPort.getItems().addAll("30000", "38101");
inpHost.getItems().addAll("game-nl.habbo.com", "game-us.habbo.com");

View File

@ -72,7 +72,7 @@
<VBox alignment="BOTTOM_LEFT" prefHeight="99.0" prefWidth="198.0" spacing="8.0" GridPane.rowIndex="1">
<children>
<CheckBox fx:id="cbx_showAdditional" mnemonicParsing="false" selected="true" text="Show additional data" />
<CheckBox disable="true" mnemonicParsing="false" selected="true" text="Show packet structure" />
<CheckBox fx:id="cbx_showstruct" mnemonicParsing="false" selected="true" text="Show packet structure" />
<CheckBox fx:id="cbx_splitPackets" mnemonicParsing="false" selected="true" text="Split packets" />
</children>
<GridPane.margin>

View File

@ -12,6 +12,8 @@ import javafx.scene.text.TextFlow;
import main.protocol.HConnection;
import main.protocol.HMessage;
import main.ui.SubForm;
import main.ui.logger.loggerdisplays.PacketLogger;
import main.ui.logger.loggerdisplays.PacketLoggerFactory;
import java.util.Calendar;
import java.util.HashMap;
@ -28,43 +30,24 @@ public class Logger extends SubForm {
public CheckBox cbx_useLog;
public TextFlow txt_logField;
public Button btnUpdate;
public CheckBox cbx_showstruct;
private int packetLimit = 8000;
public final static Map<String, String> colorizePackets;
static {
//FOR GNOME ONLY, shows up colorized packets
colorizePackets = new HashMap<>();
colorizePackets.put("BLOCKED", (char)27 + "[35m"); // some kind of grey
colorizePackets.put("INCOMING", (char)27 + "[31m"); // red
colorizePackets.put("OUTGOING", (char)27 + "[34m"); // blue
colorizePackets.put("REPLACED", (char)27 + "[33m"); // yellow
// others:
colorizePackets.put("INJECTED", "");
colorizePackets.put("SKIPPED", (char)27 + "[36m");
colorizePackets.put("DEFAULT", (char)27 + "[0m");
if (System.getenv("XDG_CURRENT_DESKTOP") == null || !System.getenv("XDG_CURRENT_DESKTOP").toLowerCase().contains("gnome")) {
for (String key : colorizePackets.keySet()) {
colorizePackets.put(key, "");
}
}
}
private PacketLogger packetLogger = PacketLoggerFactory.get();
public void onParentSet(){
getHConnection().addStateChangeListener((oldState, newState) -> Platform.runLater(() -> {
if (newState == HConnection.State.PREPARING) {
miniLogText(Color.ORANGE, "Connecting to "+getHConnection().getDomain() + ":" + getHConnection().getPort());
}
if (newState == HConnection.State.CONNECTED) {
miniLogText(Color.GREEN, "Connecting to "+getHConnection().getDomain() + ":" + getHConnection().getPort());
packetLogger.start();
}
if (newState == HConnection.State.NOT_CONNECTED) {
miniLogText(Color.RED, "End of connection");
packetLogger.stop();
}
}));
@ -72,32 +55,23 @@ public class Logger extends SubForm {
if (message.getDestination() == HMessage.Side.TOCLIENT && cbx_blockIn.isSelected() ||
message.getDestination() == HMessage.Side.TOSERVER && cbx_blockOut.isSelected()) return;
String splitter = cbx_splitPackets.isSelected() ? "-----------------------------------\n" : "";
String type = message.getDestination() == HMessage.Side.TOCLIENT ?"" +
colorizePackets.get("INCOMING") + "INCOMING" :
colorizePackets.get("OUTGOING") + "OUTGOING";
String additionalData = " ";
if (!message.isCorrupted() && cbx_showAdditional.isSelected()) {
additionalData = " (h:"+ message.getPacket().headerId() +", l:"+message.getPacket().length()+") ";
if (cbx_splitPackets.isSelected()) {
packetLogger.appendSplitLine();
}
String arrow = "--> ";
int types = 0;
if (message.getDestination() == HMessage.Side.TOCLIENT) types |= PacketLogger.MESSAGE_TYPE.INCOMING.getValue();
else if (message.getDestination() == HMessage.Side.TOSERVER) types |= PacketLogger.MESSAGE_TYPE.OUTGOING.getValue();
if (message.getPacket().length() >= packetLimit) types |= PacketLogger.MESSAGE_TYPE.SKIPPED.getValue();
if (message.isBlocked()) types |= PacketLogger.MESSAGE_TYPE.BLOCKED.getValue();
if (message.getPacket().isReplaced()) types |= PacketLogger.MESSAGE_TYPE.REPLACED.getValue();
if (cbx_showAdditional.isSelected()) types |= PacketLogger.MESSAGE_TYPE.SHOW_ADDITIONAL_DATA.getValue();
String packet = message.isCorrupted() ?
message.getPacket().getBytesLength() + " (encrypted)": // message.getPacket().toString() : // TEMP CODE TO VIEW ENCRYPTED BODY
message.getPacket().length() < packetLimit ?
message.getPacket().toString() :
colorizePackets.get("SKIPPED") + "<packet skipped (length >= " + (packetLimit) + ")>";
String skipStyle = colorizePackets.get("DEFAULT");
String isBlocked = message.isBlocked() ? colorizePackets.get("BLOCKED") + "[BLOCKED] " : "";
String isEdited = !message.getPacket().isReplaced() || message.isBlocked() ? "" : colorizePackets.get("REPLACED") + "[REPLACED] ";
System.out.println(splitter + isBlocked + isEdited + type + additionalData + arrow + packet + skipStyle);
packetLogger.appendMessage(message.getPacket(), types);
if (cbx_showstruct.isSelected() && message.getPacket().length() < packetLimit) {
packetLogger.appendStructure(message.getPacket());
}
});
});
}

View File

@ -0,0 +1,73 @@
package main.ui.logger.loggerdisplays;
import main.protocol.HPacket;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Jonas on 04/04/18.
*/
class GnomeTerminalLogger extends SimpleTerminalLogger {
public final static Map<String, String> colorizePackets;
static {
//FOR GNOME ONLY, shows up colorized packets
colorizePackets = new HashMap<>();
colorizePackets.put("BLOCKED", (char) 27 + "[35m"); // some kind of grey
colorizePackets.put("INCOMING", (char) 27 + "[31m"); // red
colorizePackets.put("OUTGOING", (char) 27 + "[34m"); // blue
colorizePackets.put("REPLACED", (char) 27 + "[33m"); // yellow
// others:
colorizePackets.put("INJECTED", "[32m");
colorizePackets.put("SKIPPED", (char) 27 + "[36m");
colorizePackets.put("EXPRESSION", (char) 27 + "[36m");
colorizePackets.put("DEFAULT", (char) 27 + "[0m");
}
@Override
public void appendMessage(HPacket packet, int types) {
StringBuilder output = new StringBuilder();
if ((types & MESSAGE_TYPE.BLOCKED.getValue()) != 0) {
output.append(colorizePackets.get("BLOCKED")).append("[BLOCKED] ");
}
else if ((types & MESSAGE_TYPE.REPLACED.getValue()) != 0) {
output.append(colorizePackets.get("REPLACED")).append("[REPLACED] ");
}
output.append(
(types & MESSAGE_TYPE.INCOMING.getValue()) != 0 ?
colorizePackets.get("INCOMING") + "INCOMING " :
colorizePackets.get("OUTGOING") + "OUTGOING "
);
if ((types & MESSAGE_TYPE.SHOW_ADDITIONAL_DATA.getValue()) != 0) {
output.append("(h:").append(packet.headerId()).append(", l:").append(packet.length()).append(") ");
}
output.append("--> ");
output.append( (types & MESSAGE_TYPE.SKIPPED.getValue()) != 0 ?
colorizePackets.get("SKIPPED") + "<packet skipped>" :
packet.toString()
);
output.append(colorizePackets.get("DEFAULT"));
System.out.println(output.toString());
}
@Override
public void appendStructure(HPacket packet) {
String expr = packet.toExpression();
if (!expr.equals("")) {
System.out.println(
colorizePackets.get("EXPRESSION") +
expr +
colorizePackets.get("DEFAULT")
);
}
}
}

View File

@ -0,0 +1,38 @@
package main.ui.logger.loggerdisplays;
import main.protocol.HMessage;
import main.protocol.HPacket;
/**
* Created by Jonas on 04/04/18.
*/
public interface PacketLogger {
enum MESSAGE_TYPE {
BLOCKED(1),
INCOMING(2),
OUTGOING(4),
REPLACED(8),
INJECTED(16),
SKIPPED(32), // don't display the whole packet
SHOW_ADDITIONAL_DATA(64);
private int val;
MESSAGE_TYPE(int val)
{
this.val = val;
}
public int getValue()
{
return val;
}
}
void start();
void stop();
void appendSplitLine();
void appendMessage(HPacket packet, int types);
void appendStructure(HPacket packet);
}

View File

@ -0,0 +1,15 @@
package main.ui.logger.loggerdisplays;
/**
* Created by Jonas on 04/04/18.
*/
public class PacketLoggerFactory {
public static PacketLogger get() {
if (System.getenv("XDG_CURRENT_DESKTOP") != null && System.getenv("XDG_CURRENT_DESKTOP").toLowerCase().contains("gnome")) {
return new GnomeTerminalLogger();
}
return new SimpleTerminalLogger();
}
}

View File

@ -0,0 +1,60 @@
package main.ui.logger.loggerdisplays;
import main.protocol.HPacket;
/**
* Created by Jonas on 04/04/18.
*/
class SimpleTerminalLogger implements PacketLogger {
@Override
public void start() {
// System.out.println("-- START OF SESSION --");
}
@Override
public void stop() {
// System.out.println("-- END OF SESSION --");
}
@Override
public void appendSplitLine() {
System.out.println("-----------------------------------");
}
@Override
public void appendMessage(HPacket packet, int types) {
StringBuilder output = new StringBuilder();
if ((types & MESSAGE_TYPE.BLOCKED.getValue()) != 0) {
output.append("[BLOCKED] ");
}
else if ((types & MESSAGE_TYPE.REPLACED.getValue()) != 0) {
output.append("[REPLACED] ");
}
output.append(
(types & MESSAGE_TYPE.INCOMING.getValue()) != 0 ?
"INCOMING " :
"OUTGOING "
);
if ((types & MESSAGE_TYPE.SHOW_ADDITIONAL_DATA.getValue()) != 0) {
output.append("(h:").append(packet.headerId()).append(", l:").append(packet.length()).append(") ");
}
output.append("--> ");
output.append( (types & MESSAGE_TYPE.SKIPPED.getValue()) != 0 ?
"<packet skipped>" :
packet.toString()
);
}
@Override
public void appendStructure(HPacket packet) {
String expr = packet.toExpression();
if (!expr.equals("")) {
System.out.println(expr);
}
}
}

View File

@ -126,22 +126,22 @@
<Insets />
</GridPane.margin>
<children>
<Button disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="------&gt;" GridPane.columnIndex="1" GridPane.halignment="CENTER">
<Button fx:id="btn_toExpr" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btn_toExpr_clicked" text="------&gt;" GridPane.columnIndex="1" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</Button>
<TextArea disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" GridPane.halignment="CENTER">
<TextArea fx:id="txt_packetArea" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="7.0" right="5.0" top="7.0" />
</GridPane.margin>
</TextArea>
<Button disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="&lt;------" GridPane.columnIndex="2" GridPane.halignment="CENTER">
<Button fx:id="btn_toPacket" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btn_toPacket_clicked" text="&lt;------" GridPane.columnIndex="2" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="5.0" top="7.0" />
</GridPane.margin>
</Button>
<TextArea disable="true" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3" GridPane.halignment="CENTER">
<TextArea fx:id="txt_exprArea" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" wrapText="true" GridPane.columnIndex="3" GridPane.halignment="CENTER">
<GridPane.margin>
<Insets bottom="7.0" left="5.0" right="7.0" top="7.0" />
</GridPane.margin>

View File

@ -3,6 +3,7 @@ package main.ui.tools;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
@ -23,6 +24,12 @@ public class Tools extends SubForm {
public Button btnEncodeUShort;
public Button btnDecodeUshort;
public Button btn_toExpr;
public TextArea txt_packetArea;
public Button btn_toPacket;
public TextArea txt_exprArea;
//TODO: toExpression() without bytelength limit for this use only
public void initialize() {
txt_intDecoded.textProperty().addListener(observable -> {
@ -98,11 +105,9 @@ public class Tools extends SubForm {
HPacket packet = new HPacket(b.array());
txt_intEncoded.setText(packet.toString());
}
public void btnDecodeInt_clicked(ActionEvent actionEvent) {
txt_intDecoded.setText(new HPacket(txt_intEncoded.getText()).readInteger(0) + "");
}
public void btnEncodeUShort_clicked(ActionEvent actionEvent) {
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(Integer.parseInt(txt_ushortDecoded.getText()));
@ -110,8 +115,16 @@ public class Tools extends SubForm {
HPacket packet = new HPacket(new byte[]{b.array()[2], b.array()[3]});
txt_ushortEncoded.setText(packet.toString());
}
public void btnDecodeUshort_clicked(ActionEvent actionEvent) {
txt_ushortDecoded.setText(new HPacket(txt_ushortEncoded.getText()).readUshort(0) + "");
}
public void btn_toExpr_clicked(ActionEvent actionEvent) {
txt_exprArea.setText(new HPacket(txt_packetArea.getText()).toExpression());
}
public void btn_toPacket_clicked(ActionEvent actionEvent) {
txt_packetArea.setText(new HPacket(txt_exprArea.getText()).toString());
}
}