FlixOlé v4.4.0版本的 MD5 值为:50e7f767ca3e8715936523e9ef089581

以下内容为反编译后的 HostsBlocker.java 源代码,内容仅作参考


package com.applisto.appcloner.classes;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import com.applisto.appcloner.classes.HostsBlocker;
import com.applisto.appcloner.classes.util.Log;
import com.applisto.appcloner.hooking.Hooking;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookReflectClass;
import com.swift.sandhook.annotation.MethodParams;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HostsBlocker {
    private static final String PREF_KEY_PREFIX = "com.applisto.appcloner.host_";
    private static boolean sAllowAllOtherHosts;
    private static String sAllowLabel;
    private static boolean sBlockByDefault;
    private static String sBlockLabel;
    private static String sContentText;
    private static String sContentTitle;
    private static Context sContext;
    private static String sHostBlockedMessage;
    private static String sHostsBlockerTitle;
    private static String sIgnoreLabel;
    private static NotificationManager sNotificationManager;
    private static SharedPreferences sPreferences;
    private static String sSocksProxyHost;
    private static final String TAG = HostsBlocker.class.getSimpleName();
    private static Map<String, Boolean> sHostsFileHosts = new HashMap();
    private static final Map<String, Boolean> sHosts = Collections.synchronizedMap(new HashMap());
    private static final Map<Integer, String> sNotifications = Collections.synchronizedMap(new HashMap());
    private static Handler sHandler = new Handler(Looper.getMainLooper());

    public static void install(Context context, boolean z, String str, boolean z2, Properties properties) {
        sContext = context;
        sBlockByDefault = z;
        sSocksProxyHost = str;
        sAllowAllOtherHosts = z2;
        sNotificationManager = (NotificationManager) context.getSystemService("notification");
        sPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        synchronized (sHosts) {
            try {
                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(context.getAssets().open(".blockedHostsFile")));
                    try {
                        Pattern compile = Pattern.compile("(0.0.0.0|127.0.0.1|# x.x.x.x)\\s+(\\S*)");
                        while (true) {
                            String readLine = bufferedReader.readLine();
                            if (readLine == null) {
                                break;
                            }
                            String trim = readLine.trim();
                            if (trim.startsWith("# x.x.x.x") || !trim.startsWith("#")) {
                                Matcher matcher = compile.matcher(trim);
                                if (matcher.find()) {
                                    String group = matcher.group(2);
                                    boolean equals = "# x.x.x.x".equals(matcher.group(1));
                                    String str2 = TAG;
                                    Log.i(str2, "install; host: " + group + ", allowedBlocked: " + equals);
                                    sHostsFileHosts.put(group, Boolean.valueOf(equals));
                                }
                            }
                        }
                        bufferedReader.close();
                    } finally {
                    }
                } catch (Exception e) {
                    Log.w(TAG, e);
                }
            } catch (FileNotFoundException | Exception unused) {
            }
            for (String str3 : sPreferences.getAll().keySet()) {
                if (str3 != null && str3.startsWith(PREF_KEY_PREFIX)) {
                    sHosts.put(str3.substring(28), Boolean.valueOf(sPreferences.getBoolean(str3, false)));
                }
            }
            String str4 = TAG;
            Log.i(str4, "install; sHosts: " + sHosts);
        }
        Hooking.initHooking(context);
        Hooking.addHookClass(Hook.class);
        Log.i(TAG, "install; hooks installed");
        sHostsBlockerTitle = properties.getProperty("hosts_blocker_title");
        sContentTitle = properties.getProperty("hosts_blocker_app_is_accessing_title");
        sContentText = properties.getProperty("hosts_blocker_touch_to_block_title");
        sAllowLabel = properties.getProperty("label_allow");
        sBlockLabel = properties.getProperty("label_block");
        sIgnoreLabel = properties.getProperty("label_ignore");
        sHostBlockedMessage = properties.getProperty("hosts_blocker_host_blocked_message");
    }

    @HookReflectClass("java.net.PlainSocketImpl")
    public static class Hook {
        @HookMethodBackup("socketConnect")
        @MethodParams({InetAddress.class, int.class, int.class})
        static Method socketConnectBackup;

        @MethodParams({InetAddress.class, int.class, int.class})
        @HookMethod("socketConnect")
        public static void socketConnectHook(Object obj, InetAddress inetAddress, int i2, int i3) throws Throwable {
            String str = HostsBlocker.TAG;
            Log.i(str, "socketConnectHook; address: " + inetAddress + ", port: " + i2 + ", timeout: " + i3);
            HostsBlocker.checkHost(inetAddress);
            Hooking.callInstanceOrigin(socketConnectBackup, obj, inetAddress, Integer.valueOf(i2), Integer.valueOf(i3));
        }
    }

    public static void checkHost(InetAddress inetAddress) throws UnknownHostException {
        if (inetAddress == null) {
            return;
        }
        checkHost(inetAddress.getHostName());
    }

    private static void checkHost(final String str) throws UnknownHostException {
        if (str == null || str.length() <= 0) {
            return;
        }
        String str2 = sSocksProxyHost;
        if ((str2 != null && str2.equals(str)) || "127.0.0.1".equals(str) || "localhost".equals(str) || str.startsWith("192.168.")) {
            return;
        }
        for (String str3 : splitHost(str)) {
            if (sHosts.containsKey(str3)) {
                Boolean bool = sHosts.get(str3);
                if (bool == null || bool.booleanValue()) {
                    String str4 = TAG;
                    Log.i(str4, "checkHost; ignored/allowed; host: " + str);
                    return;
                }
                String str5 = TAG;
                Log.i(str5, "checkHost; blocked; host: " + str);
                throw new UnknownHostException("Blocked");
            } else if (sHostsFileHosts.containsKey(str3)) {
                if (sHostsFileHosts.get(str3).booleanValue()) {
                    addAllowedHost(str);
                    return;
                }
                addBlockedHost(str);
                sHandler.post(new Runnable() {
                    @Override
                    public final void run() {
                        Toast.makeText(HostsBlocker.sContext, HostsBlocker.sHostBlockedMessage.replace("%s", str), 0).show();
                    }
                });
                String str6 = TAG;
                Log.i(str6, "checkHost; blocked; host: " + str);
                throw new UnknownHostException("Blocked");
            }
        }
        if (sAllowAllOtherHosts) {
            return;
        }
        showNotification(str);
        if (sBlockByDefault) {
            throw new UnknownHostException("Blocked by default");
        }
    }

    public static List<String> splitHost(String str) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(str);
        int length = str.length();
        boolean z = false;
        int i2 = 0;
        while (true) {
            if (i2 < length) {
                char charAt = str.charAt(i2);
                if (charAt != '.' && !Character.isDigit(charAt)) {
                    z = true;
                    break;
                }
                i2++;
            } else {
                break;
            }
        }
        if (z) {
            while (true) {
                int indexOf = str.indexOf(46);
                if (indexOf == -1) {
                    break;
                }
                str = str.substring(indexOf + 1);
                if (str.indexOf(46) == -1) {
                    break;
                }
                arrayList.add("*." + str);
            }
        }
        return arrayList;
    }

    private static void showNotification(String str) {
        int hashCode = str.hashCode();
        synchronized (sNotifications) {
            if (sNotifications.containsKey(Integer.valueOf(hashCode))) {
                return;
            }
            sNotifications.put(Integer.valueOf(hashCode), str);
            Log.i(TAG, "showNotification; host: " + str);
            int hashCode2 = str.hashCode();
            Context context = sContext;
            PendingIntent broadcast = PendingIntent.getBroadcast(context, hashCode2, new Intent(str, null, context, ContentReceiver.class), 134217728);
            Context context2 = sContext;
            PendingIntent broadcast2 = PendingIntent.getBroadcast(context2, hashCode2 + 1, new Intent(str, null, context2, AllowReceiver.class), 1073741824);
            Context context3 = sContext;
            PendingIntent broadcast3 = PendingIntent.getBroadcast(context3, hashCode2 + 2, new Intent(str, null, context3, BlockReceiver.class), 1073741824);
            Context context4 = sContext;
            PendingIntent broadcast4 = PendingIntent.getBroadcast(context4, hashCode2 + 3, new Intent(str, null, context4, IgnoreReceiver.class), 1073741824);
            Notification.Builder autoCancel = new Notification.Builder(sContext).setSmallIcon(17301543).setContentTitle(sContentTitle.replace("%s", Utils.getAppName(sContext))).setContentIntent(broadcast).setDeleteIntent(PendingIntent.getBroadcast(sContext, hashCode2 + 4, new Intent(Integer.toString(hashCode), null, sContext, CancelReceiver.class), 1073741824)).setAutoCancel(false);
            if (Build.VERSION.SDK_INT >= 16) {
                autoCancel.setContentText(str).addAction(hashCode2, sAllowLabel, broadcast2).addAction(hashCode2, sBlockLabel, broadcast3).addAction(hashCode2, sIgnoreLabel, broadcast4);
            } else {
                autoCancel.setContentText(sContentText.replace("%s", str)).setContentIntent(broadcast3);
            }
            if (Build.VERSION.SDK_INT >= 21) {
                autoCancel.setVisibility(-1);
            }
            Utils.setSmallNotificationIcon(autoCancel);
            Notification notification = autoCancel.getNotification();
            notification.sound = null;
            notification.defaults &= -2;
            sNotificationManager.notify(hashCode, notification);
        }
    }

    public static void addAllowedHost(String str) {
        String str2 = TAG;
        Log.i(str2, "addAllowedHost; host: " + str);
        synchronized (sPreferences) {
            sHosts.put(str, true);
            SharedPreferences.Editor edit = sPreferences.edit();
            edit.putBoolean(PREF_KEY_PREFIX + str, true).apply();
        }
    }

    public static void addBlockedHost(String str) {
        String str2 = TAG;
        Log.i(str2, "addBlockedHost; host: " + str);
        synchronized (sPreferences) {
            sHosts.put(str, false);
            SharedPreferences.Editor edit = sPreferences.edit();
            edit.putBoolean(PREF_KEY_PREFIX + str, false).apply();
        }
    }

    public static void addIgnoredHost(String str) {
        String str2 = TAG;
        Log.i(str2, "addIgnoredHost; host: " + str);
        synchronized (sPreferences) {
            sHosts.put(str, null);
            SharedPreferences.Editor edit = sPreferences.edit();
            edit.remove(PREF_KEY_PREFIX + str).apply();
        }
    }

    public static void whois(Context context, String str) {
        Log.i(TAG, "whois; host: " + str);
        if (str.startsWith("*.")) {
            str = str.substring(2);
        }
        try {
            Intent intent = new Intent("android.intent.action.VIEW");
            intent.setFlags(268435456);
            intent.setData(Uri.parse("http://whois.domaintools.com/" + str));
            context.startActivity(intent);
        } catch (Exception e) {
            Log.w(TAG, e);
            Toast.makeText(context, "Failed to open browser.", 1).show();
        }
    }

    public static Map<String, Boolean> getAllowedBlockedHosts() {
        if (sPreferences == null) {
            return null;
        }
        HashMap hashMap = new HashMap();
        synchronized (sPreferences) {
            for (String str : sPreferences.getAll().keySet()) {
                if (str != null && str.startsWith(PREF_KEY_PREFIX)) {
                    hashMap.put(str.substring(28), Boolean.valueOf(sPreferences.getBoolean(str, false)));
                }
            }
        }
        return hashMap;
    }

    public static void setAllowedBlockedHosts(Map<String, Boolean> map) {
        for (String str : map.keySet()) {
            Boolean bool = map.get(str);
            if (bool == null) {
                addIgnoredHost(str);
            } else if (bool.booleanValue()) {
                addAllowedHost(str);
            } else {
                addBlockedHost(str);
            }
        }
    }

    public static abstract class HostReceiver extends BroadcastReceiver {
        protected abstract void handleHost(Context context, String str);

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                String action = intent.getAction();
                if (TextUtils.isEmpty(action)) {
                    return;
                }
                handleHost(context, action);
            } catch (Exception e) {
                Log.w(HostsBlocker.TAG, e);
            }
        }
    }

    public static class ContentReceiver extends HostReceiver {
        @Override
        protected void handleHost(Context context, String str) {
            String str2 = HostsBlocker.TAG;
            Log.i(str2, "ContentReceiver; handleHost; host: " + str);
            Intent intent = new Intent(context, HostsBlockerActivity.class);
            intent.setFlags(268435456);
            intent.putExtra("host", str);
            context.startActivity(intent);
        }
    }

    public static class AllowReceiver extends HostReceiver {
        @Override
        protected void handleHost(Context context, String str) {
            String str2 = HostsBlocker.TAG;
            Log.i(str2, "AllowReceiver; handleHost; host: " + str);
            HostsBlocker.addAllowedHost(str);
            HostsBlocker.hideNotification(str);
        }
    }

    public static class BlockReceiver extends HostReceiver {
        @Override
        protected void handleHost(Context context, String str) {
            String str2 = HostsBlocker.TAG;
            Log.i(str2, "BlockReceiver; handleHost; host: " + str);
            HostsBlocker.addBlockedHost(str);
            HostsBlocker.hideNotification(str);
        }
    }

    public static class IgnoreReceiver extends HostReceiver {
        @Override
        protected void handleHost(Context context, String str) {
            String str2 = HostsBlocker.TAG;
            Log.i(str2, "IgnoreReceiver; handleHost; host: " + str);
            HostsBlocker.addIgnoredHost(str);
            HostsBlocker.hideNotification(str);
        }
    }

    public static class CancelReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                String action = intent.getAction();
                String str = HostsBlocker.TAG;
                Log.i(str, "CancelReceiver; onReceive; notificationId: " + action);
                HostsBlocker.sNotifications.remove(Integer.valueOf(Integer.parseInt(action)));
            } catch (Exception e) {
                Log.w(HostsBlocker.TAG, e);
            }
        }
    }

    public static class HostsBlockerActivity extends Activity {
        @Override
        protected void onCreate(Bundle bundle) {
            super.onCreate(bundle);
            String stringExtra = getIntent().getStringExtra("host");
            String str = HostsBlocker.TAG;
            Log.i(str, "onCreate; host: " + stringExtra);
            final String[] strArr = (String[]) HostsBlocker.splitHost(stringExtra).toArray(new String[0]);
            final AtomicReference atomicReference = new AtomicReference(strArr[0]);
            AlertDialog.Builder singleChoiceItems = Utils.getDialogBuilder(this).setTitle(HostsBlocker.sHostsBlockerTitle).setSingleChoiceItems(strArr, 0, new DialogInterface.OnClickListener() {
                @Override
                public final void onClick(DialogInterface dialogInterface, int i2) {
                    atomicReference.set(strArr[i2]);
                }
            });
            if (Build.VERSION.SDK_INT > 21) {
                singleChoiceItems.setNeutralButton("Whois", (DialogInterface.OnClickListener) null).setNegativeButton(HostsBlocker.sAllowLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public final void onClick(DialogInterface dialogInterface, int i2) {
                        HostsBlocker.HostsBlockerActivity.lambda$onCreate$1(atomicReference, dialogInterface, i2);
                    }
                }).setPositiveButton(HostsBlocker.sBlockLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public final void onClick(DialogInterface dialogInterface, int i2) {
                        HostsBlocker.HostsBlockerActivity.lambda$onCreate$2(atomicReference, dialogInterface, i2);
                    }
                });
            } else {
                singleChoiceItems.setNegativeButton("Whois", (DialogInterface.OnClickListener) null).setNeutralButton(HostsBlocker.sAllowLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public final void onClick(DialogInterface dialogInterface, int i2) {
                        HostsBlocker.HostsBlockerActivity.lambda$onCreate$3(atomicReference, dialogInterface, i2);
                    }
                }).setPositiveButton(HostsBlocker.sBlockLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public final void onClick(DialogInterface dialogInterface, int i2) {
                        HostsBlocker.HostsBlockerActivity.lambda$onCreate$4(atomicReference, dialogInterface, i2);
                    }
                });
            }
            AlertDialog create = singleChoiceItems.create();
            create.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public final void onDismiss(DialogInterface dialogInterface) {
                    HostsBlocker.HostsBlockerActivity.this.lambda$onCreate$5$HostsBlocker$HostsBlockerActivity(dialogInterface);
                }
            });
            create.show();
            if (Build.VERSION.SDK_INT > 21) {
                create.getButton(-3).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public final void onClick(View view) {
                        HostsBlocker.HostsBlockerActivity.this.lambda$onCreate$6$HostsBlocker$HostsBlockerActivity(atomicReference, view);
                    }
                });
            } else {
                create.getButton(-2).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public final void onClick(View view) {
                        HostsBlocker.HostsBlockerActivity.this.lambda$onCreate$7$HostsBlocker$HostsBlockerActivity(atomicReference, view);
                    }
                });
            }
            Utils.keepDialogOpenOnOrientationChange(create);
        }

        public static void lambda$onCreate$1(AtomicReference atomicReference, DialogInterface dialogInterface, int i2) {
            HostsBlocker.addAllowedHost((String) atomicReference.get());
            HostsBlocker.hideNotification((String) atomicReference.get());
        }

        public static void lambda$onCreate$2(AtomicReference atomicReference, DialogInterface dialogInterface, int i2) {
            HostsBlocker.addBlockedHost((String) atomicReference.get());
            HostsBlocker.hideNotification((String) atomicReference.get());
        }

        public static void lambda$onCreate$3(AtomicReference atomicReference, DialogInterface dialogInterface, int i2) {
            HostsBlocker.addAllowedHost((String) atomicReference.get());
            HostsBlocker.hideNotification((String) atomicReference.get());
        }

        public static void lambda$onCreate$4(AtomicReference atomicReference, DialogInterface dialogInterface, int i2) {
            HostsBlocker.addBlockedHost((String) atomicReference.get());
            HostsBlocker.hideNotification((String) atomicReference.get());
        }

        public void lambda$onCreate$5$HostsBlocker$HostsBlockerActivity(DialogInterface dialogInterface) {
            finish();
        }

        public void lambda$onCreate$6$HostsBlocker$HostsBlockerActivity(AtomicReference atomicReference, View view) {
            HostsBlocker.whois(this, (String) atomicReference.get());
        }

        public void lambda$onCreate$7$HostsBlocker$HostsBlockerActivity(AtomicReference atomicReference, View view) {
            HostsBlocker.whois(this, (String) atomicReference.get());
        }
    }

    public static void hideNotification(String str) {
        String str2 = TAG;
        Log.i(str2, "hideNotification; host: " + str);
        try {
            sNotificationManager.cancel(str.hashCode());
            if (str.startsWith("*.")) {
                str = str.substring(2);
            }
            synchronized (sNotifications) {
                for (Integer num : sNotifications.keySet()) {
                    if (sNotifications.get(num).endsWith(str)) {
                        sNotificationManager.cancel(num.intValue());
                    }
                }
            }
        } catch (Exception e) {
            Log.w(TAG, e);
        }
    }
}