Posts [Android] Reflection
Post
Cancel

[Android] Reflection

Reflection

  • 개념 : 구체적인 클래스의 타입을 알지 못해도, 컴파일 된 바이트 코드를 통해 역으로 클래스의 정보를 알아내어 클래스를 사용할 수 있는 기법. 거울에 비친 모습과 비슷해서 붙여진 이름
  • 리플렉션을 통해 얻을 수 있는 정보
    • ClassName
    • Class Modifiers (public, private, synchronized 등..)
    • Package Info
    • Superclass
    • Implemented Interface
    • Constructors
    • Methods (배열 형태로 모든 메소드를 불러올 수 있음, 메소드 명을 알면 특정 메소드를 불러올 수 있음)
    • Fileds (배열 형태로 모든 필드를 불러올 수 있음, 필드 명을 알면 특정 필드를 불러올 수 있음)
    • Annotations 등등 ..
  • 장점 : 접근이 불가한 private 영역에 접근하게 해주는 등 유연하게 사용할 수 있도록 함

  • 단점 : 성능 저하의 요인이 될 수 있음(정보를 찾을 때 드는 시간비용)
    (특히, for문에서 사용X)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
   /**
     * hook WebView
     *
     * because below
     * UnsupportedOperationException: For security reasons, WebView is not allowed in privileged processes
     *
     * @link https://stackoverflow.com/questions/29228183/java-lang-unsupportedoperationexception-for-security-reasons-webview-is-not-al
     */
    public void hookWebView() {
        int sdkInt = Build.VERSION.SDK_INT;
        try {
            Class<?> factoryClass = Class.forName("android.webkit.WebViewFactory");
            Field field = factoryClass.getDeclaredField("sProviderInstance");
            field.setAccessible(true);
            Object sProviderInstance = field.get(null);
            if (sProviderInstance != null) {
                LogUtil.debug(LOGD, "hookWebView() sProviderInstance isn't null");
                return;
            }
            Method getProviderClassMethod;
            if (sdkInt > 22) { // above 22
                getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
            } else if (sdkInt == 22) { // method name is a little different
                getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
            } else { // no security check below 22
                LogUtil.debug(LOGD, "hookWebView() Don't need to Hook WebView");
                return;
            }
            getProviderClassMethod.setAccessible(true);
            Class<?> providerClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
            Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
            Constructor<?> providerConstructor = providerClass.getDeclaredConstructor(delegateClass);
            if (providerConstructor != null) {
                providerConstructor.setAccessible(true);
                Constructor<?> declaredConstructor = delegateClass.getDeclaredConstructor();
                declaredConstructor.setAccessible(true);
                sProviderInstance = providerConstructor.newInstance(declaredConstructor.newInstance());
                LogUtil.debug(LOGD, "sProviderInstance:{" + sProviderInstance + "}");
                field.set("sProviderInstance", sProviderInstance);
            }
            LogUtil.debug(LOGD, "hookWebView() Hook done!");
        } catch (Throwable e) {
            e.printStackTrace();
            LogUtil.debug(LOGD, "hookWebView() " + e.getMessage());
        }
    }
참고 사이트
  • http://hiddenviewer.tistory.com/114
This post is licensed under CC BY 4.0 by the author.

[Android] 메모리 관리 - OOM(Out Of Memory)

[회고] 2019년을 돌아보며

Comments powered by Disqus.