Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"this" is not "super" #103

Open
TomSie opened this issue Nov 28, 2016 · 4 comments
Open

"this" is not "super" #103

TomSie opened this issue Nov 28, 2016 · 4 comments

Comments

@TomSie
Copy link

TomSie commented Nov 28, 2016

Hey,

I experience problems when decompiling JAVA classes that use "super". Minimal Example:

public class B extends A {
public void test(int i){
System.out.println("B");
super.test(i);
}
}

Using Krakatau it gets decompiled to

public class BDecomp extends A {
public void test(int i)
{
System.out.println("BDecomp");
((A)this).test(i);
}

}
For reference the A class:

public class A {

int i;

public void test(int i) {
	System.out.println("A");
	this.i = i;
}

}

If I run the follwing code
B b = new B();
b.test(0);

	BDecomp d = new BDecomp();
	d.test(0);

I get:

B
A
BDecomp
BDecomp
BDecomp
BDecomp
...
(crash)

In short: Methods that use "super" get falsely decompiled to "this". Recompiling leads to buggy behavior.

Best regards,

Tom

@Storyyeller
Copy link
Owner

Unfortunately, this is a difficult issue, and I am not aware of a good solution. I'm open to suggestions though.

At any rate, you shouldn't expect to be able to recompile code. This is true for any decompiler, not just Krakatau. Decompilation is for reverse engineering - if you want to modify code, you need to use the disassembler and assembler.

@TomSie
Copy link
Author

TomSie commented Nov 29, 2016

Hey,

thank you for your quick response ;) In my experience it works quite well to manually replace every occurrence of "((PARENT)this)" with "super" in Krakatau's output.

I don't know much about the internals of Krakatau, but would it be a bad idea to do this by default? After all "((PARENT)this)" looks like the code wants to call the parent's function but - according to my tests - in fact does call its own function.

Best Regards,
Tom

@Storyyeller
Copy link
Owner

I could do it, but I prefer to avoid hacks like that. Besides, there is a risk it could change places where (Foo)this is actually intentional.

@TomSie
Copy link
Author

TomSie commented Nov 30, 2016

Hey,

I modified my B class to look like this:
`public class B extends A {

public void test(int i) {
	System.out.println("B");
	this.i = i;
}

public void testSuper(int i){
	System.out.println("B - testSuper");
	super.test(i);
	
}

public void testSuperThis(int i){
	System.out.println("B - testSuperThis");
	((A)this).test(i);
	
}

public void testThis(int i){
	System.out.println("B - testThis");
	this.test(i);
	
}

}`

Additionally, I wrote the following test script:
B b = new B(); System.out.println("1"); b.testSuper(0); System.out.println("2"); b.testThis(0); System.out.println("3"); b.testSuperThis(0);

Output:
1 B - testSuper A 2 B - testThis B 3 B - testSuperThis B

As you can see, ((A)this). is functionally equivalent to this.. So if you actually want to call a parent's function, you need to use super. Just putting a cast in front of it doesn't work - at least not according to my tests.

So correct me if I'm wrong, but I cannot imagine a legitimate use of (Foo)this, as it seems to be functionally equivalent to this.

However, I can very well understand your point of not doing said hack as I tried to decompile my B.class with Krakatau. Result:

`public class B extends A {
public B()
{
super();
}

public void test(int i)
{
    System.out.println("B");
    this.i = i;
}

public void testSuper(int i)
{
    System.out.println("B - testSuper");
    ((A)this).test(i);
}

public void testSuperThis(int i)
{
    System.out.println("B - testSuperThis");
    ((A)this).test(i);
}

public void testThis(int i)
{
    System.out.println("B - testThis");
    this.test(i);
}

}
`

So after decompilation with Krakatau testSuper became equivalent to testSuperThis, while in the actual code, testSuperThis is equivalent to testThis.

Any Idea how this could be handled?

Best Regards,
Tom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants