S T G SuperAPPS v9.99.99版本的 MD5 值为:ec866d8c695a659ed10459d6bd169615

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


package com.bajingan.bangsat.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.util.Log;
import android.view.View;
import android.widget.Toast;
import com.bajingan.bangsat.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 com.swift.sandhook.annotation.SkipParamCheck;
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.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HostsBlocker {
    private static final String PREF_KEY_PREFIX = "com.bajingan.bangsat.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 blockByDefault, String socksProxyHost, boolean allowAllOtherHosts) {
        sContext = context;
        sBlockByDefault = blockByDefault;
        sSocksProxyHost = socksProxyHost;
        sAllowAllOtherHosts = allowAllOtherHosts;
        sNotificationManager = (NotificationManager) context.getSystemService("notification");
        sPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        synchronized (sHosts) {
            try {
                try {
                    BufferedReader r10 = new BufferedReader(new InputStreamReader(context.getAssets().open(".blockedHostsFile")));
                    try {
                        Pattern p10 = Pattern.compile("(0.0.0.0|127.0.0.1|# x.x.x.x)\\s+(\\S*)");
                        while (true) {
                            String line = r10.readLine();
                            if (line != null) {
                                String line2 = line.trim();
                                if (line2.startsWith("# x.x.x.x") || !line2.startsWith("#")) {
                                    Matcher m10 = p10.matcher(line2);
                                    if (m10.find()) {
                                        String host = m10.group(2);
                                        boolean allowedBlocked = "# x.x.x.x".equals(m10.group(1));
                                        Log.i(TAG, "install; host: " + host + ", allowedBlocked: " + allowedBlocked);
                                        sHostsFileHosts.put(host, Boolean.valueOf(allowedBlocked));
                                    }
                                }
                            } else {
                                try {
                                    break;
                                } catch (Exception e10) {
                                }
                            }
                        }
                    } finally {
                        try {
                            r10.close();
                        } catch (Exception e11) {
                        }
                    }
                } catch (Exception e12) {
                    Log.w(TAG, e12);
                }
            } catch (FileNotFoundException e13) {
            }
            for (String key : sPreferences.getAll().keySet()) {
                if (key != null && key.startsWith(PREF_KEY_PREFIX)) {
                    boolean b10 = sPreferences.getBoolean(key, false);
                    sHosts.put(key.substring(PREF_KEY_PREFIX.length()), Boolean.valueOf(b10));
                }
            }
            Log.i(TAG, "install; sHosts: " + sHosts);
        }
        Hooking.initHooking(context);
        Hooking.addHookClass(Hook.class);
        Log.i(TAG, "install; hooks installed");
        sHostsBlockerTitle = Utils.getAppBangsatResourceText(sContext, "hosts_blocker_title", "Hosts blocker").toString();
        sContentTitle = Utils.getAppBangsatResourceText(sContext, "hosts_blocker_app_is_accessing_title", "%s is accessing").toString();
        sContentText = Utils.getAppBangsatResourceText(sContext, "hosts_blocker_touch_to_block_title", "Touch to block %s").toString();
        sAllowLabel = Utils.getAppBangsatResourceText(sContext, "label_allow", "Allow").toString();
        sBlockLabel = Utils.getAppBangsatResourceText(sContext, "label_block", "Block").toString();
        sIgnoreLabel = Utils.getAppBangsatResourceText(sContext, "label_ignore", "Ignore").toString();
        sHostBlockedMessage = Utils.getAppBangsatResourceText(sContext, "hosts_blocker_host_blocked_message", "Host %s blocked.").toString();
    }

    @HookReflectClass("java.net.PlainSocketImpl")
    public static class Hook {

        @HookMethodBackup("socketConnect")
        @SkipParamCheck
        static Method socketConnectBackup;

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

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

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

    public static List<String> splitHost(String host) {
        List<String> list = new ArrayList<>();
        list.add(host);
        boolean alpha = false;
        int len = host.length();
        int n10 = 0;
        while (true) {
            if (n10 < len) {
                char c10 = host.charAt(n10);
                if (c10 == '.' || Character.isDigit(c10)) {
                    n10++;
                } else {
                    alpha = true;
                    break;
                }
            } else {
                break;
            }
        }
        if (alpha) {
            while (true) {
                int pos = host.indexOf(46);
                if (pos == -1) {
                    break;
                }
                host = host.substring(pos + 1);
                if (host.indexOf(46) == -1) {
                    break;
                }
                list.add("*." + host);
            }
        }
        return list;
    }

    private static void notifyHost(String host) {
        int notificationId = host.hashCode();
        synchronized (sNotifications) {
            if (sNotifications.containsKey(Integer.valueOf(notificationId))) {
                return;
            }
            sNotifications.put(Integer.valueOf(notificationId), host);
            Log.i(TAG, "notifyHost; host: " + host);
            int requestCode = host.hashCode();
            Context context = sContext;
            PendingIntent contentIntent = PendingIntent.getBroadcast(context, requestCode, new Intent(host, null, context, ContentReceiver.class), 134217728);
            Context context2 = sContext;
            PendingIntent allowIntent = PendingIntent.getBroadcast(context2, requestCode + 1, new Intent(host, null, context2, AllowReceiver.class), 1073741824);
            Context context3 = sContext;
            PendingIntent blockIntent = PendingIntent.getBroadcast(context3, requestCode + 2, new Intent(host, null, context3, BlockReceiver.class), 1073741824);
            Context context4 = sContext;
            PendingIntent ignoreIntent = PendingIntent.getBroadcast(context4, requestCode + 3, new Intent(host, null, context4, IgnoreReceiver.class), 1073741824);
            PendingIntent cancelIntent = PendingIntent.getBroadcast(sContext, requestCode + 4, new Intent(Integer.toString(notificationId), null, sContext, CancelReceiver.class), 1073741824);
            String contentTitle = sContentTitle.replace("%s", Utils.getAppName(sContext));
            Notification.Builder builder = new Notification.Builder(sContext).setSmallIcon(android.R.drawable.ic_dialog_alert).setContentTitle(contentTitle).setContentIntent(contentIntent).setDeleteIntent(cancelIntent).setAutoCancel(false);
            if (Build.VERSION.SDK_INT >= 16) {
                builder.setContentText(host).addAction(requestCode, sAllowLabel, allowIntent).addAction(requestCode, sBlockLabel, blockIntent).addAction(requestCode, sIgnoreLabel, ignoreIntent);
            } else {
                String contentText = sContentText.replace("%s", host);
                builder.setContentText(contentText).setContentIntent(blockIntent);
            }
            if (Build.VERSION.SDK_INT >= 21) {
                builder.setVisibility(-1);
            }
            Utils.setSmallNotificationIcon(builder);
            Notification notification = builder.getNotification();
            notification.sound = null;
            notification.defaults &= -2;
            sNotificationManager.notify(notificationId, notification);
        }
    }

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

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

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

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

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

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

    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 host = intent.getAction();
                if (!TextUtils.isEmpty(host)) {
                    handleHost(context, host);
                }
            } catch (Exception e10) {
                Log.w(HostsBlocker.TAG, e10);
            }
        }
    }

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

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

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

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

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

    public static class HostsBlockerActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            String host = getIntent().getStringExtra("host");
            Log.i(HostsBlocker.TAG, "onCreate; host: " + host);
            List<String> list = HostsBlocker.splitHost(host);
            final String[] items = (String[]) list.toArray(new String[0]);
            final AtomicReference<String> ref = new AtomicReference<>(items[0]);
            AlertDialog.Builder builder = Utils.getDialogBuilder(this).setTitle(HostsBlocker.sHostsBlockerTitle).setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    String item = items[which];
                    ref.set(item);
                }
            });
            if (Build.VERSION.SDK_INT > 21) {
                builder.setNeutralButton("Whois", (DialogInterface.OnClickListener) null).setNegativeButton(HostsBlocker.sAllowLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        HostsBlocker.addAllowedHost((String) ref.get());
                        HostsBlocker.removeNotification((String) ref.get());
                    }
                }).setPositiveButton(HostsBlocker.sBlockLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        HostsBlocker.addBlockedHost((String) ref.get());
                        HostsBlocker.removeNotification((String) ref.get());
                    }
                });
            } else {
                builder.setNegativeButton("Whois", (DialogInterface.OnClickListener) null).setNeutralButton(HostsBlocker.sAllowLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        HostsBlocker.addAllowedHost((String) ref.get());
                        HostsBlocker.removeNotification((String) ref.get());
                    }
                }).setPositiveButton(HostsBlocker.sBlockLabel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        HostsBlocker.addBlockedHost((String) ref.get());
                        HostsBlocker.removeNotification((String) ref.get());
                    }
                });
            }
            AlertDialog dialog = builder.create();
            dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialog2) {
                    HostsBlockerActivity.this.finish();
                }
            });
            dialog.show();
            if (Build.VERSION.SDK_INT > 21) {
                dialog.getButton(-3).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v10) {
                        HostsBlocker.whois(HostsBlockerActivity.this, (String) ref.get());
                    }
                });
            } else {
                dialog.getButton(-2).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v10) {
                        HostsBlocker.whois(HostsBlockerActivity.this, (String) ref.get());
                    }
                });
            }
            Utils.keepDialogOpenOnOrientationChange(dialog);
        }
    }

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