Browse Source

在android原生代码里hook掉Flutter读取剪切板的方法,尝试解决隐私问题

gjh 1 week ago
parent
commit
0869c4eeea

+ 79 - 0
android/app/src/main/java/com/eitchsyh/instrument/eitc_erm_dental_flutter/HookFlutterClipBordUtil.java

@@ -0,0 +1,79 @@
1
+package com.eitchsyh.instrument.eitc_erm_dental_flutter;
2
+
3
+import java.lang.reflect.Field;
4
+import java.lang.reflect.InvocationHandler;
5
+import java.lang.reflect.Method;
6
+import java.lang.reflect.Proxy;
7
+
8
+import io.flutter.Log;
9
+import io.flutter.embedding.engine.FlutterEngine;
10
+import io.flutter.embedding.engine.systemchannels.PlatformChannel;
11
+
12
+/**
13
+ * File description.
14
+ * hook flutter输入框 自动调用getClipboardData 引起的合规问题
15
+ *
16
+ * @author lihongjun
17
+ * @date 10/13/21
18
+ */
19
+public class HookFlutterClipBordUtil
20
+{
21
+    /**
22
+     * 代理剪切板功能
23
+     *
24
+     * @param flutterEngine
25
+     */
26
+    public static void hookClipBoard(FlutterEngine flutterEngine)
27
+    {
28
+        Class IPlatformMessageHandler;
29
+        Field platformMessageHandlerField;
30
+        try
31
+        {
32
+            IPlatformMessageHandler = Class.forName(
33
+                    PlatformChannel.PlatformMessageHandler.class.getName());
34
+            platformMessageHandlerField = PlatformChannel.class.getDeclaredField(
35
+                    "platformMessageHandler");
36
+            platformMessageHandlerField.setAccessible(true);
37
+
38
+            // 拿到真实正常的实例,给不需要被hook的方法使用
39
+            PlatformChannel channel = flutterEngine.getPlatformChannel();
40
+            Object real = platformMessageHandlerField.get(channel);
41
+            // 代理PlatformMessageHandler的方法
42
+            platformMessageHandlerField.set(channel, Proxy.newProxyInstance(
43
+                    IPlatformMessageHandler.getClassLoader(), new Class[]{IPlatformMessageHandler},
44
+                    new IClipboardInvocationHandler(real)));
45
+
46
+        }
47
+        catch (Exception e)
48
+        {
49
+            Log.e("HookFlutterClipBordUtil", "hook异常", e);
50
+        }
51
+    }
52
+
53
+    public static class IClipboardInvocationHandler implements InvocationHandler
54
+    {
55
+        // 真是的调用方,如果不是获取剪切板 正常调用功能
56
+        private Object real;
57
+
58
+        public IClipboardInvocationHandler(Object real)
59
+        {
60
+            this.real = real;
61
+        }
62
+
63
+        @Override
64
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
65
+        {
66
+            //Log.d("test=====",method.getName());
67
+            // flutter输入框会调用获取剪切板 合规问题屏蔽掉
68
+            if ("clipboardHasStrings".equals(method.getName()))
69
+            {
70
+                return false;
71
+            }
72
+            else if ("getClipboardData".equals(method.getName()))
73
+            {
74
+                return "";
75
+            }
76
+            return method.invoke(real, args);
77
+        }
78
+    }
79
+}

+ 1 - 0
android/app/src/main/java/com/eitchsyh/instrument/eitc_erm_dental_flutter/MainActivity.java

@@ -23,6 +23,7 @@ public class MainActivity extends FlutterActivity implements
23 23
         super.configureFlutterEngine(flutterEngine);
24 24
         this.videoController = new VideoController(this.getApplicationContext(), flutterEngine);
25 25
         this.fileController = new FileController(this.getApplicationContext(), flutterEngine, this);
26
+        HookFlutterClipBordUtil.hookClipBoard(flutterEngine);
26 27
     }
27 28
 
28 29
     @Override