#Summary AndroidNetMonitor is a system for passive monitoring, collection and analysis of fine-grained, large-scale packet measurements from Android devices. It is used to obtain real application information of traffic sources and collect brief information of packets sent and received by mobile phones (i.e. Source IP, source port, destination IP, destination port and transport layer protocol), and record which mobile app each message corresponds to according to the socket. These data are stored in files on the SD card of the mobile phone.
The information that needs to be recorded in each line of the file includes: 5-tuple information of each network socket (i.e. source IP, source port, destination IP, destination port and transport layer protocol), recording time, application name, and corresponding Events (create/destroy sockets, etc.).
#Technology 1. Recompile tcpdump and lsof into binaries suitable for Android (arm-linux-androideabi-g++)
2. Use Adapter to bind Listview, CheckBox and List<Program (custom class)>
3. Run concurrently to capture Socket and Packet, use lsof +c 0 -i -F ctPnf 2>&1
and tcpdump -v -s -w pcap
command
4. Read and parse the /proc/net/tcp, tcp6,udp,udp6
files, and use the socket inode and app's pid to establish the acquisition and correspondence between the five-tuple and the application name.
#Implementation (1) To obtain the app list, use the PackageManager to retrieve all applications and data, then use ActivityManager and PackagesInfo to obtain all app names and pids obtained from above, and display them using the listview layout.
(2) To read and parse the /proc/pid/fd file in Android, use runTime.exec(cmd); you can run the cmd command in Android, so you can use this to get the result output after running the command. Because Reading and analysis of the /proc directory requires root permissions, so runTime.exec("su"); is used to extract root permissions on Android. Then use ls -l /proc/(pid)/fd > /sdcard/fdres
to save the information to the fdres file, and then use cat /sdcard/fdres to extract the information. This is a compromise. In the obtained information, use the regular expression "socket:\S(\d+)\S"
; to extract all the inode labels of the socket and put them into the ArrayList.
(3) Reading and parsing of /proc/net/tcp, tcp6, udp, udp6 files (or use lsof +c 0 -i -F ctPnf 2>&1
command) Abstract reading of tcp, tcp6, udp, udp6 as PollData Class, use the Scanner class that comes with java to analyze and read /proc/net/tcp, etc. The output obtained is as follows
* sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid ...
* 0: 0100007F:13AD 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 ...
* 1: 00000000:15B3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 ...
* 2: 0F02000A:15B3 0202000A:CE8A 01 00000000:00000000 00:00000000 00000000 0 ...
*
Then use the socket_inode obtained above to find the corresponding specific information in the obtained information. The specific socket information obtained by converting it into decimal is as follows:
1.
2. 46: 010310AC:9C4C 030310AC:1770 01
3. | | | | | |--> connection state
4. | | | | |------> remote TCP port number
5. | | | |-------------> remote IPv4 address
6. | | |--------------------> local TCP port number
7. | |---------------------------> local IPv4 address
8. |----------------------------------> number of entry
9. 00000150:00000000 01:00000019 00000000
10. | | | | |--> number of unrecovered RTO timeouts
11. | | | |----------> number of jiffies until timer expires
12. | | |----------------> timer_active (see below)
13. | |----------------------> receive-queue
14. |-------------------------------> transmit-queue
15. 1000 0 54165785 4 cd1e6040 25 4 27 3 -1
16. | | | | | | | | | |--> slow start size threshold,
17. | | | | | | | | | or -1 if the threshold
18. | | | | | | | | | is >= 0xFFFF
19. | | | | | | | | |----> sending congestion window
20. | | | | | | | |-------> (ack.quick<<1)|ack.pingpong
21. | | | | | | |---------> Predicted tick of soft clock
22. | | | | | | (delayed ACK control data)
23. | | | | | |------------> retransmit timeout
24. | | | | |------------------> location of socket in memory
25. | | | |-----------------------> socket reference count
26. | | |-----------------------------> inode
27. | |----------------------------------> unanswered 0-window probes
28. |---------------------------------------------> uid
(4) Establish the acquisition and corresponding relationship between the quintuple and the application name. The socket inode shared by (2) and (3) and the pid of the app are used to establish the acquisition and correspondence between the quintuple and the application name. The obtained The information is saved to the default directory /sdcard/Android/data/com.xx in the format of
"The application name is, pid is, and socket is:"
"number_of_entry "+fields[i+0] + "n";
"local_IPv4_address "+fields[i+1] + "n";
"local_IPv4_address "+hexconvert.hexa2decIpAndPort(fields[i+1]) + "n";
"remote_IPv4_address "+fields[i+2] + "n";
"remote_IPv4_address "+hexconvert.hexa2decIpAndPort(fields[i+2]) + "n";
"connection_state" + fields[i+3] + "n";
"transmit_receive_queue"+ fields[i+4]+ "n";
"timer_active"+fields[i+5]+ "n";
"number_of_unrecovered_RTO_timeouts:"+fields[i+6]+ "n";
"uid: "+fields[i+7]+ "n";
"unanswered_0-window_probes: "+fields[i+8]+ "n";
"inode : "+fields[i+9]+ "n";
"socket_reference_count: "+fields[i+10]+ "n";
"location_of_socket_in_memory: "+fields[i+11]+ "n";
"retransmit_timeout: "+fields[i+12]+ "n";
"predicted_tick_of_soft_clock: "+ fields[i+13]+ "n";
"ack"+ fields[i+14]+ "n";
"sending_congestion_window: "+ fields[i+15]+ "n";
"slowstart: "+ fields[i+16]+ "nn";
(5) Upload to the server and parse using GT ProgramPython script