TCPDump从adb shell运行,但不是从设备运行

时间:2015-06-15 06:44:18

标签: java android tcpdump

我正在开发一个Android应用程序来监控Android设备中的网络使用情况。

其中一个应用程序要求是提供由tcpdump命令创建的“.pcap”文件。 当我尝试从adb shell执行tcpdum命令时,一切正常,我可以创建这个文件。 但是当我尝试使用java代码从设备本身执行此命令时,我得到权限被拒绝错误。

应该提到的是,我的java代码适用于其他不需要特殊权限的命令。

还应该提到我使用了以下两个 rooted 设备(第一个三星 - 运行android 4.4,第二个三星 - 运行android 5.1.1)

此外,我尝试安装另一个tcpdump二进制文件并赋予它执行权限,并尝试使用不同的tcpdump命令变体以获得“su”的权限。 根据我的理解,这是内核的行为,这是出于安全原因,但尽管如此,我想知道 如果有办法绕过这个/给我的应用程序所需的权限,以便运行上述命令。 下面是我试图运行的命令以及我给出的响应。

命令:tcpdump -l -i eth1 -w /sdcard/output.pcap 响应:tcpdump:eth1:您无权在该设备上捕获 (套接字:不允许操作)

命令:tcpdump -w /sdcard/output.pcap 响应:tcpdump:无法打开netlink socket 13:权限被拒绝

响应:tcpdump:rmnet0:您无权在该设备上捕获。

我的清单权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_SUPERUSER"/>

相关代码:

public static boolean executeCommandViaShell(String sCmd) {
    DataInputStream isErr = null, isRes = null;
    BufferedReader brErr = null, brRes = null;
    try {
        Process process = Runtime.getRuntime().exec(sCmd);
        isErr = new DataInputStream(process .getErrorStream());
        brErr = new BufferedReader(new InputStreamReader(isErr));
        isRes = new DataInputStream(process .getInputStream());
        brRes = new BufferedReader(new InputStreamReader(isRes));
        // errors:
        while ((m_sMessage = brErr.readLine()) != null) {
            if (m_sMessage.equalsIgnoreCase("INVALID"))
            {
                return false;
            }
        }
        while ((m_sMessage = brRes.readLine()) != null) {
            if (m_sMessage.equals("SUCCESS")) {
                Log.d(TAG, "SUCCESS m_sMessage: " + m_sMessage);
            }
            else {
                return false;
            }
        }
        return true;
    }
    catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    finally {
        try {
            isErr.close();
            isRes.close();
            brErr.close();
            brRes.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

0 个答案:

没有答案