Added more extensive logging, cleaned up mac os habbo client

This commit is contained in:
dorving 2023-03-01 10:05:40 +01:00
parent 6a9b1201ac
commit b40ad3a5dd
14 changed files with 237 additions and 248 deletions

View File

@ -0,0 +1,22 @@
package gearth.misc;
/**
* Contains utility methods for {@link String} conversions.
*/
public final class StringUtils {
/**
* Interprets the argued {@link String} as a hex-string and converts it to a byte array.
* @param hexString the {@link String} to be converted.
* @return a byte array containing the converted hex string values.
*/
public static byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ Character.digit(hexString.charAt(i+1), 16));
}
return data;
}
}

View File

@ -20,7 +20,7 @@ import java.util.function.Consumer;
public class HConnection { public class HConnection {
public static volatile boolean DECRYPTPACKETS = true; public static volatile boolean DECRYPTPACKETS = true;
public static volatile boolean DEBUG = false; public static volatile boolean DEBUG = true;
private volatile ExtensionHandler extensionHandler = null; private volatile ExtensionHandler extensionHandler = null;
@ -255,4 +255,12 @@ public class HConnection {
public ProxyProvider getProxyProvider() { public ProxyProvider getProxyProvider() {
return proxyProvider; return proxyProvider;
} }
@Override
public String toString() {
return "HConnection{" +
"state=" + state +
", proxy=" + proxy +
'}';
}
} }

View File

@ -116,4 +116,21 @@ public class HProxy {
public PacketInfoManager getPacketInfoManager() { public PacketInfoManager getPacketInfoManager() {
return packetInfoManager; return packetInfoManager;
} }
@Override
public String toString() {
return "HProxy{" +
"hClient=" + hClient +
", input_domain='" + input_domain + '\'' +
", actual_domain='" + actual_domain + '\'' +
", actual_port=" + actual_port +
", intercept_port=" + intercept_port +
", intercept_host='" + intercept_host + '\'' +
", proxy_server=" + proxy_server +
", inHandler=" + inHandler +
", outHandler=" + outHandler +
", hotelVersion='" + hotelVersion + '\'' +
", clientIdentifier='" + clientIdentifier + '\'' +
'}';
}
} }

View File

@ -7,18 +7,18 @@ import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter; import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider; import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.memory.Rc4Obtainer; import gearth.protocol.memory.Rc4Obtainer;
import gearth.protocol.packethandler.flash.FlashPacketHandler;
import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler; import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler; import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
import gearth.protocol.packethandler.flash.FlashPacketHandler;
import gearth.ui.titlebar.TitleBarController; import gearth.ui.titlebar.TitleBarController;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.stage.Stage; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
@ -27,6 +27,7 @@ import java.util.concurrent.Semaphore;
public abstract class FlashProxyProvider implements ProxyProvider { public abstract class FlashProxyProvider implements ProxyProvider {
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected final HProxySetter proxySetter; protected final HProxySetter proxySetter;
protected final HStateSetter stateSetter; protected final HStateSetter stateSetter;
protected final HConnection hConnection; protected final HConnection hConnection;
@ -47,7 +48,8 @@ public abstract class FlashProxyProvider implements ProxyProvider {
client.setSoTimeout(0); client.setSoTimeout(0);
server.setSoTimeout(0); server.setSoTimeout(0);
if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort()); logger.debug("Starting proxy thread at {}:{}", server.getLocalAddress().getHostAddress(), server.getLocalPort());
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection); Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler()); OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
@ -73,13 +75,13 @@ public abstract class FlashProxyProvider implements ProxyProvider {
try { try {
if (!server.isClosed()) server.close(); if (!server.isClosed()) server.close();
if (!client.isClosed()) client.close(); if (!client.isClosed()) client.close();
if (HConnection.DEBUG) System.out.println("STOP"); logger.debug("Closed server {} and client {}, dataStreams {}", server, client, datastream);
if (datastream[0]) { if (datastream[0]) {
onConnectEnd(); onConnectEnd();
}; };
} }
catch (IOException e) { catch (IOException e) {
e.printStackTrace(); logger.error("Failed to gracefully stop", e);
} }
} }
@ -95,8 +97,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
} }
} }
catch (IOException ignore) { catch (IOException ignore) {
// System.err.println(packetHandler instanceof IncomingPacketHandler ? "incoming" : "outgoing"); // logger.error("Failed to read input stream from socket {}", socket, ignore);
// ignore.printStackTrace();
} finally { } finally {
abort.release(); abort.release();
} }
@ -132,9 +133,8 @@ public abstract class FlashProxyProvider implements ProxyProvider {
try { try {
TitleBarController.create(alert).showAlert(); TitleBarController.create(alert).showAlert();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); logger.error("Failed to create invalid connection error alert", e);
} }
}); });
} }
} }

View File

@ -1,6 +1,5 @@
package gearth.protocol.connection.proxy.flash; package gearth.protocol.connection.proxy.flash;
import gearth.GEarth;
import gearth.misc.Cacher; import gearth.misc.Cacher;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.connection.*; import gearth.protocol.connection.*;
@ -14,8 +13,6 @@ import gearth.ui.titlebar.TitleBarController;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.*;
@ -26,7 +23,6 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
private List<String> potentialHosts; private List<String> potentialHosts;
private static final HostReplacer hostsReplacer = HostReplacerFactory.get(); private static final HostReplacer hostsReplacer = HostReplacerFactory.get();
private volatile boolean hostRedirected = false; private volatile boolean hostRedirected = false;
@ -113,7 +109,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
try { try {
TitleBarController.create(a).showAlertAndWait(); TitleBarController.create(a).showAlertAndWait();
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); logger.error("Failed to create port in use error alert", ex);
} }
}); });
throw new IOException(e); throw new IOException(e);
@ -128,8 +124,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
Socket client = proxy_server.accept(); Socket client = proxy_server.accept();
proxy = potentialProxy; proxy = potentialProxy;
closeAllProxies(proxy); closeAllProxies(proxy);
if (HConnection.DEBUG) System.out.println("accepted a proxy"); logger.debug("Accepted proxy {}, starting proxy thread (useSocks={})",proxy, useSocks);
new Thread(() -> { new Thread(() -> {
try { try {
Socket server; Socket server;
@ -152,18 +147,14 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
// should only happen when SOCKS configured badly // should only happen when SOCKS configured badly
showInvalidConnectionError(); showInvalidConnectionError();
abort(); abort();
e.printStackTrace(); logger.error("Failed to configure SOCKS proxy", e);
} }
catch (InterruptedException | IOException e) { catch (InterruptedException | IOException e) {
// TODO Auto-generated catch block logger.error("An unexpected exception occurred", e);
e.printStackTrace();
} }
}).start(); }).start();
} catch (IOException e1) { } catch (IOException e1) {
// TODO Auto-generated catch block logger.error("An unexpected exception occurred", e1);
// e1.printStackTrace();
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -171,10 +162,7 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
} }
}).start(); }).start();
} }
logger.debug("Done waiting for clients with connection state {}", hConnection.getState());
if (HConnection.DEBUG) System.out.println("done waiting for clients with: " + hConnection.getState() );
} }
@Override @Override
@ -233,12 +221,10 @@ public class NormalFlashProxyProvider extends FlashProxyProvider {
try { try {
proxy.getProxy_server().close(); proxy.getProxy_server().close();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block logger.error("Failed to close all proxies", e);
e.printStackTrace();
} }
} }
} }
} }
// potentialProxies = Collections.singletonList(except);
} }
} }

View File

@ -54,7 +54,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
maybeAddMapping(); maybeAddMapping();
if (HConnection.DEBUG) System.out.println("Added mapping for raw IP"); logger.debug("Added mapping for raw IP");
ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host())); ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
proxy.initProxy(proxy_server); proxy.initProxy(proxy_server);
@ -62,10 +62,10 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
stateSetter.setState(HState.WAITING_FOR_CLIENT); stateSetter.setState(HState.WAITING_FOR_CLIENT);
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) { while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
try { try {
if (HConnection.DEBUG) System.out.println("try accept proxy"); logger.debug("Trying to accept a new proxy from {}", proxy_server);
Socket client = proxy_server.accept(); Socket client = proxy_server.accept();
if (HConnection.DEBUG) System.out.println("accepted a proxy"); logger.debug("Accepted a proxy {}", client);
new Thread(() -> { new Thread(() -> {
try { try {
@ -82,7 +82,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); logger.error("An unexpected exception occurred in proxy listener", e);
} }
}).start(); }).start();
} }
@ -114,7 +114,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
try { try {
proxy.getProxy_server().close(); proxy.getProxy_server().close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); logger.error("Failed to close proxy server", e);
} }
} }
} }
@ -136,6 +136,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
} }
catch (SocketTimeoutException e) { catch (SocketTimeoutException e) {
showInvalidConnectionError(); showInvalidConnectionError();
logger.error("Connection to proxy {} timed out", proxy, e);
return false; return false;
} }
@ -151,7 +152,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
createSocksProxyThread(client); createSocksProxyThread(client);
} }
else if (preConnectedServerConnections.isEmpty()) { else if (preConnectedServerConnections.isEmpty()) {
if (HConnection.DEBUG) System.out.println("pre-made server connections ran out of stock"); logger.error("pre-made server connections ran out of stock");
} }
else { else {
startProxyThread(client, preConnectedServerConnections.poll(), proxy); startProxyThread(client, preConnectedServerConnections.poll(), proxy);
@ -165,6 +166,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
maybeRemoveMapping(); maybeRemoveMapping();
stateSetter.setState(HState.NOT_CONNECTED); stateSetter.setState(HState.NOT_CONNECTED);
showInvalidConnectionError(); showInvalidConnectionError();
logger.error("Failed to create socks proxy thread because configuration is null");
return; return;
} }
@ -177,7 +179,7 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
maybeRemoveMapping(); maybeRemoveMapping();
stateSetter.setState(HState.NOT_CONNECTED); stateSetter.setState(HState.NOT_CONNECTED);
showInvalidConnectionError(); showInvalidConnectionError();
e.printStackTrace(); logger.error("Failed to create socks proxy thread", e);
} }
} }
@ -188,7 +190,5 @@ public class LinuxRawIpFlashProxyProvider extends FlashProxyProvider {
protected void maybeRemoveMapping() { protected void maybeRemoveMapping() {
ipMapper.deleteMapping(proxy.getActual_domain(), proxy.getActual_port(), proxy.getIntercept_port()); ipMapper.deleteMapping(proxy.getActual_domain(), proxy.getActual_port(), proxy.getIntercept_port());
} }
} }

View File

@ -1,14 +1,21 @@
package gearth.protocol.hostreplacer.hostsfile; package gearth.protocol.hostreplacer.hostsfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* Created by Jonas on 04/04/18. * Created by Jonas on 04/04/18.
*/ */
class UnixHostReplacer implements HostReplacer { class UnixHostReplacer implements HostReplacer {
private static final Logger LOGGER = LoggerFactory.getLogger(UnixHostReplacer.class);
protected String hostsFileLocation; protected String hostsFileLocation;
UnixHostReplacer() { UnixHostReplacer() {
@ -17,23 +24,24 @@ class UnixHostReplacer implements HostReplacer {
@Override @Override
public void addRedirect(String[] lines) { public void addRedirect(String[] lines) {
List<String> adders = new ArrayList<>();
for (int i = 0; i < lines.length; i++) {
adders.add(lines[i] + "\t# G-Earth replacement");
}
FileReader fr = null; final List<String> adders = appendCommentToEachLine(lines);
BufferedReader br = null;
FileWriter fw = null;
BufferedWriter out = null;
FileReader fr;
BufferedReader br;
FileWriter fw;
BufferedWriter out;
try try
{ {
ArrayList<String> fileLines = new ArrayList<>(); final ArrayList<String> fileLines = new ArrayList<>();
File f1 = new File(hostsFileLocation); final File hostsFile = new File(hostsFileLocation);
fr = new FileReader(f1);
LOGGER.debug("Replacing hosts at {}", hostsFile.getAbsolutePath());
fr = new FileReader(hostsFile);
br = new BufferedReader(fr); br = new BufferedReader(fr);
String line = null;
String line;
while ((line = br.readLine()) != null) while ((line = br.readLine()) != null)
{ {
adders.remove(line); adders.remove(line);
@ -42,7 +50,7 @@ class UnixHostReplacer implements HostReplacer {
fr.close(); fr.close();
br.close(); br.close();
fw = new FileWriter(f1); fw = new FileWriter(hostsFile);
out = new BufferedWriter(fw); out = new BufferedWriter(fw);
for (String li : adders) { for (String li : adders) {
@ -58,29 +66,26 @@ class UnixHostReplacer implements HostReplacer {
} }
catch (Exception ex) catch (Exception ex)
{ {
ex.printStackTrace(); LOGGER.error("Failed to add host redirects", ex);
} }
} }
@Override @Override
public void removeRedirect(String[] lines) { public void removeRedirect(String[] lines) {
ArrayList<String> removers = new ArrayList<>(); final List<String> removers = appendCommentToEachLine(lines);
for (int i = 0; i < lines.length; i++) {
removers.add(lines[i] + "\t# G-Earth replacement");
}
FileReader fr = null; FileReader fr;
BufferedReader br = null; BufferedReader br;
FileWriter fw = null; FileWriter fw;
BufferedWriter out = null; BufferedWriter out;
try try
{ {
ArrayList<String> fileLines = new ArrayList<String>(); final ArrayList<String> fileLines = new ArrayList<>();
File f1 = new File(hostsFileLocation); final File hostsFile = new File(hostsFileLocation);
fr = new FileReader(f1); fr = new FileReader(hostsFile);
br = new BufferedReader(fr); br = new BufferedReader(fr);
String line = null; String line;
while ((line = br.readLine()) != null) while ((line = br.readLine()) != null)
{ {
if (!removers.contains(line)) if (!removers.contains(line))
@ -89,12 +94,13 @@ class UnixHostReplacer implements HostReplacer {
fr.close(); fr.close();
br.close(); br.close();
fw = new FileWriter(f1); fw = new FileWriter(hostsFile);
out = new BufferedWriter(fw); out = new BufferedWriter(fw);
for (int i = 0; i < fileLines.size(); i++) { for (int i = 0; i < fileLines.size(); i++) {
out.write(fileLines.get(i)); out.write(fileLines.get(i));
if (i != fileLines.size() - 1) out.write(System.getProperty("line.separator")); if (i != fileLines.size() - 1)
out.write(System.getProperty("line.separator"));
} }
out.flush(); out.flush();
fw.close(); fw.close();
@ -102,7 +108,14 @@ class UnixHostReplacer implements HostReplacer {
} }
catch (Exception ex) catch (Exception ex)
{ {
ex.printStackTrace(); LOGGER.error("Failed to remove host replace lines", ex);
} }
} }
private static List<String> appendCommentToEachLine(String[] lines) {
return Arrays
.stream(lines)
.map(line -> line + "\t# G-Earth replacement")
.collect(Collectors.toList());
}
} }

View File

@ -18,6 +18,8 @@ import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
@ -25,7 +27,9 @@ import java.util.List;
public class Rc4Obtainer { public class Rc4Obtainer {
public static final boolean DEBUG = false; private static final Logger LOGGER = LoggerFactory.getLogger(Rc4Obtainer.class);
public static final boolean DEBUG = true;
private final HabboClient client; private final HabboClient client;
private List<FlashPacketHandler> flashPacketHandlers; private List<FlashPacketHandler> flashPacketHandlers;
@ -58,8 +62,7 @@ public class Rc4Obtainer {
new Thread(() -> { new Thread(() -> {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
if (DEBUG) System.out.println("[+] send encrypted"); LOGGER.debug("[+] send encrypted");
boolean worked = false; boolean worked = false;
int i = 0; int i = 0;
while (!worked && i < 4) { while (!worked && i < 4) {
@ -70,8 +73,7 @@ public class Rc4Obtainer {
} }
if (!worked) { if (!worked) {
System.err.println("COULD NOT FIND RC4 TABLE"); LOGGER.error("COULD NOT FIND RC4 TABLE");
Platform.runLater(() -> { Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("alert.somethingwentwrong.title"), ButtonType.OK); Alert alert = new Alert(Alert.AlertType.WARNING, LanguageBundle.get("alert.somethingwentwrong.title"), ButtonType.OK);
@ -90,14 +92,13 @@ public class Rc4Obtainer {
try { try {
TitleBarController.create(alert).showAlert(); TitleBarController.create(alert).showAlert();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Failed to create error alert", e);
} }
}); });
} }
final long endTime = System.currentTimeMillis(); final long endTime = System.currentTimeMillis();
if (DEBUG) LOGGER.debug("Cracked RC4 in " + (endTime - startTime) + "ms");
System.out.println("Cracked RC4 in " + (endTime - startTime) + "ms");
flashPacketHandlers.forEach(FlashPacketHandler::unblock); flashPacketHandlers.forEach(FlashPacketHandler::unblock);
}).start(); }).start();

View File

@ -3,7 +3,7 @@ package gearth.protocol.memory.habboclient;
import gearth.misc.OSValidator; import gearth.misc.OSValidator;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.memory.habboclient.linux.LinuxHabboClient; import gearth.protocol.memory.habboclient.linux.LinuxHabboClient;
import gearth.protocol.memory.habboclient.macOs.MacOsHabboClient; import gearth.protocol.memory.habboclient.macos.MacOSHabboClient;
import gearth.protocol.memory.habboclient.windows.WindowsHabboClient; import gearth.protocol.memory.habboclient.windows.WindowsHabboClient;
/** /**
@ -15,7 +15,7 @@ public class HabboClientFactory {
public static HabboClient get(HConnection connection) { public static HabboClient get(HConnection connection) {
if (OSValidator.isUnix()) return new LinuxHabboClient(connection); if (OSValidator.isUnix()) return new LinuxHabboClient(connection);
if (OSValidator.isWindows()) return new WindowsHabboClient(connection); if (OSValidator.isWindows()) return new WindowsHabboClient(connection);
if (OSValidator.isMac()) return new MacOsHabboClient(connection); if (OSValidator.isMac()) return new MacOSHabboClient(connection);
// todo use rust if beneficial // todo use rust if beneficial

View File

@ -1,144 +0,0 @@
package gearth.protocol.memory.habboclient.macOs;
import gearth.misc.Cacher;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.memory.habboclient.HabboClient;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
public class MacOsHabboClient extends HabboClient {
public MacOsHabboClient(HConnection connection) {
super(connection);
connection.addTrafficListener(0, message -> {
if (message.getDestination() == HMessage.Direction.TOSERVER && message.getPacket().headerId() == PRODUCTION_ID) {
production = message.getPacket().readString();
}
});
}
private static final String OFFSETS_CACHE_KEY = "RC4Offsets";
private static final int PRODUCTION_ID = 4000;
private String production = "";
@Override
public List<byte[]> getRC4cached() {
List<byte[]> result = new ArrayList<>();
try {
List<String> possibleResults = readPossibleBytes(true);
if (possibleResults == null)
return new ArrayList<>();
for (String s : possibleResults)
result.add(hexStringToByteArray(s));
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
return result;
}
private ArrayList<String> readPossibleBytes(boolean useCache) throws IOException, URISyntaxException {
ProcessBuilder pb;
JSONObject revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
if (revisionList == null) {
Cacher.put(OFFSETS_CACHE_KEY, new JSONObject());
revisionList = (JSONObject) Cacher.get(OFFSETS_CACHE_KEY);
}
assert revisionList != null;
JSONArray cachedOffsets;
if (revisionList.has(production))
cachedOffsets = (JSONArray) revisionList.get(production);
else
cachedOffsets = null;
StringJoiner joiner = new StringJoiner(" ");
if (useCache) {
if (cachedOffsets == null) {
return null;
}
for (Object s : cachedOffsets) {
joiner.add((String)s);
}
}
String g_mem = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "/G-Mem";
if (!useCache)
pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()));
else
pb = new ProcessBuilder(g_mem, hConnection.getClientHost() , Integer.toString(hConnection.getClientPort()), "-c" + joiner.toString());
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
ArrayList<String> possibleData = new ArrayList<>();
if (cachedOffsets == null) {
cachedOffsets = new JSONArray();
}
int count = 0;
while((line = reader.readLine()) != null) {
if (line.length() > 1) {
if (!useCache && (count++ % 2 == 0)) {
if (!cachedOffsets.toList().contains(line)) {
cachedOffsets.put(line);
System.out.println("[+] " + line);
}
}
else
possibleData.add(line);
}
}
revisionList.put(production, cachedOffsets);
Cacher.put(OFFSETS_CACHE_KEY, revisionList);
p.destroy();
return possibleData;
}
@Override
public List<byte[]> getRC4possibilities() {
List<byte[]> result = new ArrayList<>();
try {
ArrayList<String> possibleData = readPossibleBytes(false);
for (String possibleHexStr : possibleData) {
result.add(hexStringToByteArray(possibleHexStr));
}
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
return result;
}
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}

View File

@ -0,0 +1,104 @@
package gearth.protocol.memory.habboclient.macos;
import gearth.misc.StringUtils;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
import gearth.protocol.memory.habboclient.HabboClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
/**
* Represents a {@link HabboClient} implementation for the MacOS operating system.
*
* @author sirjonasxx / dorving (revised)
*/
public class MacOSHabboClient extends HabboClient {
private static final Logger LOGGER = LoggerFactory.getLogger(MacOSHabboClient.class);
private static final String G_MEM_EXECUTABLE_FILE_NAME = "/g_mem_mac";
/**
* The header id (opcode) of the packet that contains the value for the {@link #production} field.
*/
private static final int PRODUCTION_ID = 4000;
private String production = "";
/**
* Create a new {@link MacOSHabboClient} instance.
*
* @param connection the {@link HConnection connection} with the Habbo server.
*/
public MacOSHabboClient(HConnection connection) {
super(connection);
listenForProductionPacket(connection);
}
private void listenForProductionPacket(HConnection connection) {
connection.addTrafficListener(0, message -> {
if (message.getDestination() == HMessage.Direction.TOSERVER) {
final HPacket packet = message.getPacket();
if (packet.headerId() == PRODUCTION_ID) {
production = packet.readString();
LOGGER.debug("Read production packet from connection {}, set `production` to {}", connection, production);
}
}
});
}
@Override
public List<byte[]> getRC4cached() {
return new ArrayList<>();
}
@Override
public List<byte[]> getRC4possibilities() {
final List<byte[]> result = new ArrayList<>();
try {
for (String possibleHexStr : readPossibleBytes())
result.add(StringUtils.hexStringToByteArray(possibleHexStr));
} catch (IOException | URISyntaxException e) {
LOGGER.error("Failed to parse line as hex string", e);
}
return result;
}
private ArrayList<String> readPossibleBytes() throws IOException, URISyntaxException {
final String pathToGMemExecutable = getPathToGMemExecutable();
final String clientHost = hConnection.getClientHost();
final String clientPort = Integer.toString(hConnection.getClientPort());
LOGGER.debug("Attempting to execute G-Mem executable {} with host {} at port {}", pathToGMemExecutable, clientHost, clientPort);
final Process process = new ProcessBuilder(pathToGMemExecutable, clientHost, clientPort)
.start();
final ArrayList<String> possibleData = new ArrayList<>();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
int count = 0;
String line;
while((line = reader.readLine()) != null) {
if (line.length() > 1 && (count++ % 2 != 0))
possibleData.add(line);
}
} catch (Exception e) {
LOGGER.error("Failed to execute G-Mem", e);
} finally {
process.destroy();
}
LOGGER.debug("Read {} from G-Mem output stream", possibleData);
return possibleData;
}
private String getPathToGMemExecutable() throws URISyntaxException {
return new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + G_MEM_EXECUTABLE_FILE_NAME;
}
}

View File

@ -1,5 +1,6 @@
package gearth.protocol.memory.habboclient.rust; package gearth.protocol.memory.habboclient.rust;
import gearth.misc.StringUtils;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.memory.habboclient.HabboClient; import gearth.protocol.memory.habboclient.HabboClient;
@ -48,18 +49,9 @@ public class RustHabboClient extends HabboClient {
List<byte[]> ret = new ArrayList<>(); List<byte[]> ret = new ArrayList<>();
for (String possibleHexStr : possibleData) for (String possibleHexStr : possibleData)
ret.add(hexStringToByteArray(possibleHexStr)); ret.add(StringUtils.hexStringToByteArray(possibleHexStr));
return ret; return ret;
} }
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
} }

View File

@ -1,6 +1,7 @@
package gearth.protocol.memory.habboclient.windows; package gearth.protocol.memory.habboclient.windows;
import gearth.misc.Cacher; import gearth.misc.Cacher;
import gearth.misc.StringUtils;
import gearth.protocol.HConnection; import gearth.protocol.HConnection;
import gearth.protocol.HMessage; import gearth.protocol.HMessage;
import gearth.protocol.memory.habboclient.HabboClient; import gearth.protocol.memory.habboclient.HabboClient;
@ -44,7 +45,7 @@ public class WindowsHabboClient extends HabboClient {
return new ArrayList<>(); return new ArrayList<>();
for (String s : possibleResults) for (String s : possibleResults)
result.add(hexStringToByteArray(s)); result.add(StringUtils.hexStringToByteArray(s));
} catch (IOException | URISyntaxException e) { } catch (IOException | URISyntaxException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -124,23 +125,12 @@ public class WindowsHabboClient extends HabboClient {
List<byte[]> result = new ArrayList<>(); List<byte[]> result = new ArrayList<>();
try { try {
ArrayList<String> possibleData = readPossibleBytes(false); ArrayList<String> possibleData = readPossibleBytes(false);
for (String possibleHexStr : possibleData) { for (String possibleHexStr : possibleData) {
result.add(hexStringToByteArray(possibleHexStr)); result.add(StringUtils.hexStringToByteArray(possibleHexStr));
} }
} catch (IOException | URISyntaxException e) { } catch (IOException | URISyntaxException e) {
e.printStackTrace(); e.printStackTrace();
} }
return result; return result;
} }
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
} }

View File

@ -16,7 +16,7 @@ import java.util.List;
public abstract class FlashPacketHandler extends PacketHandler { public abstract class FlashPacketHandler extends PacketHandler {
protected static final boolean DEBUG = false; protected static final boolean DEBUG = true;
private volatile OutputStream out; private volatile OutputStream out;
private volatile boolean isTempBlocked = false; private volatile boolean isTempBlocked = false;