#요약 AndroidNetMonitor는 Android 기기에서 발생하는 세밀한 대규모 패킷 측정값을 수동적으로 모니터링, 수집 및 분석하는 시스템으로, 트래픽 소스의 실제 애플리케이션 정보를 얻고 휴대폰에서 주고받는 패킷의 간략한 정보를 수집하는 데 사용됩니다. (예: 소스 IP, 소스 포트, 대상 IP, 대상 포트 및 전송 계층 프로토콜), 소켓에 따라 각 메시지가 어떤 모바일 앱에 해당하는지 기록합니다. 이러한 데이터는 휴대폰의 SD 카드에 파일로 저장됩니다.
파일의 각 줄에 기록해야 하는 정보에는 각 네트워크 소켓의 5튜플 정보(예: 소스 IP, 소스 포트, 대상 IP, 대상 포트 및 전송 계층 프로토콜), 기록 시간, 애플리케이션 이름 및 해당 정보가 포함됩니다. 이벤트(소켓 생성/파기 등).
#기술 1. tcpdump 및 lsof를 Android에 적합한 바이너리로 다시 컴파일합니다(arm-linux-androideabi-g++).
2. Adapter를 사용하여 Listview, CheckBox 및 List<프로그램(사용자 정의 클래스)>를 바인딩합니다.
3. 동시에 실행하여 소켓과 패킷을 캡처하고 lsof +c 0 -i -F ctPnf 2>&1
및 tcpdump -v -s -w pcap
명령을 사용합니다.
4. /proc/net/tcp, tcp6,udp,udp6
파일을 읽고 구문 분석하고 소켓 inode와 앱의 pid를 사용하여 5-튜플과 애플리케이션 이름 간의 획득 및 대응을 설정합니다.
#Implementation (1) 앱 목록을 얻으려면 PackageManager를 사용하여 모든 애플리케이션과 데이터를 가져온 다음 ActivityManager 및 PackagesInfo를 사용하여 위에서 얻은 모든 앱 이름과 PID를 가져와 목록 보기 레이아웃을 사용하여 표시합니다.
(2) Android에서 /proc/pid/fd 파일을 읽고 구문 분석하려면 runTime.exec(cmd)를 사용합니다. Android에서 cmd 명령을 실행할 수 있으므로 이를 사용하여 명령 실행 후 결과 출력을 얻을 수 있습니다. /proc 디렉토리를 읽고 분석하려면 루트 권한이 필요하므로 Android에서 루트 권한을 추출하는 데 runTime.exec("su")가 사용됩니다. 그런 다음 ls -l /proc/(pid)/fd > /sdcard/fdres
사용하여 정보를 fdres 파일에 저장한 다음 cat /sdcard/fdres를 사용하여 정보를 추출합니다. 얻은 정보에서 "socket:\S(\d+)\S"
정규식을 사용하여 소켓의 모든 inode 레이블을 추출하고 이를 ArrayList에 넣습니다.
(3) /proc/net/tcp, tcp6, udp, udp6 파일 읽기 및 구문 분석(또는 lsof +c 0 -i -F ctPnf 2>&1
명령 사용) tcp, tcp6, udp, udp6을 PollData로 추상 읽기 클래스, Java와 함께 제공되는 Scanner 클래스를 사용하여 /proc/net/tcp 등을 분석하고 읽습니다. 얻은 출력은 다음과 같습니다.
* 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 ...
*
그런 다음 위에서 얻은 소켓_inode를 사용하여 얻은 정보에서 해당하는 특정 정보를 찾습니다. 이를 10진수로 변환하여 얻은 특정 소켓 정보는 다음과 같습니다.
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) quintuple과 애플리케이션 이름 간의 획득 및 대응 관계를 설정합니다. (2)와 (3)에서 공유하는 소켓 inode와 앱의 pid를 사용하여 quintuple과 애플리케이션 이름 간의 획득 및 대응 관계를 설정합니다. 획득한 정보는 기본 디렉터리인 /sdcard/Android/data/com.xx에 다음과 같은 형식으로 저장됩니다.
"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) 서버에 업로드하고 GT ProgramPython 스크립트를 사용하여 구문 분석합니다.