0

I've been trying to make some sort of alpha key system for my game. I thought in order to prevent people from decompiling my jar and changing around some code to bypass the system and get straight into my game, I thought about making it so after some verification, the server would send a serialized copy of a ClassLoader object to the client, which the client can then use to load the required files off an external host to start running the game.

Turns out it's not working at all.. ClassLoader seems to be non-serializeable. Are there any suggestions on how I could make a simliar system, or some way to somehow be able to ram that ClassLoader object through?

Source code:

Server.java:

package org.arno;

import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

import org.arno.Packet.ClassLoaderPacket;

public class InitServer {

private static ObjectOutputStream out;
private static ObjectInputStream in;
private static ServerSocket server;
private static Socket connection;
private static final float HANDSHAKE_UID = 9678;

public static void main(String[] args) {
    startServer();  
}

private static void startServer() {
    try {
        server = new ServerSocket(7799,100);
        System.out.println("[LoginServer] Initiated");
        while (true) {
            waitForClientConnection();
            setStreams();
            waitForHandShake();
            sendData();
            closeClientConnection();
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private static void closeClientConnection() throws Exception {
    out.close();
    in.close();
    connection.close(); 
}

private static void waitForHandShake() throws Exception{
    float handshake = (float) in.readObject();
    System.out.println(handshake == HANDSHAKE_UID? "Handshakes match UID" : "Wrong handshake sent");

}

private static void sendData() throws Exception {
    ClassLoaderPacket.writeObject(new ClassLoaderPacket(out));
    System.out.println("DATA SEND");
}

private static void waitForClientConnection() throws Exception {
    connection = server.accept();
    System.out.println("[LoginServer] Connection made from IP [" 
    + connection.getInetAddress().getHostAddress() + "]");

}

private static void setStreams() throws Exception {
    out = new ObjectOutputStream(connection.getOutputStream());
    out.flush();
    in = new ObjectInputStream(connection.getInputStream());

}
}

ClassLoaderPacket.java:

package org.arno.Packet;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;


/**
 * @author arno
 * File: ClassLoaderPacket.java
 */
public class ClassLoaderPacket implements Serializable {

static ObjectOutputStream out;
private transient ClassLoader cL;
private static final String GAME_URL = "https://dl.dropboxusercontent.com/u/9385659/Avalonpk718.jar";

public ClassLoaderPacket(ObjectOutputStream out) throws MalformedURLException {
    this.out = out;
    cL = new URLClassLoader(new URL[] { new URL(GAME_URL) });
}

public ClassLoader getClassLoaderContext() {
    return cL;
}

public static void writeObject(ClassLoaderPacket packet) throws IOException {
    out.writeObject(packet.getClassLoaderContext());
}

}

Client sided reading:

public void receiveData() throws Exception {
     gameLoader = (ClassLoader) in.readObject();
}

1 Answers1

0

I think there are too much of complex fields in the ClassLoader in order to serialize it. Additionally, it should implement Serializable interface and have serialVersionUID in the serializable class.

Would it be enough just to obfuscate the code? I think there are plenty of tools which may help you to conceal your code.

Here is the useful thread about java code obfuscation/protection: Best Java obfuscator?

Community
  • 1
  • 1
Dagaz
  • 353
  • 4
  • 15