Is there any level of obfuscation that can โ€œtrickโ€ an instance?

I played with this, and so far I have not been able to find a way to hide or trick instanceof into returning false by hiding its type through obfuscation layers, but this does not mean this is impossible, since I am far from the most knowledgeable person about Java. So I came to ask the experts.

I tried the following combinations, and in each case the instanceof operator can identify the true / base type of the object.

 public class Test { public static void main(String[] args) { Object o = new TestObject(); printType("Base Class", o); o = (TestSuperObject)(new TestObject()); printType("Super Class", o); o = (TestInterface)(new TestObject()); printType("Interface", o); o = (TestInterface)((TestSuperObject3)(new TestObject3())); printType("Interface on Super Class", o); o = (TestSuperObject3)((TestInterface)(new TestObject3())); printType("Super Class on Interface", o); } private static void printType(String testCase, Object o) { System.out.println(testCase); System.out.println("TestObject:" + (o instanceof TestObject)); System.out.println("TestObject2:" + (o instanceof TestObject2)); System.out.println("TestObject3:" + (o instanceof TestObject3)); System.out.println(); } } 

Classes are defined as ...

 public class TestObject extends TestSuperObject implements TestInterface public class TestObject2 extends TestSuperObject implements TestInterface public interface TestInterface public class TestSuperObject public class TestObject3 extends TestSuperObject3 public class TestSuperObject3 implements TestInterface 

So, basically, is there a way to hide this information or somehow lose type information? I do not ask, because I have a reason to do this, but I would like to know and be careful in the future, if possible. Besides, I'm just curious.

+4
source share
4 answers

You can confuse yourself instanceof , but not the JVM.

  • classes with the same name but in different packages do not match. That means you can do

     // in one class ClassA classA = new ClassA(); // package1.ClassA another.test(classA); // calls in another class public void test(Object o) { if (o instanceof ClassA) // package2.ClassA => false 
  • using different classloaders, packages and o.getClass().getName() same, but since classloaders are different instanceof return false.

  • The null object and null instanceof ClassB always false, although null can be assigned to any reference type.
+4
source

So, basically, is there a way to hide this information or somehow lose type information?

No, It is Immpossible.

Each object has a real type, and the strong + static Java type system makes it impossible to change the type of the object or makes it appear that its actual type is different from what it is.


(Hypothetically, you can abandon your own code and undermine a system like Java, but the consequences can be very bad ... crash-the-JVM bad.)

+2
source

You can run the code through an obfuscator. But this is basically a rename. TestObject can be renamed, for example, A , but instanceof A still returns the correct result.

BTW: naming your classes * Object is a bad idea (in object oriented languages).

0
source

It depends on what the OP really wants, but this can do it.

I basically make the class private. This means that any object instanceof Class code will not compile (outside the scope of a private class).

0
source

Source: https://habr.com/ru/post/1440058/


All Articles