ME1312 / VanillaCord

VanillaCord – IP Forwarding support for Vanilla Minecraft Servers
Mozilla Public License 2.0
75 stars 11 forks source link

[1.8] 1.18.2 Patching of ServerLoginPacketListenerImpl.handleHello() alters wrong instruction - java.lang.VerifyError: Bad type on operand stack #17

Closed TigerWalts closed 2 years ago

TigerWalts commented 2 years ago

When attempting to connect via a BungeeCord proxy, the following kick message is returned:

disconnected with: Kicked whilst connecting to lobby: Internal Exception: java.lang.VerifyError: Bad type on operand stack Exception Details: Location: aeq.a(Lxp;)V @33: invokestatic Reason: Type integer (current frame, stack[0]) is not assignable to 'java/lang/String' Current Frame: bci: @33 flags: { } locals: { 'aeq', 'xp' } stack: { integer }

There is more, but this was sufficient to track down the cause. In 1.18.2, an extra validation call is made to make sure no invalid characters are in the player's username.

1.18.1

    public void a(xd $$0) {
        Validate.validState((this.h == aec$a.a ? 1 : 0) != 0, (String)"Unexpected hello packet", (Object[])new Object[0]);
        this.j = $$0.b();
        if (this.g.U() && !this.a.d()) {
            this.h = aec$a.b;
            this.a.a((qr)new wy("", this.g.L().getPublic().getEncoded(), this.f));
        } else {
            this.h = aec$a.e;
        }
    }

1.18.2

    public void a(final xp $$0) {
        Validate.validState(this.h == aeq.a.a, "Unexpected hello packet", new Object[0]);
        this.j = $$0.b();
        Validate.validState(a(this.j.getName()), "Invalid characters in username", new Object[0]);
        if (this.g.U() && !this.a.d()) {
            this.h = aeq.a.b;
            this.a.a((rc)new xk("", this.g.L().getPublic().getEncoded(), this.f));
        }
        else {
            this.h = aeq.a.e;
        }
    }

I suspect that the patcher is finding the second Validate and making changes to it.

ME1312 commented 2 years ago

Yeah, generally, an exception of this type is caused by some kind of corruption – and as you suspected – the problem lies with the fact that they moved the if statement we're trying to alter down a line. The following is not valid code:

Validate.validState(a((String) false), "Invalid characters in username", new Object[0]);

Luckily, a simple type check can keep us from altering calls to the previously assigned instance variable j, so backwards compatibility should remain intact.

TigerWalts commented 2 years ago

Thanks. It's working with 1.18.2 now. I haven't tested any older versions.