#Java reflection argument mismatch

83 messages · Page 1 of 1 (latest)

heady hound
#

argument type mismatch

The prints from above the invocation:

public static kp eg.aj(kb,tk,byte)  // Method parameters (kb, tk, byte)
kb tk class java.lang.Byte          // Values I'm passing (kb, tk, byte)
Class<?> client_class;
client_class = client.getClass();

// getPacketNodeBuffer
Class<?> getPacketBufferNode;
getPacketBufferNode = Class.forName("eg", false, client.getClass().getClassLoader());
Method getPacketNode = Arrays.stream(getPacketBufferNode.getDeclaredMethods()).filter(m -> m.getName().equals("aj")).findFirst().orElse(null);

Class<?> clientPacket;
clientPacket = Class.forName("kb", false, client.getClass().getClassLoader());
Field MOVE_CLICK = Arrays.stream(clientPacket.getDeclaredFields()).filter(m -> m.getName().equals("br")).findFirst().orElse(null);

Field packet_writer = client_class.getField("ii");
Object packet_writer_isaac_cipher = packet_writer.getType().getDeclaredField("an").get(packet_writer.get(client));

// PacketBufferNode = kp
Class<?> PacketBufferNode;
PacketBufferNode = Class.forName("kp", true, client.getClass().getClassLoader()); // var39 (PacketBufferNode)
getPacketNode.setAccessible(true);
Byte byte_value = (byte) (-27);
System.out.println(getPacketNode);
System.out.println(MOVE_CLICK.getType().getName() + " " + packet_writer_isaac_cipher.getClass().getName() + " " + byte_value.getClass());
Object packetBufferNode = getPacketNode.invoke(getPacketBufferNode, MOVE_CLICK, packet_writer_isaac_cipher, byte_value);  // Argument error here
getPacketNode.setAccessible(false);
shell fieldBOT
#

This post has been reserved for your question.

Hey @heady hound! Please use /close or the Close Post button above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.

TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.

heady hound
#

The values i'm passing are the same type as the parameter shows but am still getting argument mismatch exception.

crystal laurel
#

it may help if you provide the full error output

heady hound
#
java.lang.IllegalArgumentException: argument type mismatch
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:108)
    at java.base/java.lang.reflect.Method.invoke(Method.java:577)
    at net.runelite.client.plugins.clanapi.clanAPIPugin.onGameTick(clanAPIPugin.java:100)
    at net.runelite.client.eventbus.EventBus$Subscriber.invoke(EventBus.java:70)
    at net.runelite.client.eventbus.EventBus.post(EventBus.java:223)
    at net.runelite.client.callback.Hooks.tick(Hooks.java:207)
    at client.ip(client.java:12917)
    at client.bp(client.java)
    at br.aa(br.java:367)
    at br.run(br.java:346)
    at java.base/java.lang.Thread.run(Thread.java:833)
#

and line 100 is the invoke line I sent above

crystal laurel
#

does the method you are trying to invoke have any overloads?

heady hound
#

there is another method with the same obfuscated name but it has different parameters entirely

crystal laurel
#

it could be that you are passing a Byte object where a byte primitive is expected

heady hound
#

I tried with just passing (byte) (-27) in place of byte_value and got the same error

#

I only changed it to that for that reason

#

Ill test again now to be sure

#

Yep same error

crystal laurel
#

try enclosing your invocation parameters inside a new Object[] { } when you call invoke

heady hound
#

Same error with that

#

I also tried casting object to all args

#

but they were all redundant anyway

crystal laurel
heady hound
#

It belongs to the PacketBufferNode class

#

which is "kp"

#

oh so packet_writer_isaac_cipher is an instance class

crystal laurel
#

Class.forName returns a Class<?> which is not an instance of that class
that means the type of getPacketBufferNode is Class<PacketBufferNode> and not PacketBufferNode which is expected

heady hound
#

That makes a lot of sense

#

So I need to make a new instance of the class

crystal laurel
#

yes

heady hound
#

Is that possible through reflection? I've never done that

crystal laurel
#

yes
that should be your first parameter to the invoke call

heady hound
#

Ok that also make a lot more sense, I never understood what object was supposed to go there

crystal laurel
#

documentation is your friend

heady hound
#

I had been using null for past programs since I guess it didn't need instanced classes for that particular method

crystal laurel
#

were those methods static

heady hound
#

One sec let me see

#

Yes

crystal laurel
#

that is why null works

#

when the method is not static you need an instance object

heady hound
#

I'm coming from python so all these things are new to me lol

#

static just means it doesn't use "this" right?

#

Which means it doesn't need any of the members of the class to run the method

crystal laurel
#

static means it belongs to the class and must be invoked through the class:

MyClass.staticMethod()

non static means it belongs to instances of the class and must be invoked through them:

MyClass instance = new MyClass();
instance.instanceMethod();
heady hound
#

You are so helpful, thank you so much.

shell fieldBOT
# heady hound You are so helpful, thank you so much.

If you are finished with your post, please close it.
If you are not, please ignore this message.
Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.

heady hound
#

I'm gonna see if I can make an instance of the class real quick

crystal laurel
heady hound
#

Ok wait, the getPacketNode method is static as well

crystal laurel
#

is the class containing the method nested in another class?

heady hound
#

No

#

The 2nd parameter certainly needs to have an instanced value though, would that cause it?

#

As in, packetWriter is an instance of PacketWriter in the Client class which has the field isaacCipher

#

In other words if were accessible it would be written as:

Client.java

PacketWriter packetWriter;
PacketWriter.java

public IsaacCipher isaacCipher

client.packetWriter.isaacCipher

#

and I tried getting that instanced value like this:

Field packet_writer = client_class.getField("ii");
Object packet_writer_isaac_cipher = packet_writer.getType().getDeclaredField("an").get(packet_writer.get(client));
#

ii = packetWriter
an = PacketWriter.isaacCipher

crystal laurel
#

how do you know all of the unobfuscated type names if you are only accessing them by their obfuscated names in the code you have provided?

heady hound
#

There is mapped code out there

crystal laurel
#

is the class from a library you are trying to use?

#

I'm only asking since you said you are coming from python and it may be possible that reflection is not required depending on what you are actually trying to do with this code

heady hound
#

It's for an obfuscated game

#

Where client is accessible with all the class instances mentioned being inaccessible without reflection

crystal laurel
#

fair enough
anyway, it looks like the method requires instances for all of its parameters so if you are retrieving other classes than the one containing the method, you may need to instantiate those also in order to pass them to the invocation

heady hound
#

Well for the 2nd parameter I need to grab the instance of the class that already exists since it's isaacCipher value (and other values) are already changed

heady hound
#

Or is that not possible?

crystal laurel
#

I understand what you are trying to do
let me come up with a sample to check against

heady hound
#

and just to reiterate, client contains an instance of Client which has a field packetWriter which is an instance of PacketWriter which contains the field isaacCipher.

From client I am trying to get the instance of packetWriter and it's field isaacCipher to be passed into this method as the 2nd param

crystal laurel
#

am I understanding correctly?

public class Client
{
    public PacketWriter packetWriter;
}

public class PacketWriter
{
    public IsaacCipher isaacCipher;
}
heady hound
#

yep exactly

crystal laurel
#

and which of these has the method you are invoking (or is that another class)?

heady hound
#

Yea it's another class

#

Which is static so it can just be invoked normally

crystal laurel
#

the class is static or the method is static (or both)?

heady hound
#

The method

#

Here is even an example of the same method being executed

PacketBufferNode var39 = UserComparator9.getPacketBufferNode(ClientPacket.MOVE_GAMECLICK, packetWriter.isaacCipher);
#

So looks like just param2 needs to have the instance of packetWriter

#

Well it really just needs the instanced value of isaacCipher

#

from packetWriter

#
getstatic       kb.br:Lkb;
getstatic       client2.clientPacketWriter:LPacketWriter;
getfield        PacketWriter.isaacCipher:LIsaacCipher;
bipush          -11
invokestatic    UserComparator9.getPacketBuffer:(Lkb;LIsaacCipher;B)LPacketBufferNode;
#

Here is even the byte code which I've mapped out a little bit

#

kb = ClientPacket

crystal laurel
#

are you able to provide the mapped names for all of the obfuscated names in your initial code segment?

heady hound
#

eg = UserComparator9
aj = UserComparator9.getBufferNode
ii = client.packetWriter
an = PacketWriter.isaacCipher
kp = PacketBufferNode
kb = ClientPacket
br = ClientPacket.MOVE_CLICK

#

kp node = eg.aj.invoke(null, kb.br, client.ii.an, (byte) -11);

crystal laurel
#

are you able to provide a link to the source of the code you are trying to use reflectively? it would help if I could take a closer look at that

heady hound
#

Dmed