Skip to content

Instantly share code, notes, and snippets.

@mtbarr
Created November 8, 2020 12:32
Show Gist options
  • Save mtbarr/1997e3c6670c2dff80301698a2c0848b to your computer and use it in GitHub Desktop.
Save mtbarr/1997e3c6670c2dff80301698a2c0848b to your computer and use it in GitHub Desktop.
package io.github.sasuked.ninjaspigot.network;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import net.minecraft.server.EnumProtocolDirection;
import net.minecraft.server.NetworkManager;
import net.minecraft.server.Packet;
import net.minecraft.server.PacketDataSerializer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import java.util.List;
public class NinjaSpigotPacketDecoder extends ByteToMessageDecoder {
private static final Logger logger = LogManager.getLogger();
private static final Marker marker = MarkerManager.getMarker("PACKET_RECEIVED", NetworkManager.b);
private final EnumProtocolDirection direction;
private int packetState = 0;
private int handshakeIntent = 0;
public NinjaSpigotPacketDecoder(final EnumProtocolDirection direction) {
this.direction = direction;
}
protected void decode(final ChannelHandlerContext channel, final ByteBuf buf, final List<Object> objects) throws Exception {
try {
if (buf.readableBytes() <= 0) {
channel.pipeline().remove(this);
throw new ExploitException("Null readable bytes received");
}
if (packetState >= 4) {
handshakeIntent = 0;
}
if (packetState == 0 || (packetState == 1 && handshakeIntent == 2)) {
try {
final PacketDataSerializer buffer = new PacketDataSerializer(buf.copy());
if (packetState == 0) {
handshakeIntent = PacketUtil.checkHandshake(buffer);
}
if (packetState == 1 && handshakeIntent == 2) {
PacketUtil.checkLogin(buffer);
}
} catch (final ExploitException e) {
channel.pipeline().remove(this);
throw new ExploitException("Decoder exception");
}
}
final PacketDataSerializer serializer = new PacketDataSerializer(buf);
if ((handshakeIntent == 2 && packetState < 3) && serializer.readableBytes() <= 0) {
channel.pipeline().remove(this);
throw new ExploitException("Empty packet");
}
if ((handshakeIntent == 1 && packetState == 1) && (serializer.readableBytes() >= 2)) {
channel.pipeline().remove(this);
throw new ExploitException("Empty Packet");
}
if ((handshakeIntent == 1 && packetState == 2 || packetState == 0) && serializer.readableBytes() <= 0) {
channel.pipeline().remove(this);
throw new ExploitException("Invalid packet data");
}
final int packetId = serializer.e();
if (packetState == 2 && packetId != 1 && handshakeIntent == 1) {
channel.pipeline().remove(this);
throw new ExploitException("Invalid packet");
}
final Packet<?> packet = channel.channel().attr(NetworkManager.c).get().a(this.direction, packetId);
if (packet == null) {
buf.skipBytes(buf.readableBytes());
serializer.skipBytes(serializer.readableBytes());
} else {
packet.a(serializer);
if (serializer.isReadable()) {
channel.pipeline().remove(this);
throw new ExploitException("Packet is too big");
}
objects.add(packet);
++packetState;
}
} catch (final IndexOutOfBoundsException e) {
channel.pipeline().remove(this);
throw new ExploitException("Invalid data");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment