AOSP 隐藏 su

本文介绍了一种在Android设备上隐藏root权限的方法,通过修改su文件路径和procmem文件,同时更新fs_config.cpp和file_contexts文件中的权限设置,使应用无法检测到root状态。

       我们在开发过程中会用到root权限,但是又不想其它的应用能够检测到手机是root的,该怎么做呢?

       首先,检测检测手机root有很重要的一个检测方式, 就是 检测 /system/xbin/su 文件的  s位. 如下图:   

-rwsr-sr-x  1 root root    11056 2018-12-05 23:33 procmem
-rwsr-x---  1 root shell   11064 2018-12-05 23:33 su

       从上面我们可以清除看到 权限组一项 有是 s位的, 现在一些应用的检测手段就是  通过得到手机的PATH环境变量,然后扫描该环境变量路径中的全部文件来分析 是否有这个s 位.  那么我们完全可以这么干.

      1` 编译的时候删除掉 procmem 这个文件, 删掉是不会有啥影响的. 

      2` 将su文件的路径给改一改.  比如放到 上一级 system 目录下面.   

      这两个文件的源码都在 AOSP/system/extras 目录下. 直接修改Android.mk 文件 改变其编译后的路径即可. 但是, su文件如果仅仅是改了路径是不行的. 因为其权限问题.

      我们要知道 所有system 分区的文件权限其实都已经在代码中 给预先定义好了, 所以如果要改su文件的路径,那么 代码中定义的权限也需要改掉. 同样如果我们需要在 system分区新增加文件, 也需要去定义权限.

      该权限文件路径 AOSP/system/core/libcutils/fs_config.cpp 摘取代码片段如下:

    { 00600, AID_ROOT,      AID_ROOT,      0, "system/build.prop" },
    { 00444, AID_ROOT,      AID_ROOT,      0, sys_conf_dir + 1 },
    { 00444, AID_ROOT,      AID_ROOT,      0, sys_conf_file + 1 },
    { 00440, AID_ROOT,      AID_SHELL,     0, "system/etc/init.goldfish.rc" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/init.goldfish.sh" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/init.ril" },
    { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/ppp/*" },
    { 00555, AID_ROOT,      AID_ROOT,      0, "system/etc/rc.*" },
    { 00440, AID_ROOT,      AID_ROOT,      0, "system/etc/recovery.img" },
    { 00600, AID_ROOT,      AID_ROOT,      0, "vendor/build.prop" },
    { 00600, AID_ROOT,      AID_ROOT,      0, "vendor/default.prop" },
    { 00444, AID_ROOT,      AID_ROOT,      0, ven_conf_dir + 1 },
    { 00444, AID_ROOT,      AID_ROOT,      0, ven_conf_file + 1 },

    // the following two files are INTENTIONALLY set-uid, but they
    // are NOT included on user builds.
    { 06755, AID_ROOT,      AID_ROOT,      0, "system/xbin/procmem" },
    { 04750, AID_ROOT,      AID_SHELL,     0, "system/su" },

我们可以看到 其中 /system/su 就是我修改后的路径, 原本是 /system/xibin/su.

      此处修改完毕,还有一处aosp/system/sepolicy/private/file_contexts 该文件中 对于 /system/xbin/su的 声明也要改掉.

     改完编译后, 执行 /system/su 就会起效了. 直接执行 su 是找不到的. 

<think> 我们正在讨论Android 13中设置IP地址的隐藏API。由于Android系统通常不鼓励直接使用隐藏API(它们可能不稳定且不被官方支持),但有时在特定场景下(如系统应用或拥有特殊权限的应用)可能需要使用。 在Android中,网络设置通常通过`ConnectivityManager`和相关的网络类进行。但是,公开的API可能不提供直接设置静态IP的方法。因此,我们需要查看隐藏的API。 在Android框架中,设置IP地址通常与`WifiConfiguration`类相关(在较新版本中已被替换)或使用`StaticIpConfiguration`类。从Android 10开始,`WifiConfiguration`被标记为过时,取而代之的是`WifiNetworkSuggestion`等API,但这些新API也不直接暴露设置静态IP的方法。 在Android 13中,我们可以尝试使用反射来调用隐藏API。注意:隐藏API在不同Android版本中可能发生变化,且使用反射调用隐藏API可能在未来版本中失效。 以下步骤可能用于设置静态IP: 1. 获取当前的网络连接(例如WIFI网络)。 2. 创建一个`StaticIpConfiguration`对象(隐藏API)并设置IP地址、网关、DNS等。 3. 通过反射调用相关方法设置静态IP。 具体步骤: - 首先,我们需要获取`ConnectivityManager`的实例。 - 然后,获取当前的网络(例如WIFI网络)。 - 使用反射来调用隐藏方法。 注意:从Android 7.0(API 24)开始,Google加强了私有API的限制(称为受限API),因此即使通过反射也可能无法调用。对于非系统应用,这几乎是不可能的。但是,如果您的应用是系统应用(具有系统签名),或者在具有root权限的设备上运行,则可能绕过这些限制。 下面是一个使用反射设置静态IP的示例代码框架(仅用于研究目的,实际使用需谨慎): ```java import android.net.ConnectivityManager; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.StaticIpConfiguration; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; public class StaticIpSetter { public static void setStaticIp(ConnectivityManager connectivityManager, String ipAddress, int prefixLength, String gateway, String dns1, String dns2) throws Exception { // 创建StaticIpConfiguration对象 StaticIpConfiguration staticConfig = new StaticIpConfiguration(); // 设置IP地址和子网掩码 InetAddress inetAddress = InetAddress.getByName(ipAddress); LinkAddress linkAddress = new LinkAddress(inetAddress, prefixLength); staticConfig.ipAddress = linkAddress; // 设置网关 staticConfig.gateway = InetAddress.getByName(gateway); // 设置DNS if (dns1 != null) { staticConfig.dnsServers.add(InetAddress.getByName(dns1)); } if (dns2 != null) { staticConfig.dnsServers.add(InetAddress.getByName(dns2)); } // 获取当前网络(这里假设是活跃的网络,实际可能需要指定网络) android.net.Network network = connectivityManager.getActiveNetwork(); if (network == null) { throw new IllegalStateException("No active network"); } // 通过反射调用ConnectivityManager的setStaticIpConfiguration方法 try { Method setStaticIpMethod = ConnectivityManager.class.getMethod( "setStaticIpConfiguration", android.net.Network.class, StaticIpConfiguration.class); setStaticIpMethod.invoke(connectivityManager, network, staticConfig); } catch (Exception e) { e.printStackTrace(); throw e; } } } ``` 注意: 1. 上述代码使用反射调用隐藏方法`setStaticIpConfiguration`,这个方法在Android 13中可能存在也可能不存在。 2. 需要权限:`android.permission.CHANGE_NETWORK_STATE`和`android.permission.ACCESS_NETWORK_STATE`,而且由于是隐藏API,可能还需要系统签名。 3. 此代码仅为示例,实际使用时需要处理异常和不同的Android版本。 另外,在Android 10及以上,Google引入了更严格的政策,禁止非SDK接口的使用(即隐藏API),因此上述反射调用在普通应用中将无法使用(会抛出`NoSuchMethodException`或调用失败)。 替代方案: - 对于系统应用,可以将应用放在`/system/priv-app`目录下,并使用`@hide` API(通过AOSP源码编译时引入)。 - 使用系统权限:如果设备已root,可以通过执行shell命令(如`ip`命令)来设置IP,但需要root权限。 使用shell命令设置静态IP的示例(需要root): ```java public static void setStaticIpWithRoot(String interfaceName, String ipAddress, int netmask, String gateway, String dns1, String dns2) { try { Process process = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(process.getOutputStream()); // 清除现有IP os.writeBytes("ip addr flush dev " + interfaceName + "\n"); // 设置新IP os.writeBytes("ip addr add " + ipAddress + "/" + netmask + " dev " + interfaceName + "\n"); // 设置网关 os.writeBytes("ip route add default via " + gateway + "\n"); // 设置DNS(需要修改系统属性或resolv.conf,但不同设备位置可能不同) // 例如,修改resolv.conf os.writeBytes("echo 'nameserver " + dns1 + "' > /system/etc/resolv.conf\n"); if (dns2 != null) { os.writeBytes("echo 'nameserver " + dns2 + "' >> /system/etc/resolv.conf\n"); } os.writeBytes("exit\n"); os.flush(); os.close(); process.waitFor(); } catch (Exception e) { e.printStackTrace(); } } ``` 注意:修改系统文件(如`resolv.conf`)可能在不同设备上位置不同,且需要文件系统可写。 总结: - 普通应用无法直接使用隐藏API设置静态IP(受限于非SDK接口限制)。 - 系统应用可以通过反射或直接调用隐藏API(需在系统镜像中编译)。 - 在已root设备上,可以通过执行root命令设置。 请根据您的具体情况选择合适的方法。 §§相关问题§§ 1. 在Android 13中,如何为系统应用申请使用隐藏API的权限? 2. 如何使用ADB命令设置Android设备的静态IP地址? 3. Android 13中,WIFI网络和以太网网络设置静态IP的方法是否相同? 4. 如何避免使用反射调用隐藏API导致的兼容性问题? </think> 在 Android 13 中设置 IP 地址的隐藏 API 主要涉及网络配置相关的内部类和方法。这些 API 属于 `@hide` 标记的非公开接口,使用时需要通过反射调用。以下是关键实现步骤和注意事项: ### 核心隐藏 API 1. **`StaticIpConfiguration` 类** ```java android.net.StaticIpConfiguration ``` - 用于配置静态 IP 参数(IP 地址、网关、DNS 等) - 隐藏字段: ```java public LinkAddress ipAddress; // IP 和子网掩码 public InetAddress gateway; // 网关 public List<InetAddress> dnsServers; // DNS 列表 ``` 2. **`IpConfiguration` 类** ```java android.net.IpConfiguration ``` - 设置 IP 分配策略: ```java ipConfig.setStaticIpConfiguration(staticIpConfig); // 设置静态IP配置 ipConfig.setIpAssignment(IpAssignment.STATIC); // 设为静态分配模式 ``` 3. **网络更新方法** ```java // 通过 ConnectivityManager 更新网络配置 ConnectivityManager.setNetworkPreference(network, ipConfiguration); ``` ### 完整反射实现示例 ```java import android.content.Context; import android.net.ConnectivityManager; import android.net.IpConfiguration; import android.net.LinkAddress; import android.net.StaticIpConfiguration; import java.lang.reflect.Method; import java.net.InetAddress; public class HiddenIpApi { public static boolean setStaticIp(Context context, String ip, int prefix, String gateway, String[] dnsServers) { try { // 1. 创建 StaticIpConfiguration 对象 Class<?> staticIpClass = Class.forName("android.net.StaticIpConfiguration"); Object staticIpConfig = staticIpClass.newInstance(); // 设置 IP 地址 (192.168.1.100/24 格式) Method setIpAddress = staticIpClass.getMethod("setIpAddress", LinkAddress.class); setIpAddress.invoke(staticIpConfig, new LinkAddress(InetAddress.getByName(ip), prefix)); // 设置网关 Method setGateway = staticIpClass.getMethod("setGateway", InetAddress.class); setGateway.invoke(staticIpConfig, InetAddress.getByName(gateway)); // 设置 DNS for (String dns : dnsServers) { Method addDns = staticIpClass.getMethod("addDns", InetAddress.class); addDns.invoke(staticIpConfig, InetAddress.getByName(dns)); } // 2. 创建 IpConfiguration 对象 IpConfiguration ipConfig = new IpConfiguration(); // 通过反射设置静态IP配置 Method setStaticIp = IpConfiguration.class.getMethod( "setStaticIpConfiguration", staticIpClass); setStaticIp.invoke(ipConfig, staticIpConfig); // 设置分配模式为 STATIC Method setAssignment = IpConfiguration.class.getMethod( "setIpAssignment", IpConfiguration.IpAssignment.class); setAssignment.invoke(ipConfig, IpConfiguration.IpAssignment.STATIC); // 3. 获取 ConnectivityManager 服务 ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); // 4. 获取当前活跃网络 android.net.Network network = connMgr.getActiveNetwork(); // 5. 反射调用更新方法 Method setNetworkPreference = ConnectivityManager.class.getMethod( "setNetworkPreference", android.net.Network.class, IpConfiguration.class); setNetworkPreference.invoke(connMgr, network, ipConfig); return true; } catch (Exception e) { e.printStackTrace(); return false; } } } ``` ### 关键注意事项 1. **权限要求** ```xml <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> ``` 2. **系统限制** - 仅适用于系统级应用(需系统签名) - 普通应用因 SELinux 限制无法调用 - Android 10+ 的非 SDK 接口限制(需添加到豁免列表) 3. **兼容性风险** - 隐藏 API 可能随版本更新变化(如 Android 14 可能修改实现) - 需验证目标设备固件中的实际类名和方法签名 > **替代方案**:对非系统应用,可通过 `WifiManager` 的公开 API 配置 WiFi 静态 IP(需用户手动操作),或使用 `ip` 命令通过 root 权限执行 shell 命令: > ```bash > adb shell ip address add 192.168.1.100/24 dev wlan0 > ``` ### 验证方法 在 ADB 中检查 IP 配置: ```bash adb shell ifconfig wlan0 adb shell ip route show ``` [^1]: Android AOSP 源码中 `ConnectivityService.java` 的网络配置实现 [^2]: Android 开发者文档关于网络策略管理的说明
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值