【问题标题】:Acccess to /proc/net/tcp in Android Q在 Android Q 中访问 /proc/net/tcp
【发布时间】:2020-02-18 04:53:37
【问题描述】:

在 Android-9 之前的我的 VPN 应用程序中,可以从针对 API 级别 /proc/net/tcp 文件。从应用程序访问似乎不再适用于 Android Q。我收到一个错误 @ 987654324@ 尝试读取文件时。

在 Android-Q 隐私更改中,谷歌已解决 Restriction on access to /proc/net filesystem

而且我认为如果应用程序 compileSDK 版本为 29,则可以使用ConnectivityManager.getConnectionOwnerUid()。但不幸的是,目前我无法更改我的 compileSDK 版本,但我将 targetSDK 版本更新为最新的 IE,29。

在 Android-10 中读取文件的任何其他可能方式?贴出我的代码供参考

public static final int INDEX_UID_COL = 7;
public static final int INDEX_LOCAL_ADDRESS_COL = 1;
public static final String PROC_FILE = "/proc/net/tcp";

 public static String getPackageName(Context context, int srcPort) {
        String packageName = "";
        try {

            BufferedReader br = new BufferedReader(new FileReader(PROC_FILE));

            //Ignore first line
            String line = br.readLine();
            while ((line = br.readLine()) != null) {
                /**
                 * Proc file table column sequence
                 * sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
                 */
                String[] parts = line.trim().split("\\s+");
                if (parts.length >= 8) {
                    String localAddress = parts[INDEX_LOCAL_ADDRESS_COL];
                    if (!localAddress.isEmpty()) {
                        String[] localAddressParts = localAddress.split(":");
                        if (localAddressParts.length == 2) {
                            int port = Integer.parseInt(localAddressParts[1], 16);
                            if (port == srcPort) {
                                int uid = Integer.parseInt(parts[INDEX_UID_COL]);
                                packageName = context.getPackageManager().getNameForUid(uid);
                                break;
                            }
                        }
                    }
                }
            }
            br.close();
        } catch (Exception ex) {
            Log.e("ProcFileParser", ex.getMessage());
        }
        return packageName;
    }

【问题讨论】:

  • 您可以随时更改您的compileSdkVersion
  • @ianhanniballake 我们即将推出更新,同时更新 compieSdkVersion 所有测试用例都失败了,因为 AndroidTesCase 在 compileSKD 29 中被删除。所以我们决定修复关键问题并上线,然后迁移到新的测试支持库。所以暂时无法更新compileSdk。
  • @ianhanniballake 有没有其他方法可以解决这个问题?感谢您的支持。

标签: android networking linux-kernel ip android-10.0


【解决方案1】:

ConnectivityManager 是平台级 API。您可以尝试 java 反射以便在您的上下文中访问 getConnectionOwnerUid但我建议你将 compileSdk 版本更新到最新版本

import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;

InetSocketAddress remoteInetSocketAddress = new InetSocketAddress(finalHost, srcPort);
InetSocketAddress localInetSocketAddress = new InetSocketAddress(1234);

ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Method method = ConnectivityManager.class.getMethod("getConnectionOwnerUid", int.class, InetSocketAddress.class, InetSocketAddress.class);
int uid = (int) method.invoke(connectivityManager, IPPROTO_TCP, localInetSocketAddress, remoteInetSocketAddress);
if (uid != INVALID_UID) {
       // UID access here         
  }

注意:该方法仅允许 VPN 应用程序查找网络连接的 UID 所有者。这意味着只有适用于调用 VPN 应用的 UID 的连接才会被解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2020-06-16
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多