Android 通过adb禁止某个应用上网

您所在的位置:网站首页 三星手机如何禁止软件联网 Android 通过adb禁止某个应用上网

Android 通过adb禁止某个应用上网

2024-07-10 18:57| 来源: 网络整理| 查看: 265

#通过包名查找应用的uid ➜ apk adb shell cat /data/system/packages.xml | grep com.xzh.hbls #关闭某个uid的上网权限 ➜ apk adb shell iptables -I fw_OUTPUT -m owner --uid-owner 10106 -j DROP ➜ apk adb shell iptables -I fw_INPUT -m owner --uid-owner 10106 -j DROP

注意命令行中的uid需要替换,uid如下图所示 在这里插入图片描述 详细信息请参考: https://blog.csdn.net/cyj88jyc/article/details/87985219

为防止作者后期删除,copy一份: iptables是Linux的一个命令行工具,通过设置一些规则可以直接把指定uid或网址的数据包从ip层过滤掉,从而实现网络防火墙的功能,这部分已经比较成熟,android或厂商只是对iptables命令进行了封装,让android app可以通过iptables命令进行防火墙设置,iptables有很多复杂的功能,我们主要看看怎么设置白名单只让指定的uid app可以联网和设置黑名单让指定的uid app不能联网,我们通过代码流程来分析,代码是mtk android8.1。

root后通过adb shell iptables -L可以查看当前的规则列表,Chain INPUT,OUTPUT就是控制数据包的输入输出,没做任何设置前应该张下面这个样子,Chain OUTPUT的数据包通过Chain fw_OUTPUT控制, Chain fw_OUTPUT的规则是空的,所以当前对网络不做限制。

$ adb shell iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination bw_INPUT all – anywhere anywhere fw_INPUT all – anywhere anywhere

Chain FORWARD (policy ACCEPT) target prot opt source destination oem_fwd all – anywhere anywhere fw_FORWARD all – anywhere anywhere bw_FORWARD all – anywhere anywhere natctrl_FORWARD all – anywhere anywhere

Chain OUTPUT (policy ACCEPT) target prot opt source destination oem_out all – anywhere anywhere firewall all – anywhere anywhere fw_OUTPUT all – anywhere anywhere st_OUTPUT all – anywhere anywhere bw_OUTPUT all – anywhere anywhere

Chain fw_FORWARD (1 references) target prot opt source destination

Chain fw_INPUT (1 references) target prot opt source destination

Chain fw_OUTPUT (1 references) target prot opt source destination

//android app层

INetworkManagementService networkService = INetworkManagementService.Stub.asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));

public void WhiteListMode(INetworkManagementService networkService) { FireWallUtils.setFirewallEnabled(networkService, true);//白名单模式 FireWallUtils.setFirewallUidRule(networkService, 0, 1016, 0); //重置vpn uid rule FireWallUtils.setFirewallUidRule(networkService, 0, 1016, 1); //设置vpn uid为白名单 FireWallUtils.setFirewallUidRule(networkService, 0, 0, 0); //重置root uid rule FireWallUtils.setFirewallUidRule(networkService, 0, 0, 1); //设置root uid为白名单

// List whitelistApp = new ArrayList(); // whitelistApp.add(“com.nuts.extremspeedup”); // PackageManager pm = mContext.getPackageManager(); // for (String pkgName : whitelistApp) { // int uid = FireWallUtils.getUidFromPackageName(pm, pkgName); // if (uid > 0) { // FireWallUtils.setFirewallUidRule(networkService, 0, uid, 0); //重置 uid rule // FireWallUtils.setFirewallUidRule(networkService, 0, uid, 1); //设置白名单 // } // } }

public void BlackListMode(INetworkManagementService networkService) { FireWallUtils.setFirewallEnabled(networkService, false); //黑名单模式 List whitelistApp = new ArrayList(); whitelistApp.add("com.iflytek.inputmethod");//com.iflytek.inputmethod PackageManager pm = getPackageManager(); for (String pkgName : whitelistApp) { int uid = FireWallUtils.getUidFromPackageName(pm, pkgName); //获取app的uid if (uid > 0) { FireWallUtils.setFirewallUidRule(networkService, 0, uid, 0); //重置 uid rule FireWallUtils.setFirewallUidRule(networkService, 0, uid, 2); //设置uid为黑名单 } } } public void DisableMobileMode(INetworkManagementService networkService) { FireWallUtils.setFirewallEnabled(networkService, false); //黑名单模式 List whitelistApp = new ArrayList(); whitelistApp.add("com.iflytek.inputmethod");//com.iflytek.inputmethod PackageManager pm = getPackageManager(); for (String pkgName : whitelistApp) { int uid = FireWallUtils.getUidFromPackageName(pm, pkgName); if (uid > 0) { FireWallUtils.setFirewallUidChainRule(networkService, uid, 0, false); //(networkType == 1) ? WIFI : MOBILE; , 禁止此uid连mobile } } }

import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.INetworkManagementService; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.Settings; import android.util.Log;

import java.util.ArrayList; import java.util.List;

public class FireWallUtils { private static final String TAG = “FireWallUtils”;

public static void setFirewallEnabled(INetworkManagementService networkService, boolean enable) { try { networkService.setFirewallEnabled(enable); } catch (RemoteException e) { Log.e(TAG, "setFirewallEnabled RemoteException e:" + Log.getStackTraceString(e)); } catch (Exception e) { Log.e(TAG, "setFirewallEnabled Exception e:" + Log.getStackTraceString(e)); } } public static void setFirewallUidRule(INetworkManagementService networkService, int chain, int uid, int rule) { try { networkService.setFirewallUidRule(chain, uid, rule); } catch (RemoteException e) { Log.e(TAG, "setFirewallUidRule RemoteException e:" + Log.getStackTraceString(e)); } catch (Exception e) { Log.e(TAG, "setFirewallUidRule Exception e:" + Log.getStackTraceString(e)); } } public static int getUidFromPackageName(PackageManager pm, String pkgName) { try { ApplicationInfo appInfo = pm.getApplicationInfo(pkgName, PackageManager.MATCH_ALL); if (appInfo != null) { return appInfo.uid; } } catch (PackageManager.NameNotFoundException e) { //e.printStackTrace(); } return -1; }

}

public static void setFirewallUidChainRule(INetworkManagementService networkService, int uid, int networkType, boolean allow) { try { networkService.setFirewallUidChainRule(uid, networkType, allow); } catch (RemoteException e) { Log.d(TAG, "setFirewallEnabled RemoteException e:" + Log.getStackTraceString(e)); } catch (Exception e) { Log.d(TAG, "setFirewallEnabled Exception e:" + Log.getStackTraceString(e)); } } public static void clearFirewallChain(INetworkManagementService networkService, String chain) { try { networkService.clearFirewallChain(chain); } catch (RemoteException e) { Log.d(TAG, "setFirewallEnabled RemoteException e:" + Log.getStackTraceString(e)); } catch (Exception e) { Log.d(TAG, "setFirewallEnabled Exception e:" + Log.getStackTraceString(e)); } }

frameworks/base/core/java/android/os/INetworkManagementService.aidl

void setFirewallEnabled(boolean enabled); boolean isFirewallEnabled(); void setFirewallInterfaceRule(String iface, boolean allow); void setFirewallUidRule(int chain, int uid, int rule); void setFirewallUidRules(int chain, in int[] uids, in int[] rules); void setFirewallChainEnabled(int chain, boolean enable); /** * agold * Cnfigure firewall rule by uid and chain * @hide */ void setFirewallUidChainRule(int uid, int networkType, boolean allow); /** @} */ /** * agold * Delete all rules in chain or all chains * @hide */ void clearFirewallChain(String chain);

frameworks/base/services/core/java/com/android/server/NetworkManagementService.java

@Override public void setFirewallEnabled(boolean enabled) { enforceSystemUid(); try { mConnector.execute("firewall", "enable", enabled ? "whitelist" : "blacklist"); mFirewallEnabled = enabled; } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } @Override public void setFirewallUidRule(int chain, int uid, int rule) { enforceSystemUid(); synchronized (mQuotaLock) { setFirewallUidRuleLocked(chain, uid, rule); } } private void setFirewallUidRuleLocked(int chain, int uid, int rule) { if (updateFirewallUidRuleLocked(chain, uid, rule)) { try { mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, getFirewallRuleName(chain, rule)); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } } /** * agold * @Configure firewall rule by uid and chain * @hide */ public void setFirewallUidChainRule(int uid, int networkType, boolean allow) { android.util.Log.i("linyuan_NMS", "setFirewallUidChainRule uid = " + uid + ", networkType = " + networkType + ", allow = " + allow); //enforceSystemUid(); final String MOBILE = "mobile"; final String WIFI = "wifi"; final String rule = allow ? "allow" : "deny"; final String chain = (networkType == 1) ? WIFI : MOBILE; try { mConnector.execute("firewall", "set_uid_fw_rule", uid, chain, rule); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } /** * agold * @Configure firewall rule by uid and chain * @hide */ public void clearFirewallChain(String chain) { //enforceSystemUid(); try { mConnector.execute("firewall", "clear_fw_chain", chain); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } }

system/netd/server/CommandListener.cpp

int CommandListener::FirewallCmd::runCommand(SocketClient *cli, int argc, char **argv) { if (argc < 2) { cli->sendMsg(ResponseCode::CommandSyntaxError, “Missing command”, false); return 0; }

if (!strcmp(argv[1], "enable")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: firewall enable ", false); return 0; } FirewallType firewallType = parseFirewallType(argv[2]); int res = gCtls->firewallCtrl.enableFirewall(firewallType); return sendGenericOkFail(cli, res); } if (!strcmp(argv[1], "disable")) { int res = gCtls->firewallCtrl.disableFirewall(); return sendGenericOkFail(cli, res); } if (!strcmp(argv[1], "is_enabled")) { int res = gCtls->firewallCtrl.isFirewallEnabled(); return sendGenericOkFail(cli, res); } if (!strcmp(argv[1], "set_uid_rule")) { if (argc != 5) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: firewall set_uid_rule ", false); return 0; } ChildChain childChain = parseChildChain(argv[2]); if (childChain == INVALID_CHAIN) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Invalid chain name. Valid names are: ", false); return 0; } int uid = atoi(argv[3]); FirewallRule rule = parseRule(argv[4]); int res = gCtls->firewallCtrl.setUidRule(childChain, uid, rule); return sendGenericOkFail(cli, res); } //agold start if (!strcmp(argv[1], "set_uid_fw_rule")) { ALOGD("set_uid_fw_rule"); if (argc != 5) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: firewall set_uid_fw_rule ", false); return 0; } int uid = atoi(argv[2]); FirewallChinaRule chain = parseChain(argv[3]); FirewallRule rule = parseRule(argv[4]); int res = gCtls->firewallCtrl.setUidFwRule(uid, chain, rule); return sendGenericOkFail(cli, res); } if (!strcmp(argv[1], "clear_fw_chain")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: firewall clear_fw_chain ", false); return 0; } FirewallChinaRule chain = parseChain(argv[2]); int res = gCtls->firewallCtrl.clearFwChain(chain); return sendGenericOkFail(cli, res); } //agold end cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false); return 0;

}

system/netd/server/FirewallController.cpp

int FirewallController::enableFirewall(FirewallType ftype) { int res = 0; if (mFirewallType != ftype) { // flush any existing rules disableFirewall();

if (ftype == WHITELIST) { // create default rule to drop all traffic std::string command = "*filter\n" "-A fw_INPUT -j DROP\n" "-A fw_OUTPUT -j REJECT\n" "-A fw_FORWARD -j REJECT\n" "COMMIT\n"; res = execIptablesRestore(V4V6, command.c_str()); } // Set this after calling disableFirewall(), since it defaults to WHITELIST there mFirewallType = ftype; } return res;

}

int FirewallController::disableFirewall(void) { mFirewallType = WHITELIST; mIfaceRules.clear();

// flush any existing rules std::string command = "*filter\n" ":fw_INPUT -\n" ":fw_OUTPUT -\n" ":fw_FORWARD -\n" "COMMIT\n"; return execIptablesRestore(V4V6, command.c_str());

}

int FirewallController::setUidRule(ChildChain chain, int uid, FirewallRule rule) { const char* op; const char* target; FirewallType firewallType = getFirewallType(chain); if (firewallType == WHITELIST) { target = “RETURN”; // When adding, insert RETURN rules at the front, before the catch-all DROP at the end. op = (rule == ALLOW)? “-I” : “-D”; } else { // BLACKLIST mode target = “DROP”; // When adding, append DROP rules at the end, after the RETURN rule that matches TCP RSTs. op = (rule == DENY)? “-A” : “-D”; }

std::vector chainNames; switch(chain) { case DOZABLE: chainNames = { LOCAL_DOZABLE }; break; case STANDBY: chainNames = { LOCAL_STANDBY }; break; case POWERSAVE: chainNames = { LOCAL_POWERSAVE }; break; case NONE: chainNames = { LOCAL_INPUT, LOCAL_OUTPUT }; break; default: ALOGW("Unknown child chain: %d", chain); return -1; } std::string command = "*filter\n"; for (std::string chainName : chainNames) { StringAppendF(&command, "%s %s -m owner --uid-owner %d -j %s\n", op, chainName.c_str(), uid, target); } StringAppendF(&command, "COMMIT\n"); return execIptablesRestore(V4V6, command);

}

//agold start const char* FirewallController::FIREWALL = “firewall”; const char* FirewallController::FIREWALL_MOBILE = “mobile”; const char* FirewallController::FIREWALL_WIFI = “wifi”; //agold end

int FirewallController::setupIptablesHooks(void) { int res = 0; //agold start std::string command = “*filter\n”; StringAppendF(&command, “-F firewall \n”); StringAppendF(&command, “-A firewall -o ppp+ -j mobile\n”); StringAppendF(&command, “-A firewall -o ccmni+ -j mobile\n”); StringAppendF(&command, “-A firewall -o ccemni+ -j mobile\n”); StringAppendF(&command, “-A firewall -o usb+ -j mobile\n”); StringAppendF(&command, “-A firewall -o cc2mni+ -j mobile\n”); StringAppendF(&command, “-A firewall -o wlan+ -j wifi\n”); StringAppendF(&command, “COMMIT\n”); res |= execIptablesRestore(V4V6, command.c_str()); //agold end res |= createChain(LOCAL_DOZABLE, getFirewallType(DOZABLE)); res |= createChain(LOCAL_STANDBY, getFirewallType(STANDBY)); res |= createChain(LOCAL_POWERSAVE, getFirewallType(POWERSAVE)); return res; }

//agold start int FirewallController::setUidFwRule(int uid, FirewallChinaRule chain, FirewallRule rule) { ALOGD(“setUidFwRule”); std::string command = "filter\n"; char uidStr[16]; const char op; const char* fwChain;

sprintf(uidStr, "%d", uid); if (rule == DENY) { op = "-I"; } else { op = "-D"; } if(chain == MOBILE) { fwChain = "mobile"; }else{ fwChain = "wifi"; }

/* if(chain == MOBILE) { if(rule == ALLOW) blacklistUsers.insert(uid); else blacklistUsers.erase(uid); } */

ALOGD("setUidFwRule op = %s, chain = %s, uid = %s", op, fwChain, uidStr); StringAppendF(&command, "%s %s -m owner --uid-owner %s -j REJECT\n", op, fwChain, uidStr); StringAppendF(&command, "COMMIT\n"); return execIptablesRestore(V4V6, command.c_str());

}

int FirewallController::clearFwChain(FirewallChinaRule chain) { std::string command = "filter\n"; const char fwChain; if(chain == MOBILE) { fwChain = “mobile”; }else{ fwChain = “wifi”; } StringAppendF(&command, “-F %s \n”, fwChain); StringAppendF(&command, “COMMIT\n”); return execIptablesRestore(V4V6, command.c_str()); } //agold end

运行到最后就是调用iptables命令去添加或删除一些规则,如果没有接口可以参考上面的接口增加,熟悉下iptables的规则就知道怎么添加了。

WhiteListMode函数其实就调的下面的iptables命令

adb shell iptables -A fw_INPUT -j DROP ; // -A表示要添加规则到fw_INPUT链, -j DROP表示添加丢弃规则,丢弃所有输入包 adb shell iptables -A fw_OUTPUT -j REJECT // -A表示要添加规则到fw_OUTPU链, -j REJECT表示添加拒绝规则,拒绝所有输出包 adb shell iptables -A fw_FORWARD -j REJECT

adb shell iptables -I fw_OUTPUT -m owner --uid-owner 1016 -j ACCEPT // -I表示插入一条规则到fw_OUTPUT链,是一条白名单规则,允许uid 1016的数据包通过

adb shell iptables -I fw_INPUT -m owner --uid-owner 1016 -j ACCEPT

调用后iptables张下面这个样子,Chain OUTPUT的数据包通过Chain fw_OUTPUT控制, Chain fw_OUTPUT的规则是reject所有数据包,只允许uid 1016 vpn。

$ adb shell iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination bw_INPUT all – anywhere anywhere fw_INPUT all – anywhere anywhere

Chain FORWARD (policy ACCEPT) target prot opt source destination oem_fwd all – anywhere anywhere fw_FORWARD all – anywhere anywhere bw_FORWARD all – anywhere anywhere natctrl_FORWARD all – anywhere anywhere

Chain OUTPUT (policy ACCEPT) target prot opt source destination oem_out all – anywhere anywhere firewall all – anywhere anywhere fw_OUTPUT all – anywhere anywhere st_OUTPUT all – anywhere anywhere bw_OUTPUT all – anywhere anywhere

Chain fw_FORWARD (1 references) target prot opt source destination REJECT all – anywhere anywhere reject-with icmp-port-unreachable

Chain fw_INPUT (1 references) target prot opt source destination RETURN all – anywhere anywhere owner UID match vpn DROP all – anywhere anywhere

Chain fw_OUTPUT (1 references) target prot opt source destination RETURN all – anywhere anywhere owner UID match vpn REJECT all – anywhere anywhere reject-with icmp-port-unreachable

BlackListMode函数其实就调的下面的iptables命令

adb shell iptables -F fw_INPUT

adb shell iptables -F fw_OUTPUT //清除fw_OUTPUT链上所有规则,允许所有数据包通过

adb shell iptables -D fw_INPUT -m owner --uid-owner 10086 -j DROP // -D表示删除一条规则

adb shell iptables -I fw_OUTPUT -m owner --uid-owner 10086 -j DROP // -I表示插入一条规则到fw_OUTPUT链,是一条黑名单规则,只禁止uid 10086的数据包通过

adb shell iptables -I fw_INPUT -m owner --uid-owner 10086 -j DROP

调用后iptables张下面这个样子,Chain OUTPUT的数据包通过Chain fw_OUTPUT控制, Chain fw_OUTPUT的规则是只丢弃

uid 为u11_a83(10086)的数据包,就是前面设置的app的uid 10086

~$adb shell iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination bw_INPUT all – anywhere anywhere fw_INPUT all – anywhere anywhere

Chain OUTPUT (policy ACCEPT) target prot opt source destination oem_out all – anywhere anywhere firewall all – anywhere anywhere fw_OUTPUT all – anywhere anywhere st_OUTPUT all – anywhere anywhere bw_OUTPUT all – anywhere anywhere

Chain fw_INPUT (1 references) target prot opt source destination DROP all – anywhere anywhere owner UID match u11_a83

Chain fw_OUTPUT (1 references) target prot opt source destination DROP all – anywhere anywhere owner UID match u11_a83

如果需要单独控制wifi或移动数据,看DisableMobileMode里面setFirewallUidChainRule接口,这部分是厂商加的,如果没有可以按上面的内容进行添加,参考agold关键字,对照adb shell iptables -L的输出调试问题就不大了。

调用后iptables张下面这个样子,Chain OUTPUT的数据包通过Chain fw_OUTPUT 和Chain firewall控制, Chain fw_OUTPUT的规则为空就是不限制,Chain firewall通过mobile和wifi链控制wifi/mobile, Chain wifi为空,Chain mobile为reject owner UID match u0_a79

~$ adb shell iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination bw_INPUT all – anywhere anywhere fw_INPUT all – anywhere anywhere

Chain OUTPUT (policy ACCEPT) target prot opt source destination oem_out all – anywhere anywhere firewall all – anywhere anywhere fw_OUTPUT all – anywhere anywhere st_OUTPUT all – anywhere anywhere bw_OUTPUT all – anywhere anywhere

Chain firewall (1 references) target prot opt source destination mobile all – anywhere anywhere mobile all – anywhere anywhere mobile all – anywhere anywhere mobile all – anywhere anywhere mobile all – anywhere anywhere wifi all – anywhere anywhere

Chain fw_INPUT (1 references) target prot opt source destination

Chain fw_OUTPUT (1 references) target prot opt source destination

Chain mobile (5 references) target prot opt source destination REJECT all – anywhere anywhere owner UID match u0_a79 reject-with icmp-port-unreachable

Chain wifi (1 references) target prot opt source destination

iptables命令可以参考 https://blog.csdn.net/l1028386804/article/details/47356011

https://blog.csdn.net/reyleon/article/details/12976341

———————————————— 版权声明:本文为CSDN博主「cyj88jyc」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/cyj88jyc/article/details/87985219



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3