2013-10-18 15 views
3

내가 같이 동적으로 클래스를 가져 오는 해요 :리플렉션을 사용하여 다른 동적 클래스를 확장하는 클래스를 동적으로 생성하려면 어떻게해야합니까?

Class<?> clazz = Class.forName("com.android.systemui.quicksettings.QuickSettingsTile"); 

내가 DummyTile 그게 전부라는 또 다른 클래스를 생성하고 싶은 것은 내 이전 클래스를 확장합니다. 이 모양은 다음과 같습니다.

public class DummyTile extends QuickSettingsTile { 

    public DummyTile(Context context, QuickSettingsController qsc) { 
     super(context, qsc); 
    } 

    public void updateTile() { 
     System.out.println("Hello"); 
    } 

    @Override 
    public void updateResources() { 
     updateTile(); 
     super.updateResources(); 
    } 

} 

...하지만 리플렉션을 사용하여이를 수행하는 방법을 잘 모르겠습니다. This is the class that I'm trying to extend. 또한 메서드를 재정의하고 생성자를 사용하여 개체를 초기화하는 방법에 대해서도 확신하지 못합니다. 리플렉션을 사용하여 매우 간단한 작업을했지만 다른 클래스를 동적으로 확장하는 방법을 다루지 않았습니다.

사람이 일부 발췌 문장으로 올바른 방향으로 나를 가리킬 수 있다면, 나는 거기에서 그것을 처리 할 수있을 것이라고 확신합니다.

+2

왜이 작업을 수행 하시겠습니까? –

+0

Xposed를 사용하여 Android ROM의 일부 기능을 수정할 수 있도록 : http://repo.xposed.info/ –

답변

1

리플렉션을 통해이를 수행 할 수 없습니다. java.lang.reflect.Proxy을 사용하여 interface 구현을 동적으로 만들 수는 있지만 그게 전부입니다.

더 많은 정보를 원하면 타사 라이브러리를 사용해야합니다. 그러나 이러한 라이브러리는 일반적으로 낮은 수준에서 작동합니다. 바이트 코드와 약간의 경험이 필요합니다. 제한된 환경에서는 사용할 수 없습니다.

0

리플렉션을 사용하여 실제로 클래스를 확장 할 수는 없지만 캡슐화 할 수는 있습니다.
이것은 물론 주요 보안 위험이며이를 허용할지 여부에 대해 열심히 생각해야합니다.

은 참조 :이 같은 http://initbinder.com/articles/hack_any_java_class_using_reflection_attack.html

뭔가 트릭을 할해야합니다.

import java.lang.reflect.Constructor; 
import java.lang.reflect.Method; 
import java.lang.reflect.Field; 
import java.lang.reflect.Modifier; 
import java.lang.ClassNotFoundException; 
import java.lang.InstantiationException; 
import java.lang.IllegalAccessException; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.NoSuchMethodException; 

public class Tester { 

    private static String CLASS_NAME = "VictimClass"; 
    private static Class victimClass = null; 
    private static Object victimClassObj = null; 

    public static void main(String[] args) { 
    victimClass = loadClass(victimClass, CLASS_NAME); 
    printClassStructure(); 
    attack(); 
    } 

    private static Class loadClass(Class clazz, String className) { 
    Thread thread = Thread.currentThread(); 
    ClassLoader classLoader = 
    thread.getContextClassLoader(); 

    try { 
     clazz = Class.forName(className, true, classLoader); 
    } 
    catch (ClassNotFoundException e) { 
     System.err.println("Error: could not find class: " 
     + CLASS_NAME); 
    } 

    return clazz; 
    } 

    private static void printClassStructure() { 

    Constructor[] constructors = 
    victimClass.getDeclaredConstructors(); 
    for (Constructor c : constructors) { 
     int modifier = c.getModifiers(); 
     System.out.println("Declared constructor name: " 
      + c.getName() + "ntis accessible: " 
      + c.isAccessible() + "ntis private: " 
      + Modifier.isPrivate(modifier) + "n"); 
    } 

    Method[] methods = victimClass.getDeclaredMethods(); 
    for (Method m : methods) { 
     int modifier = m.getModifiers(); 
     System.out.println("Declared method name: " + m.getName() 
      + "ntis accessible: " 
      + m.isAccessible() 
      + "ntis private: " 
      + Modifier.isPrivate(modifier) 
      + "ntis static: " 
      + Modifier.isStatic(modifier) + "n"); 
    } 

    Field[] fields = victimClass.getDeclaredFields(); 
    for (Field f : fields) { 
     int modifier = f.getModifiers(); 
     System.out.println("Declared field name: " + f.getName() 
      + "ntis accessible: " 
      + f.isAccessible() 
      + "ntis private: " 
      + Modifier.isPrivate(modifier) 
      + "ntis static: " 
      + Modifier.isStatic(modifier) 
      + "ntis final: " 
      + Modifier.isFinal(modifier) + "n"); 
    } 
    } 

    private static void attack() { 

    Field[] fields = victimClass.getDeclaredFields(); 
    Method[] methods = victimClass.getDeclaredMethods(); 
    Constructor[] constructors = victimClass.getDeclaredConstructors(); 

    //make constructor accessible 
    constructors[0].setAccessible(true); 

    System.err.println("Initiating reflection attack:"); 
    try { 
     //create new object by invoking private constructor 
     victimClassObj = constructors[0].newInstance(new Object[] {}); 

     //make static method accessible and get its value 
     //please note: when invoking static method, 
     //object represented by this Method is null 
     methods[2].setAccessible(true); 
     Object o = methods[2].invoke(null, new Object[] {}); 
     System.out.println("Got user ID from private static accessor: " 
      + o.toString()); 

     //make method accessible and get its value 
     methods[0].setAccessible(true); 
     o = methods[0].invoke(victimClassObj, new Object[] {}); 
     System.out.println("Got original password from private accessor: " 
      + o.toString()); 

     //make method accessible and set to it new value 
     methods[1].setAccessible(true); 
     System.out.println("Injecting new password using private mutator"); 
     methods[1].invoke(victimClassObj, new Object[] {"injected_password"}); 

     //get method’s its new value 
     o = methods[0].invoke(victimClassObj, new Object[] {}); 
     System.out.println("Got injected password from private accessor: " 
      + o.toString()); 

     //make field accessible and get its value 
     fields[2].setAccessible(true); 
     o = fields[2].get(victimClassObj); 
     System.out.println("Got private field: " + o); 

     //make field accessible and set to it new value 
     System.out.println("Injecting value to a private field:"); 
     fields[2].set(victimClassObj, "new_default_value"); 

     //get field’s its new value 
     o = fields[2].get(victimClassObj); 
     System.out.println("Got updated private field: " + o); 

     //make field accessible and get its value 
     fields[1].setAccessible(true); 
     o = fields[1].get(victimClassObj); 
     System.out.println("Got private static field: " + o); 

     //make field accessible and set to it new value 
     System.out.println("Injecting value to a private static final field:"); 
     fields[1].set(null, new Integer(2)); 

     //get field’s its new value 
     o = fields[1].get(victimClassObj); 
     System.out.println("Got updated private static final field: " + o); 

    } 
    catch (InstantiationException e) { 
     System.err.println("Error: could not instantiate: " + e); 
    } 

    catch (IllegalAccessException e) { 
     System.err.println("Error: could not access: " + e); 
    } 

    catch (InvocationTargetException e) { 
     System.err.println("Error: could not invoke the target: " + e); 
    } 
    } 
} 
0

Duckapter은 오리 입력을 Java에 추가 할 수 있습니다.

DummyTile tile = ...; 
QuickSettingsTile settingsTile = Duck.type(tile, QuickSettingsTile.class); 
관련 문제