我正在开发一个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();
}
}
}