1. Trang chủ
  2. » Luận Văn - Báo Cáo

Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android

60 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Tác giả Nguyễn Hữu Hoàng
Người hướng dẫn PGS. TS. Quản Thành Thơ
Trường học Đại học Quốc gia Tp. HCM
Chuyên ngành Khoa học Máy tính
Thể loại Luận văn thạc sĩ
Năm xuất bản 2016
Thành phố Tp. Hồ Chí Minh
Định dạng
Số trang 60
Dung lượng 4,33 MB

Cấu trúc

  • 1.1 Lí do nghiên cứu (10)
  • 1.2 Mục tiêu nghiên cứu (11)
  • 2.1 Tổng quan về Android (12)
  • 2.2 Các dịch vụ hệ thống (14)
  • 2.3 Cấu trúc Android Package và định dạng DEX (17)
  • 3.1 Các bước xây dựng và phân tích đồ thị cuộc gọi (20)
  • 3.2 Công cụ và framework phân tích bytecode (21)
  • 3.3 Các mục đích nghiên cứu (23)
  • 3.4 Phương pháp phân tích cơ bản (25)
  • 4.1 Tổng quan hướng tiếp cận (28)
  • 4.2 Những thách thức (29)
  • 4.3 Hàm truy cập công khai (30)
  • 4.4 Hiểu về hàm hệ thống Android và kiểm tra quyền truy cập . 22 (31)
  • 5.1 Thiết lập (33)
  • 5.2 Tóm tắt kết quả (33)
  • 5.3 Thảo luận (40)
  • 8.1 Các bài báo đã công bố (48)
  • 8.2 Lý lịch trích ngang (60)

Nội dung

Những yêu cầu như vậy cần phảiđược hỗ trợ bởi các công cụ có thể hoạt động trên từng phần của hệ thống vàcác phiên bản Android khác nhau.Trong lĩnh vực phân tích tĩnh hệ thống và ứng dụn

Lí do nghiên cứu

Ra đời năm 2007, hệ điều hành Android đạt được sự phát triển nhanh chóng, năm 2016 Android đã chiếm 80% thị phần hệ điều hành di động toàn cầu [19] Hệ điều hành này có hơn 8 triệu nhà phát triển ứng dụng tính tới năm 2014 [18] Do đó, để giúp các lập trình viên, đặc biệt là những người mới làm quen, phát triển ứng dụng một cách nhanh chóng thì nắm bắt kiến trúc của hệ điều hành và tất cả các API được cung cấp là việc cần thiết Khi đó, nhà phát triển có thể hiểu được những cách thức mà hệ điều hành quản lý các ứng dụng và gọi các chức năng muốn sử dụng thông qua các API này Mặc dù kiến trúc hệ thống của Android và một số API được cung cấp tài liệu, tuy nhiên do Android được phát triển trải dài từ phiên bản 1.0 đến Nougat 7.0, vì vậy gây ra sự không tương thích trên các phiên bản và sự thiếu nhất quán giữa các hành vi của mã trong thực tế với tài liệu Ngoài ra còn có các API không được công bố trong tài liệu nhưng vẫn có thể được sử dụng từ ứng dụng, bên cạnh đó còn có những lỗi và lỗ hỏng của hệ điều hành bị các ứng dụng khai thác với mục đích xấu.

Việc hiểu hành vi của hệ thống và các API trở nên khó khăn hơn với sự phân mảnh của hệ điều hành Android: có hơn 1000 thương hiệu và hơn 24.000 loại điện thoại vào năm 2015 [38]; các nhà sản xuất tùy chỉnh hệ thống Android theo những cách khác nhau và thường không cung cấp đủ tài liệu cho lập trình viên Việc theo dõi và hiểu được mối quan hệ giữa các API của hệ thống khác nhau bằng việc đọc từng tài liệu và duyệt thủ công trên mã nguồn là rất tốn thời gian và dễ phát sinh lỗi Những yêu cầu như vậy cần phải được hỗ trợ bởi các công cụ có thể hoạt động trên từng phần của hệ thống và các phiên bản Android khác nhau.

Trong lĩnh vực phân tích tĩnh hệ thống và ứng dụng Android, có nhiều nghiên cứu tập trung vào phân tích ứng dụng Android [8, 28, 41, 47], những nghiên cứu này đòi hỏi kiến thức chuyên sâu về mô hình của hệ thống Android như vòng đời callbacks được sử dụng để quản lý các activity của ứng dụng[1], back stack được sử dụng trong hệ thống để quản lý các activity đang thực thi [2], Các mô hình chuyên sâu và thủ công như vậy không theo kịp với sự phát triển và phân mảnh của hệ thống, dẫn đến mô hình và kết quả phân tích không đủ chính xác.

Mục tiêu nghiên cứu

Mục tiêu cuối cùng của luận văn là xây dựng được một mô hình tự động cho hệ thống Android, tạo điều kiện để lập trình viên hiểu hành vi hệ thống và các API Một cách hướng tới mục tiêu này là thực hiện phân tích toàn bộ chương trình của một phiên bản Android kết hợp với một hoặc nhiều ứng dụng, nhằm tránh việc xây dựng thủ công mô hình hành vi hệ thống Android trước khi phân tích ứng dụng Phương pháp này được xem xét dựa trên nghiên cứu của Dacong Yan và các cộng sự, tuy nhiên đi kèm nhiều thách thức khi hiện thực [46].

Nghiên cứu này là bước đầu tiên để phân tích toàn bộ hệ thống Android với từng phiên bản, nhằm tự động giám sát các chức năng của hệ thống An- droid có thể được truy cập bởi các ứng dụng, cung cấp một “bản đồ điều hướng” cho những phiên bản Android khác nhau Điều này giúp người lập trình viên hiểu những chức năng có trong từng phiên bản Android, có thể được gọi bằng các API Chúng tôi phân tích trên 6 phiên bản Android: 4.1.1,4.2.2, 4.3, 4.4.4, 5.1.0, 6.0.1 và phân tách các hàm public từ các phiên bản này Số lượng các hàm public và kích thước mã nguồn Android tăng dần lên qua từng phiên bản, từ khoảng 53.000 ở phiên bản 4.1.1 lên 74.000 ở phiên bản 6.0.1 Cùng với những phân tích khác (ví dụ như việc thêm vào các kiểm tra permission nhằm ngăn chặn truy cập vào các hàm public một cách trái phép, phân tách các hàm public phụ thuộc vào dữ liệu từ ứng dụng), cách tiếp cận này ngoài việc giúp nhà phát triển hiểu được chức năng hệ thống và các API, đồng thời giúp tìm ra các API trong hệ thống không được bảo vệ có thể dẫn đến rò rỉ bảo mật và sự riêng tư trong Android.

Tổng quan về Android

Android là một hệ điều hành mã nguồn mở dựa trên Linux, được phát hành bởi Google vào năm 2007 [37], ban đầu Android được xây dựng trên bộ vi xử lý nền tảng ARM, sau này mở rộng lên cả Intel x86, MIPS Do được xây dựng dựa trên nền tảng Linux, nó cho phép truy cập vào thiết bị thông qua các Linux shell cũng như thực thi các lệnh cơ bản của Unix.

Hình 1: Tổng quan kiến trúc Android [45]

Android Java, máy ảo Dalvik và Android Runtime

Về cơ bản, Dalvik là máy ảo Java của Android Nó cho phép Android chạy bytecode được tạo ra từ các ứng dụng trên nền Java bao gồm cả các thành phần riêng của hệ thống Android, đồng thời cung cấp các hook cần thiết và môi trường giao tiếp với phần còn lại của hệ thống bao gồm cả các thư viện bản địa (native libraries) và các native user-space.

Từ phiên bản Android 4.4 trở về trước, mã nguồn Java của hệ thống An- droid và các ứng dụng của nhà phát triển được biên dịch thành Dalvik byte- code (định dạng DEX) để thực thi trên kiến trúc máy ảo Dalvik (Dalvik Vir- tual Machine - DVM) DVM được tối ưu hóa cho một CPU di động, chậm hơn CPU một máy tính cá nhân, và hoạt động với bộ nhớ RAM tương đối nhỏ khoảng 20MB sau khi các dịch vụ hệ thống cao cấp đã được khởi động [14].

Khác với máy ảo Java thông thường (Java Virtual Machine - JVM), DVM dựa trên register-based thay vì stack-based DVM được thiết kế để nhân rộng một cách nhanh chóng vì mỗi ứng dụng chạy trong một “sandbox”, một dạng con- text có chứa instance riêng được máy ảo gắn cho một định danh người dùng Unix (Unix user ID) đặc biệt.

Năm 2013, Google lần đầu tiên giới thiệu kiến trúc Android Runtime(ART) thay thế cho kiến trúc Dalvik cũ trước đó, đây là một bước tiến quan trọng trong việc tối ưu hóa phần cứng, cũng như tăng tốc độ thực thi cho ứng dụng Android Từ phiên bản Android 5.0 trở về sau, DVM đã hoàn toàn được thay thế bởi ART Nếu DVM sử dụng Just-In-Time (JIT) để thông dịch các ứng dụng mỗi khi chạy (JIT chuyển đổi bytecode thành mã máy) làm hiệu suất của ứng dụng bị giảm, thì ART giải quyết vấn đề đó với Ahead-Of-Time(AOT) Khi ứng dụng lần đầu được cài đặt vào máy, Dalvik bytecode sẽ đượcART biên dịch một lần duy nhất thành mã máy (định dạng ELF của Linux)[17], điều này giúp loại bỏ thời gian chuyển đổi của JIT Một số ưu điểm củaART là cải thiện hiệu năng hệ thống, giúp việc khởi động và thực thi các ứng dụng trở nên nhanh chóng hơn, tăng tuổi thọ pin và hỗ trợ phần cứng tốt hơn,tuy nhiên cũng có một số nhược điểm như tăng không gian lữu trữ cho mỗi ứng dụng từ 10-20% và thời gian cài đặt ứng dụng cũng lâu hơn.

Bên cạnh DVM và ART, mã viết bằng Java đôi khi cũng cần phải giao tiếp với mã ngôn ngữ khác để có thể sử dụng các chức năng cấp thấp (low- level), điều này đặc biệt đúng với một môi trường nhúng như Android Do đó, Android cung cấp cơ chế Java Native Interface (JNI) Về bản chất đây là một cầu nối cuộc gọi đến các ngôn ngữ khác như C và C++, nó tương tự nhưP/Invoke trong thế giới NET/C#.

Các dịch vụ hệ thống

Trong Embedded Android, Karim Yaghmour đã mô tả tương đối đầy đủ về các dịch vụ hệ thống (system services) của Android [45] Các dịch vụ hệ thống là một điểm khá nhiều thú vị của Android, thậm chí Google không đề cập đến nó một cách rõ ràng trong các tài liệu phát triển ứng dụng của họ Có khoảng từ 50 đến 70 dịch vụ hệ thống, những dịch vụ này kết hợp với nhau để cung cấp những gì cơ bản nhất cho hệ điều hành hướng đối tượng xây dựng trên nhân Linux này.

Hình 2: Các dịch vụ hệ thống [45]

Hình 2 là một vài dịch vụ chính có liên quan trong thực tế Nổi bật nhất là System Server, có các thành phần dịch vụ chính chạy cùng một tiến trình gọi là system_server System Server chủ yếu được tạo thành từ hai dịch vụ trên nền C/C++ và phần lớn các dịch vụ sử dụng Java quan trọng như Activ- ity Manager, Window Manager, Package Manager, Notification Manager,

System Server cũng bao gồm một số mã truy cập thông quan JNI để dựa vào Java để giao tiếp với các lớp thấp hơn của Android Bên cạnh là một số dịch vụ truyền thông được đặt trong Media Server, những dịch vụ này đều được viết bằng C/C++ Cuối cùng là các dịch vụ điện thoại nằm độc lập với các dịch vụ khác.

Phạm vi nghiên cứu của luận văn là tập trung vào việc xây dựng và phân tích các luồng điều khiển cuộc gọi giữa những dịch vụ hệ thống Java-build với nhau.

Cơ chế khởi động của hệ thống Android và ứng dụng

Hình 3: Trình tự khởi động của Android [45]

Hình 3 mô tả cơ chế khởi động của hệ thống Android và ứng dụng.

CPU bắt đầu khởi động, kế đến là Bootloader sẽ thiết lập cho RAM, tải lên Kernel Tại Kernel sẽ thiết lập các driver và tiến trình cơ bản của hệ điều hành, đồng thời bắt đầu các daemon cơ bản như servicemanager, medi- aserver, bootanimation, adbd, keystore, app_process, Trong đó quan trọng nhất làapp_process -X Zygote, lệnh này sẽ khởi động Android Runtime, khi runtime khởi động sẽ gọi hàm main của Zygote và Dalvik VM (với Android 4.4 trở về trước).

Zygote chỉ kích hoạt khi có một ứng dụng mới cần khởi động Để ứng dụng khởi động nhanh hơn, Zygote bắt đầu bằng cách nạp trước tất cả các lớp Java và tài nguyên mà ứng dụng cần khi chạy Zygote luôn lắng nghe yêu cầu khởi động một ứng dụng mới ở socket /dev/socket/zygote.

Mặc dù, Zygote được thiết kế để lắng nghe các yêu cầu khởi động từ ứng dụng, nhưng có một ứng dụng đặc biệt mà Zygote khởi động trực tiếp đó là System Server Đây là ứng dụng được khởi động đầu tiên từ Zygote và nó vẫn tiếp tục tồn tại như một tiến trình độc lập với cha mẹ System Server bắt đầu khởi tạo các dịch vụ hệ thống và đăng ký các dịch vụ đó với Service Manager được khởi động trước đó Một trong những dịch vụ mà nó khởi tạo là Activity Manager, việc khởi tạo kết thúc bằng cách gửi một intent loại Intent.CATEGORY_HOME Đây chính là lúc ứng dụng Launcher cơ bản với màn hình chính quen thuộc của tất cả người dùng Android được khởi động.

Khi người dùng bấm vào một biểu tượng của ứng dụng trên màn hình chính, Launcher sẽ yêu cầu Activity Manager bắt đầu một tiến trình chuyển yêu cầu tới Zygote, nó sẽ kích hoạt chính nó và bắt đầu ứng dụng mà người dùng chọn sau đó hiển thị lên màn hình thiết bị của người dùng.

Tóm lại, có thể hiểu Zygote và System Server nắm giữ phần lớn hệ thống hoạt động của hệ thống Android và ứng dụng, đây chính là trọng tâm của nghiên cứu đã được nhắc đến ở phần 2.2, sẽ được trình bày chi tiết ở phần 4 và 5.

Cấu trúc Android Package và định dạng DEX

Một ứng dụng Android được cài đặt vào thiết bị thông qua một tập tin có định dạng là APK Tập tin Android Package hay APK về cơ bản là một gói ZIP chứa các tập tin mô tả, tài nguyên, thư viện và tập tin classes.dex chứa Dalvik bytecode của ứng dụng Android.

Nội dung mỗi tập tin APK thì khác nhau tùy thuộc vào mục đích ứng dụng được tạo ra Tuy nhiên, cấu trúc trình bày ở đây là một vài thành phần quan trọng của ứng dụng Android.

CERT.RSA Chứng chỉ của ứng dụng Để được chấp nhận cho việc cài đặt, một tập tin APK phải có chữ ký kỹ thuật số được khóa bởi một khóa riêng (private key) của nhà phát triển ứng dụng.

CERT.SF Tập tin chứa danh sách các tài nguyên của ứng dụng được mã hóa bằng SHA-1.

MANIFEST.SF Tập tin manifest của ứng dụng. res chứa các tài nguyên của ứng dụng như hình ảnh, âm thanh,

AndroidManifest.xmlMột tập tin nhị phân khai báo các thành phần và quyền của ứng dụng khi thực thi trong hệ thống. classes.dex Chứa các lớp của ứng dụng dưới dạng Dalvik Excutable bytecode Đây là thành phần quan trọng nhất của tập tin APK. resources.arsc Chứa các tài nguyên tiền biên dịch của ứng dụng.

Bên cạnh đó, mỗi ứng dụng thường có một thư mụclibchứa các mã native tiền biên dịch của một kiến trúc vi xử lý như ARM, x86, MIPS,

Các dịch vụ hệ thống (system services) của Android không được lưu dưới định dạng APK mà lưu dưới định dạng JAR nhưng bên trong vẫn chứa classes.dexhayMETA-INFtương tự như một tập tin APK Những dịch vụ này thường nằm trong thư mục/system/framework.

2 CƠ SỞ LÝ THUYẾT Định dạng DEX

Tập tin classes.dex là thành phần quan trọng nhất của một chương trình Android kể cả ứng dụng thông thường hay một dịch vụ hệ thống Do đó, nghiên cứu định dạng DEX cùng với cấu trúc của Dalvik opcode có liên quan chặt chẽ với những công cụ hỗ trợ phân tích bytecode hiệu quả Ngoài ra, việc gây rối rắm cho ứng dụng (obfuscation) cũng được khai thác trên tập tinclasses.dexnhưng nằm ngoài phạm vi nghiên cứu của luận văn này.

So sánh bytecode thông thường của Java và Dalvik, có thể nhận thấy nó tối ưu hóa không gian dựa trên việc chia sẻ dữ liệu Bộ nhớ được lưu bằng cách đảm bảo dữ liệu được lặp lại tối thiểu, áp dụng implicit typing và labeling.

Hình 4: Cấu trúc của tập tin class và dex [27]

Hình 4 mô tả cấu trúc tập tin dex và so sánh một tập tin nén JAR thông thường chứa các tập tin class với một tập tin APK chứa các class tương tự nhưng được đóng gói thành một tập tin duy nhất dex Mỗi tập tin class có heterogeneous constant pool chứa các dữ liệu bị duplicate.

Ví dụ, có nhiều phương thức với nhiều biến trả về kiểu String, thì kết quả sẽ lặp lại java.lang.String cho mỗi dấu hiệu của từng phương thức (method’s signature) Tập tin dex lưu trữ bộ nhớ hiệu quả chủ yếu từ việc lưu dữ liệu của các type-specific constant pool Như ví dụ trên, hằng số java.lang.String sẽ được hiện diện duy nhất một lần ở type_ids pool và sẽ được tham chiếu bởi mỗi phương thức dùng nó Một tập tin dex có số lượng tham chiếu nhiều đáng kể so với một file.class Việc thiết kế tối ưu này của.dexvẫn đảm bảo chi tiết dữ liệu và cho phép nén một cách hiệu quả lên đến 44% khi so sánh với kích thước một tập tin nén.jar[16].

Như đã trình bày, DVM là một register-based Các register có 32 bit để lưu các giá trị lớn như số interger hay dấu chấm động Cặp thanh ghi liền kề được sử dụng để lưu giá trị 64 bit Không có yêu cầu liên kết giữa các cặp thanh ghi [4] Nếu một phương thức có đối số N, nó đặt theo thứ tự từ cuối của N thanh ghi trong khung gọi (invocation frame) phương thức [6] Các introduction tương ứng của phương thức này được định dạng theo trật tự từ cuối tới đầu cho các đối số của chính nó Trong suốt quá trình cài đặt và tối ưu hóa, một số introduction có thể thay đổi Tổng cộng có 218 opcode trong Dalvik bytecode [4, 5].

Việc hiểu cấu trúc Android Package và đặc biệt định dạng DEX là điều kiện cần thiết cho việc chuyển đổi Dalvik bytecode thành một biểu diễn trung gian (intermediate representation) trước khi xây dựng đồ thị luồng điều khiển (control flow graph - CFG) cho hệ thống cũng như chương trình Android. Đồ thị luồng điều khiển là một đồ thị biễu diễn tất cả các đường đi có thể được đi qua trong quá trình thực thi của một chương trình.

Việc phân tích mã thực thi Java bytecode không phải là mới trong lĩnh vực công nghệ nhưng các ứng dụng Android tuy được phát triển bằng ngôn ngữ Java lại có sự khác biệt giữa bytecode Java thông thường với Dalvik như đã trình bày ở phần 2.3 Các nghiên cứu phân tích Java bytecode nếu không cải tiến và cập nhật hỗ trợ thêm Dalvik thì không hoạt động được trực tiếp trên mã thực thi của Android cụ thể như WALA framework.

Các bước xây dựng và phân tích đồ thị cuộc gọi

Đầu tiên, phải nói đến các kỹ thuật biên dịch, có hai phương pháp trong kỹ thuật biên dịch ngược [31]:phương pháp quét tuyến tính (linear sweep) và phương pháp duyệt đệ quy(recursive traversal) Nếu phương pháp quét tuyến tính là giải mã các byte thành câu lệnh hợp ngữ tuần tự từ đầu đến cuối thì phương pháp duyệt đệ quy lại bắt đầu từ điểm vào của ứng dụng, lần theo các nhánh và sử dụng kỹ thuật tìm kiếm theo chiều sâu (depth first search) để giải mã ứng dụng.

Kế đến, về cách xây dựng và phân tích đồ thị cuộc gọi cho Android có khá nhiều cách tiếp cận nhưng đều tập trung vào nguyên lý mô tả ở hình 5:

• Bước 1: Giải nén (decompression) tập tin apkđối với ứng dụng An- droid hoặc tập tin jarđối với các dịch vụ hệ thống Android.

• Bước 2: Dịch ngược (dissasembly) tập tinclasses.dexchứa Dalvik bytecode.

• Bước 3: Biểu diễn trung gian (intermediate representation - IR) thông qua biểu diễn bytecode (bytecode representation) kết quả bước 2.

• Bước 4: Xây dựng đồ thị cuộc gọi (call graph - CG) từ các IR bước 3.

• Bước 5: Áp dụng các kỹ thuật phân tích tĩnh dựa trên CG được xây dựng ở bước 4.

• Bước 6: Phân tích kết quả thu được ở bước 5.

Hình 5: Các bước xây dựng và phân tích đồ thị cuộc gọi của Android Đồ thị cuộc gọi là một đồ thị luồng điều khiển, đại diện cho mối quan hệ cuộc gọi giữa các chương trình con (subroutines) trong một chương trình máy tính (computer program).

Công cụ và framework phân tích bytecode

Về phía công nghiệp, phần lớn các dự án nghiên cứu trên Android chỉ dừng lại ở mức độ dịch ngược Dalvik bytecode thành hợp ngữ hoặc biểu diễn trung gian Các nghiên cứu này tập trung cho việc tinh chỉnh và phân tích các tập tin APK ở mức cơ bản.

• dexdump [3] Là một phần của Android SDK, đây là công cụ đơn giản nhất để thực hiện việc biên dịch ngược Dalvik bytecode Công cụ này dùng thuật toán quét tuyến tính (linear sweep) trên từng bytecode để phân tích.

• dex2jar [39] Một công cụ chuyển đổi bytecode của Dalvik thành Java,nhưng hạn chế của công cụ là khả năng khôi phục mã không cao, gây

• baksmali [22] Một trong những công cụ biên dịch ngược Dalvik phổ biến nhất trên thế giới Nó sử dụng các thuật toán phức tạp, duyệt đệ quy và khả năng phục hồi của baksmali tốt hơn các công cụ khác Một trong những kế thừa xuất sắc nhất của baksmali là apktool.

• IDA Pro [23] Là phần mềm thương mại, IDA Pro từ phiên bản 6.6 đã hỗ trợ phân tích ứng dụng Android từ Dalvik bytecode và đưa ra được luồng thực thi cơ bản của ứng dụng, tuy nhiên hạn chế của công cụ này là vấn đề chi phí bản quyền lớn, không hỗ trợ việc xây dựng và phân tích đồ thị luồng điều khiển (CFG) cho nhiều ứng dụng đồng thời Ngoài ra do là phần mềm thương mại nên IDA chỉ cung cấp một số API cho việc phát triển các plugin nên hạn chế cho việc mở rộng nghiên cứu.

Về phía học thuật, hai hướng chính trong việc phân tích mã nhị phân là phân tích tĩnh (static analysis) và phân tích động (dynamic analysis), mỗi hướng có những ưu và khuyết điểm riêng Như phân tích động có thời gian thực hiện ngắn hơn, nhưng chương trình phải thực thi trong một môi trường ảo, các ngữ cảnh được giả lập có thể không đầy đủ tất cả trạng thái của chương trình Còn với phân tích tĩnh có ưu điểm là bao hàm được hết các trạng thái của chương trình, nhưng chính điều này lại cũng chính là hạn chế do sự bùng nổ về không gian trạng thái Nghiên cứu này chỉ giới hạn trong hướng phân tích tĩnh cho hệ thống và ứng dụng Android.

Có hai framework nổi tiếng trong giới học thuật về phân tích tĩnh bytecode là WALA và Soot.

• WALA [15] Là một framework dùng để phân tích tĩnh mã thực thi của Java và Javascript Một số chức năng chính của framework này là xây dựng CFG, hỗ trợ luồng dữ liệu (data flow) interprocedural và context- sensitive Một hạn chế của WALA là không hỗ trợ trực tiếp Dalvik bytecode nên để sử dụng được framework này với ứng dụng Android đòi hỏi phải tự thực hiện quá trình chuyển đổi thành WALA IR.

• Soot [44] Được tạo ra bởi Raja Vallée-Rai vào năm 2000, qua thời gian trở thành một framework hiệu quả cho việc phân tích tĩnh Java bytecode Soot dùng phương pháp tuyến tính để chuyển đổi bytecode thành biểu diễu trung gian Jimple Năm 2012, Bartel và các cộng sự đã phát triểnDexplergiúp chuyển đối Dalvik bytecode của Android thành Jimple IR của Soot [12], với những đóng góp đó, Dexpler đã được tích hợp như một thành phần của Soot, chính điều này giúp Soot có thể phân tích được mã Dalvik bytecode một cách hiệu quả Framework này được dùng cho việc xây dựng CFG, phân tích điểm (points-to analysis), đồng thời hỗ trợ phân tích luồng dữ liệu cả intra-procedural lẫn inter- procedural.

Với những ưu điểm của mình, Soot đã được lựa chọn làm nền tảng cho việc xây dựng và phân tích CFG của luận văn này. Đồ thị luồng dữ diệu hay luồng dữ liệu là một đồ thị biểu diễn sự phụ thuộc dữ liệu giữa một số phương thức trong một chương trình.

Các mục đích nghiên cứu

Một số vấn đề lớn được khai thác theo hướng phân tích tĩnh mã nhị phân Android bao gồm:

Rò rỉ dữ liệu riêng tư

Cùng với sự phát triển của ứng dụng Android, vấn đề dữ liệu riêng tư được tập trung nghiên cứu FlowDroid [8] được Steven Arzt và các cộng sự giới thiệu năm 2014 là một phương pháp hiệu quả cho phân tích rò rỉ dữ liệu riêng tư Nghiên cứu thực hiện phân tích vế bẩn (taint analysis) cho ứng dụng Android với các nhạy cảm (sensitive) flow-, context-, field-, object- và bao gồm cả phân tích flow-, lifecycle-, static-, alias-aware, nên cách tiếp cận này có độ chính xác cao Do FlowDroid mã nguồn mở nên đã được kế thừa trên một số nghiên cứu mở rộng để tăng chính xác cho kết quả phân tích[42, 26, 10, 29, 28].

Lỗ hỏng bảo mật luôn là một vấn đề cần được quan tâm, người dùng cần phải được bảo vệ tránh khỏi các phần mềm độc hại khai thác dữ liệu với mục đích xấu như truy cập trái phép vào các nguồn tài nguyên riêng tư hay cần bảo vệ thông qua các thành phần dễ tổn thương của ứng dụng hoặc tiêm mã độc để thao tác dữ liệu đầu vào với các mục đích riêng Các nghiên cứu nổi bật theo hướng này như CHEX [33] phát hiện luồng rò rỉ bảo mật dựa trên một đồ thị hệ thống phụ thuộc, Epicc [36] và IC3 [35] đề xuất kỹ thuật phân tích tĩnh để phát hiện ngữ cảnh của các lỗ hỏng liên thành phần (inter-component vulnerabilities) Trên cơ sở đó, PCLeaks [29] thực hiện phân tích luồng dữ liệu nhạy cảm trên các lỗ hỏng thành phần đó, cho phép nó không chỉ giúp biết vấn đề là gì mà còn biết những dữ liệu nhạy cảm sẽ bị rò rỉ thông qua đó.

Kiểm tra quyền sử dụng là một trụ cột trong vấn đề về bảo mật của An- droid Mô hình quyền sử dụng của Android có chép liên kết đến các tài nguyên nhạy cảm với một tập hợp các quyền phải có để có thể truy cập Tuy nhiên, nghiên cứu của Bartel và các cộng sự chỉ ra mô hình quyền sử dụng này có những rủi ro, từ các ứng dụng được cấp thêm nhiều quyền mà họ thực sự cần [13] Mã độc có thể lợi dụng điểm này để đạt được mục đích gây hại.

PSCount [9] cũng thực hiện nghiên cứu với phương pháp bóc tách các đặc điểm kỹ thuật của Android dựa trên phân tích tĩnh mã nguồn hệ điều hành Android.

Nhìn chung, các nghiên cứu hiện có phần lớn tập trung vào việc phân tíchDalvik bytecode trên từng ứng dụng Android riêng rẽ, các hướng nghiên cứu này có ưu điểm về thời gian thực thi và phân tích nhanh nhưng lại không khai thác một cách đầy đủ quá trình vận hành của ứng dụng với hệ thống, đặc biệt là các điểm giao tiếp giữa hệ thống và ứng dụng, đây là những hạn chế của các nhóm đi trước Nghiên cứu của luận văn này, dựa vào CFG của hệ thống và ứng dụng Android, từ đó kết hợp với các thuật toán phân tích luồng dữ liệu nhằm tìm ra các điểm giao tiếp kể trên Đây là tiền đề cho việc phát hiện các lỗ hỏng của hệ thống Android và ứng dụng, đồng thời kiểm tra được vấn đề cấp quyền sử dụng Bên cạnh đó, dựa vào nghiên cứu có thể xây dựng mộtCFG hoàn chỉnh gồm hệ thống Android và nhiều ứng dụng đồng thời, từ đó giải quyết các vấn đề bảo mật trên đa ứng dụng.

Phương pháp phân tích cơ bản

Mỗi nghiên cứu đều có những công nghệ và phương pháp riêng để đạt được mục tiêu của mình Tuy nhiên tổng hợp lại có một số phương pháp cơ bản như:

Mô tả trừu tượng (abstract interpretation) là một lý thuyết xấp xỉ ngữ nghĩa của chương trình, tính đúng đắn của việc phân tích phải được đảm bảo nhằm tránh các kết quả âm tính (negative results) Một hiện thực cụ thể của mô tả trừu tượng là thông qua việc phân tích chương trình hình thức (formal program) Một vài ví dụ như Julia [40] sử dụng phương pháp này để thực hiện các phân tích tĩnh ứng dụng Java và Android cho việc kiểm thử phần mềm nhằm tăng cao chất lượng sản phẩm hay ScanDal [25] dùng mô tả trừu tượng để phát hiện rò rỉ riêng tư cho ứng dụng Android.

Phân tích vết bẩn (taint analysis) là gồm hai bước, đầu tiên là định nghĩa các thành phần nhạy cảm và tạo một tập hợp dữ liệu các vết bẩn, sau đó kiểm tra nó dựa trên phân tích luồng dữ liệu Nếu luồng dữ liệu bẩn dẫn đến một điểm không được phép, các hướng dẫn cụ thể sẽ được áp dụng như dừng hành vi và đưa ra cảnh cáo Ví dụ như AppSealer [49], khi dữ liệu bẩn vi phạm các chính sách đã định trước, nó sẽ ngăn cản và đưa ra cảnh báo với người dùng qua một pop-up thông báo Một ví dụ khác là FlowDroid [8] thực hiện phân tích tĩnh vết bẩn để phát hiện rò rỉ dữ liệu nhạy cảm như đã trình bày ở phần 3.3 FlowDroid dự trên một tập hợp có sẵn các phương thức source và sink được trích rút từ Android SDK (dữ liệu này xây dựng trên nghiên

3 NGHIÊN CỨU LIÊN QUAN được cảnh báo nếu dữ liệu này bắt đầu từ các phương thức source (những dữ liệu nhiễm độc) và cuối cùng có luồng chảy vào các phương thức sink (vi phạm chính sách bảo mật).

Thực thi tượng trưng (symbolic execution) là một hướng tiếp cận tạo giả sử đầu vào cho chương trình, phương pháp này có nhiều khác biệt với mô tả trừu tượng Bởi vì nó giả định các giá trị đầu vào hơn là có được đầu vào thực tế như mô tả trừu tượng thực hiện Một ví dụ như AppIntent [48] sử dụng thực thi tượng trưng để xây dựng một chuỗi các thao tác trên giao diện người dùng dẫn đến việc truyền dữ liệu Nếu chỉ dựa trên các thực thi tượng trưng đơn giản thì quá tốn thời gian cho nhiều ứng dụng Android, do đó AppIntent đề ra một số mô hình thực thi độc đáo để giảm không gian tìm kiếm mà không phải hi sinh code coverage.

Chia nhỏ chương trình (program slicing) đã được sử dụng như một phương pháp phổ biến trong lĩnh vực phân tích nhằm làm giảm một số hành vi chương trình, mà nếu có giữ chúng cũng không làm thay đổi hành vi chương trình cần phân tích Như cho một biến v trong chương trình p, một phần chia nhỏ có thể bao gồm tất cả các câu lệnh trong pbị ảnh hưởng bởi giá trị của v Bằng phương pháp này Hoffmann và các cộng sự giới thiệu một framework gọi là SAAF [24] tạo ra các lát cắt của chương trình nhằm phân tích luồng dữ liệu chảy ngược (backward data-flow) để theo dõi các giá trị tham số của một phương thức Android nhất định. Đo đạc mã

Trong phân tích tĩnh, đo đạc mã (code instrumentation) thường được sử dụng để giải quyết một số vấn đề phức tạp như giao tiếp liên thành phần(inter-component communication), phản xạ (reflection), Steve Arzt và các cộng sự đã giới thiệu một số phương tiện để đo đạc các ứng dụng Android[7], trong đó họ minh hoạ Soot là một framework hiệu quả hỗ trợ cho việc đo đạc các ứng dụng Android IccTA [30] sử dụng phương pháp đo đạc mã để làm giảm vấn đề lan truyền vết bẩn liên thành phần (inter-component taint propagation) trở thành một vấn đề nội thành phần (intra-component).

Kiểm tra mô hình và kiểm tra loại

Kiểm tra mô hình (model checking) và kiểm tra loại (type checking) là hai hướng tiếp cận phổ biến của kiểm thử chương trình (program verification).

Nếu kiểm tra loại thường dựa trên cú pháp (syntactic) và mô dun (modular) thì kiểm tra mô hình thường được định nghĩa trong một ngữ nghĩa (semantic) hay toàn bộ chương trình (whole-program) Trên thực tế, sự khác biệt này làm cho hai cách tiếp cận này bổ sung cho nhau: kiểm tra loại thì tốt cho việc giải thích tại sao một chương trình được chấp nhận, còn kiểm tra mô hình lại tốt cho việc giải thích tại sao một chương trình bị từ chối Ví dụ như COVERT [11], đầu tiên trích rút các đặc điểm bảo mật từ một ứng dụng sau đó áp dụng kiểm tra mô hình để xác minh ứng dụng đang phân tích có an toàn hay không.

Còn với kiểm tra loại, Cassandra [32] cho phép người dùng thiết bị di động kiểm tra xem các ứng dụng Android có đáp ứng đủ các yêu cầu về quyền riêng tư trước khi cài đặt các ứng dụng này.

Tổng quan hướng tiếp cận

(1) Construction of call graphs and control‐flow graphs

(2) Understanding publicly accessible functions (Intra‐ and inter‐procedural control‐ and data‐flow analysis) SystemServer.main

(3) Application on verifying permission checks for system APIs Relations among objects and functions

Hình 6: Tổng quan hướng tiếp cận

Về cơ bản, ý tưởng nghiên cứu của luận văn này được xây dựng trên 3 bước chính như hình 6.

• Bước 1: Thu thập mã của mỗi phiên bản Android, xác định tất cả các lớp Java có liên quan, xây dựng đồ thị cuộc gọi cho toàn bộ dịch vụ hệ thống Android từ điểm vào chính của hệ thống (com.android.server.

• Bước 2: Xác định các hàm có khả năng tiếp cận công khai (publicly accessible functions), và sử dụng kết hợp phân tích luồng dữ liệu với luồng điều khiển trên đồ thị cuộc gọi (callgraph) nhằm xác định các đối tượng và hàm khác cần thiết cho việc thực hiện cuộc gọi đến mỗi hàm public Việc phân tích này nhằm xây dựng thông tin về sự phụ thuộc lẫn nhau giữa các đối tượng và hàm Đồng thời chỉ ra các đường đi trong mã liên kết các yếu tố phụ thuộc lại với nhau.

• Bước 3: Phân tích các phụ thuộc và đường đi ở bước 2.

Dựa thông tin thu được ở bước 2, với các phụ thuộc và đường đi đó, nghiên cứu có thể kiểm tra những hàmpublic được bảo vệ bởi hệ thống (ví dụ như đoạn mã mẫu trong hình 6 cho thấy hàm getDeviceId được bảo vệ bởi quyền truy cập READ_PHONE_STATE) và phát hiện các API của hệ thống dùng để truy xuất vào hệ thống hay các tài nguyên riêng tư mà không cần kiểm tra quyền truy cập, những API hệ thống như vậy có thể được gọi từ các ứng dụng nhưng không cần quyền truy cập, gây ra các vấn đề về bảo mật và quyền riêng tư Đồng thời, từ các thông tin ở bước 2 có thể dùng để xây dựng một tập hợp các hàm public có dữ liệu phụ thuộc vào ứng dụng, những hàm này chính là các điểm giao tiếp giữa hệ thống và ứng dụng đã trình bày ở phần 3.3.

Những thách thức

Chương trình Android có thể hiểu là một dạng mở rộng sử dụng lập trình hướng sự kiện (event-driven programming), các listener được đăng ký để kích hoạt các loại cuộc gọi nhằm xử lý thông điệp Bên cạnh đó, các broadcast hay intent có thể được gởi qua lại bởi cả hệ thống và ứng dụng để gọi các hàm khác nhau dựa trên các intent tương ứng Android cũng hỗ trợ định nghĩa các cuộc gọi và intent thông qua các tập tin cấu hình XML, đây chính là một thách thức cho việc xây dựng đồ thị cuộc gọi tĩnh một cách chính xác Trong phạm vi nghiên cứu của luận văn không giải quyết những thách thức kể trên, thay vào đó chúng tôi dựa vào khả năng hiện có của Soot để xây dựng đồ thị cuộc gọi bắt đầu từSystemServer.main().

Ngoài ra, việc xây dựng đồ thị cuộc gọi cho các dịch vụ hệ thống Android đối mặt với nhiều thách thức công nghệ khác Một trong số đó là sự khác biệt giữa chương trình Java với Android, ví dụ như Java reflection thường dùng để nạp một cách tự động các lớp và phương thức mà không cần phân tích chuỗi chính xác của tên phương thức được nạp Chúng tôi dựa trên khả năng phân tích tĩnh của Soot framework [43] và một số mở rộng để giải quyết vấn đề này.

Bên cạnh đó, với một hệ thống lớn và được xây dựng qua nhiều năm nhưAndroid cũng xuất hiện một thách thức khác là kích thước đồ thị cuộc gọi khá lớn (khoảng trên 1 triệu cạnh và hơn 50 ngàn đỉnh) như hình 7, điều này gây khó khăn cho đưa việc dữ liệu đồ thị từ tập tin lên bộ nhớ, cũng như áp dụng những giải thuật tìm đường và các công nghệ không tối ưu với đồ thị lớn Để giải quyết bài toán này chúng tôi sử dụng một thư viện trung gian cho việc

4 HƯỚNG TIẾP CẬN phân tích đồ thị là NetworkX [34], dump đồ thị từ bộ nhớ thành một dạng tập tin có cấu trúc đặc biệt pickle của thư viện, điều này giúp cải thiện đáng kể thời gian truy xuất đồ thị.

Hình 7: Đồ thị cuộc gọi tất cả dịch vụ hệ thống Android

Hàm truy cập công khai

Điều kiện cơ bản cho một hàm trong hệ thống Android có thể truy cập công khai là hàm đó phải là một phương thức Java Ngoài ra, điều kiện thứ hai phức tạp hơn là một hàm gọi một hàm truy cập công khai cũng là một hàm truy cập công khai hoặc có thể được xây dựng một cách dễ dàng Để kiểm tra xem một hàm có thỏa mãn hai điều kiện đó, nghiên cứu phải thực hiện đệ quy kiểm tra tất cả các đối tượng liên quan và các hàm có thể truy cập công khai, trong đó chủ yếu là phân tích luồng dữ liệu ngược với một bộ lọc áp dụng một số heuristic dựa trên cách lập trình và đặt tên quy ước.

Ví dụ, một đối tượng kiểu Tthì cần được gọi bởi một hàmpublictên là f, sau đó cần phải kiểm tra constructor của T hoặc một instance của T có thể trả về thông qua một vài hàmgetter 1 xem có phải là truy cập công khai Nếu constructor hoặc getter của hàm đòi hỏi các thông số để gọi, kiểm tra đệ quy được thực hiện.

1 Ví dụ như một hàm tên getSomething trả về giá trị kiểu T; những heuristic này tuy không hoàn chỉnh nhưng làm đơn giản hơn việc phân tích. Để đơn giản việc phân tích và nhận kết quả sơ bộ, nghiên cứu này xem xét một hàm là truy cập công khai như là một hàm public Thêm vào đó, có một số hàm truy cập công khai trong hệ thống (khoảng 38–43%) không thể truy cập bằng đồ thị cuộc gọi với lối vào là SystemServer.main() Đối với những hàm này chúng tôi xem xét như là những hàm không được gọi bởi hệ thống và có nhiều khả năng được thiết kế để ứng dụng sử dụng Tóm lại,chúng tôi xem xét các hàm là truy cập công khai miễn nó thỏa mãn các điều kiện nêu trên và là hàmpublic.

Hiểu về hàm hệ thống Android và kiểm tra quyền truy cập 22

Chúng tôi xem xét ba loại thông tin có thể hữu ích trong việc tìm hiểu một hàm truy cập công khai nếu lập trình viên muốn gọi nó đúng cách:

(1) Thông tin về tất cả sự phụ thuộc bao gồm cả đối tượng và những hàm cần thiết trước khigọi hàm.

(2) Thông tin về những gì xảy ra bao gồm các đối tượng bị ảnh hưởng và những hàm được gọi sau khihàm ban đầu được gọi.

(3) Thông tin về những gì xảy ra bao gồm các đối tượng bị ảnh hưởng và những hàm được gọi bên trong hàm ban đầu.

Mục (1) có thể thu thập được bằng cách sử dụng phân tích luồng dữ liệu ngược để xác định các đối tượng và các hàm mà lập trình viên cần phải xây dựng hoặc trước khi gọi hàm Mục (2) có thể thu thập bởi một phân tích tác động luồng điều khiển và luồng dữ liệu theo hướng tới, cùng với một phân tích chẩn đoán dựa trên tên đối tượng và hàm, để xác định các đối tượng và chức năng bị ảnh hưởng bên ngoài Mục (3) có thể thu tập bởi một phân tích tác động tương tự, nhưng tập trung vào các hoạt động bên trong một hàm và có thể cần thiết nếu người lập trình viên muốn hiểu các hàm bên trong Phần 5 sẽ trình bày các số liệu thống kê về những thông tin đã được thu thập.

Một ứng dụng cụ thể của các thông tin đó, nghiên cứu có thể áp dụng để

4 HƯỚNG TIẾP CẬN cập công khai có thể truy cập vào hệ thống hoặc tài nguyên cá nhân đều được bảo vệ bởi các quyền truy cập thích hợp? Cho một hàm truy cập công khaif:

(1) nếu các đối tượng và hàm cần thiết để gọi fkhông có bất kỳ sự bảo vệ quyền truy cập nào?

(2) nếu các đối tượng và hàm bên trong f không có bất kỳ sự bảo vệ quyền truy cập nào?

(3) nếu việc gọi hàmfcó thể thay đổi một vài đối tượng bên ngoài, sau đó rất có khả năng không được bảo vệ bởi một quyền truy cập?

Phần 5.2 minh họa cách kiểm tra quyền truy cập như vậy được thực hiện thông qua một ví dụ cụ thể.

Thiết lập

Hướng tiếp cận của luận văn này sử dụng Soot để xây dựng đồ thị cuộc gọi cho các dịch vụ hệ thống Android và đầu ra là một tập tin có định dạng dot Kế đến, chúng tôi sử dụng thư viện NetworkX [34] để phân tích đồ thị cuộc gọi như: duyệt đồ thị để tìm đường đi, phân tích in-degree, out-degree, và dump đồ thị xuống thành tập tin định dạng pickle như đã trình bày ở phần 4.2. Đối với việc xây dựng đồ thị cuộc gọi từ Soot, cho mỗi phiên bản Android, chúng tôi cung cấp cho nó tất cả tập tin jar của hệ thống (bao gồm cả android.jar trong Android SDK được bởi Google) Để phân tích các dịch vụ hệ thống Android từ phiên bản 4.1 đến 4.4.4, chúng tôi sử dụng tất cả các tập tin hệ thống bên trong/system/framework được trích rút từ giả lập Google Nexus của phần mềm Genymotion [20]; các tập tin này bao gồm cả classes.dex của Dalvik Virtual Machine (DVM) Từ phiên bản Android 5.0.0 trở về sau, Android thay đổi kiến trúc của nó, thay thế DVM bởi Android Runtime (ART) và các tập tin dex được biên dịch thành tập tin định dạng ELF chứa mã nhị phân của hệ điều hành Linux Vì Soot framework không hỗ trợ tập tin nhị phân của Linux, chúng tôi sử dụng Java bytecode của Android được Grepcode [21] cung cấp cho phiên bản Android 5.1.0 và 6.0.1.

Thời gian xây dựng và đọc đồ thị cuộc gọi từng là một vấn đề thách thức với chúng tôi Thời gian xây dựng các đồ thị này xấp xỉ 15 tiếng cho một phiên bản Kế đến, mất khoảng 10 phút để đọc và chuyển đổi tập tin dot sang pickle thông qua NetworkX, và sau đó các thuật toán duyệt đồ thị dựa trênpickle có thể thực hiện được một cách nhanh chóng.

Thảo luận

Mục đích chính của nghiên cứu chúng tôi là hỗ trợ các nhà phát triển hiểu về quá trình các dịch vụ hệ thống Android giao tiếp với ứng dụng như đã trình bày ở ví dụ hình 11, từ đó đưa ra thông tin về các hàm truy cập công khai và các sự thay đổi của Android qua từng phiên bản ở hình 8 Những điểm giao tiếp giữa hệ thống và ứng dụng hay những API không được công bố này giúp các nhà lập trình có thể mở rộng thêm khả năng ứng dụng của họ thay vì chỉ dựa vào các thông tin được cung cấp từ Google.

Tuy nhiên những API đó mang những rủi ro tiềm ẩn của hệ điều hành Android, như trong ví dụ đã trình bày ở phần 5.2, công nghệ của chúng tôi có thể sử dụng để phát hiện các lỗ hỏng trong hệ thống này Nó cũng có nhiều tiềm năng để phát hiện rò rỉ dữ liệu hay vi phạm bảo mật.

Lưu ý rằng, cách gọi trực tiếp các hàm truy cập công khai trong dịch vụ hệ thống không phải là cách duy nhất các ứng dụng Android gọi các chức năng của hệ thống Có nhiều cách khác, chẳng hạn như truyền một intent phù hợp và được xử lý bởi hệ thống, hoặc sử dụng Java reflection để gọi hàm một cách tự động, Những cách gọi các hàm hệ thống như vậy chưa được phát hiện như là một hàm truy cập công khai của nghiên cứu này, các vấn đề đó sẽ để lại cho những công việc trong tương lai.

Luận văn này là được xây dựng để phân tích toàn bộ hệ thống của Android trên các phiên bản khác nhau, với ý muốn tự động hóa mô hình hành vi của hệ thống, có điều kiện phân tích toàn bộ hệ thống chính xác hơn và có khả năng mở rộng ra cho các ứng dụng Android Nghiên cứu này tập trung cho việc cung cấp các hàm hệ thống có thể truy cập công khai một cách dễ hiểu hơn.

Dựa trên các nghiên cứu hạn chế sáu phiên bản dịch vụ hệ thống Android từ 4.1.1 đến 6.0.1, và ba câu hỏi khoa học ở phần 5.2, chúng tôi nhận ra rằng các chức năng trong hê thống thay đổi rất nhiều qua từng phiên bản, số lượng hàm truy cập công khai thay đổi từ khoảng 53.000 lên đến 74.000 Ngoài ra, có sự phức tạp cao liên quan đến nhiều API dựa vào in-degree và out-degree của chúng Điều này giúp cung cấp thêm có các nhà phát triển những API khác không được mô tả trong tài liệu của Android. Đồng thời, chúng tôi cũng cho thấy tiềm năng hữu ích của nghiên cứu bằng việc trình bày quyền truy cập bị bỏ qua cho một API có thể truy cập công khai mà điều này có thể vi phạm bảo mật và sự riêng tư Nghiên cứu này có thể mở rộng để xây dựng một giải pháp có việc xác định có lỗ hổng tiềm tàng trong mã nguồn của hệ điều hành Android một các tự động.

Ngoài ra, nghiên cứu có thể áp dụng để xây dựng đồ thị cuộc gọi từ hệ thống Android cho nhiều ứng dụng điều này hỗ trợ cho việc phân tích đa ứng đồng thời, cũng như tìm ra những rủi ro tiềm ẩn của nhiều ứng dụng độc lập nhưng có liên kết gọi dữ liệu lẫn nhau.

Trong tương lai gần, chúng tôi sẽ tích hợp các phụ thuộc API và luồng điều kiện/dữ liệu vào các IDEs hiện đại (như Android Studio, Eclipse, IntelJIDEA) một cách trực quan để giúp các lập trình viên điều hướng thông tin và hiểu các API hệ thống phức tạp Đồng thời nghiên cứu sâu hơn về vấn đề tự động kiểm tra và phát hiện quyền truy cập với API không được bảo vệ có thể dẫn đến hành vi xâm phạm bảo mật và sự riêng tư.

[1] Android Open Source Project, “Android API guides: Activities,” https:

//developer.android.com/guide/components/activities.html.

[2] ——, “Android API guides: Tasks and back stack,” https://developer. android.com/guide/components/tasks-and-back-stack.html.

[3] ——, “Android sdk tools,” http://developer.android.com/tools/help/ index.html, 2016.

[4] ——, “Dalvik bytecode,” http://source.android.com/devices/tech/ dalvik/dalvik-bytecode.html, 2016.

[5] ——, “Dalvik Executable format,” https://source.android.com/devices/ tech/dalvik/dex-format.html, 2016.

[6] ——, “Dalvik Executable instruction formats,” http://source.android. com/devices/tech/dalvik/instruction-formats.html, 2016.

[7] S Arzt, S Rasthofer, and E Bodden, “Instrumenting android and java applications as easy as abc,” in International Conference on Runtime Verification Springer, 2013, pp 364–381.

[8] S Arzt, S Rasthofer, C Fritz, E Bodden, A Bartel, J Klein, Y L.

Traon, D Octeau, and P McDaniel, “FlowDroid: precise context, flow, field, object-sensitive and lifecycle-aware taint analysis for android apps,” in ACM SIGPLAN Conference on Programming Language Design and Implementation, PLDI, Edinburgh, United Kingdom, June

9–11 2014, p 29 [Online] Available: http://doi.acm.org/10.1145/

[9] K W Y Au, Y F Zhou, Z Huang, and D Lie, “Pscout: analyzing the android permission specification,” inProceedings of the 2012 ACM conference on Computer and communications security ACM, 2012,pp 217–228.

[10] V Avdiienko, K Kuznetsov, A Gorla, A Zeller, S Arzt, S Rasthofer, and E Bodden, “Mining apps for abnormal usage of sensitive data,” in 2015 IEEE/ACM 37th IEEE International Conference on Software Engineering, vol 1 IEEE, 2015, pp 426–436.

[11] H Bagheri, A Sadeghi, J Garcia, and S Malek, “Covert: Composi- tional analysis of android inter-app permission leakage,”IEEE Transac- tions on Software Engineering, vol 41, no 9, pp 866–886, 2015.

[12] A Bartel, J Klein, Y Le Traon, and M Monperrus, “Dexpler: convert- ing android dalvik bytecode to jimple for static analysis with soot,” in

Proceedings of the ACM SIGPLAN International Workshop on State of the Art in Java Program analysis ACM, 2012, pp 27–38.

[13] A Bartel, J Klein, M Monperrus, and Y Le Traon, “Static analysis for extracting permission checks of a large scale framework: The challenges and solutions for analyzing android,” IEEE Transactions on Software Engineering, vol 40, no 6, pp 617–632, 2014.

[14] D Bornstein, “Dalvik vm internals,” https://sites.google.com/site/io/ dalvik-vm-internals, 2008.

[15] I T W R Center, “Wala,” http://wala.sourceforge.net/wiki/index.php/

[16] D Ehringer, “The dalvik virtual machine architecture,” Techn report (March 2010), vol 4, p 8, 2010.

[17] Elvis, “Analysis of android art mechanism,” http://www.programering. com/a/MjM4ETNwATQ.html, Jul 2014.

[18] Evans Data Corporation, “Mobile developers now number 8.7 million worldwide,” http://www.fiercewireless.com/developer/ evans-data-mobile-developers-now-number-8-7-million-worldwide,June 2014.

[19] Gartner, “Worldwide smartphone sales grew 9.7 percent in fourth quar- ter of 2015,” http://www.gartner.com/newsroom/id/3215217, February 2016.

[20] Genymotion, “Fast and easy android emulator,” https://www. genymotion.com/.

[21] Grepcode, “Java source code search 2.0,” http://repository.grepcode. com/java/ext/com/google/android/android/.

[22] B Gruver, “Smali,” https://github.com/JesusFreke/smali, Oct 2015.

[23] Hex-Rays SA, “IDA Pro,” https://www.hex-rays.com/products/ida, Sep.

[24] J Hoffmann, M Ussath, T Holz, and M Spreitzenbarth, “Slicing droids: program slicing for smali code,” in Proceedings of the 28th An- nual ACM Symposium on Applied Computing ACM, 2013, pp 1844–

[25] J Kim, Y Yoon, K Yi, J Shin, and S Center, “Scandal: Static ana- lyzer for detecting privacy leaks in android applications,”MoST, vol 12,

[26] W Klieber, L Flynn, A Bhosale, L Jia, and L Bauer, “Android taint flow analysis for app sets,” in Proceedings of the 3rd ACM SIGPLAN International Workshop on the State of the Art in Java Program Analy- sis ACM, 2014, pp 1–6.

[27] A Kovacheva, “Efficient code obfuscation for android,” in Interna- tional Conference on Advances in Information Technology Springer, 2013, pp 104–119.

[28] L Li, A Bartel, T F Bissyandé, J Klein, Y L Traon, S Arzt, S Rasthofer, E Bodden, D Octeau, and P McDaniel, “IccTA:

Detecting inter-component privacy leaks in android apps,” in 37thIEEE/ACM International Conference on Software Engineering, ICSE, vol 1, Florence, Italy, May 16–24 2015, pp 280–291 [Online].

Available: http://dx.doi.org/10.1109/ICSE.2015.48

[29] L Li, A Bartel, J Klein, and Y Le Traon, “Automatically exploiting potential component leaks in android applications,” in 2014 IEEE 13th International Conference on Trust, Security and Privacy in Computing and Communications IEEE, 2014, pp 388–397.

[30] L Li, A Bartel, J Klein, Y L Traon, S Arzt, S Rasthofer, E Bodden, D Octeau, and P Mcdaniel, “I know what leaked in your pocket: un- covering privacy leaks on android apps with static taint analysis,”arXiv preprint arXiv:1404.7431, 2014.

[31] C Linn and S Debray, “Obfuscation of executable code to improve re- sistance to static disassembly,” in Proceedings of the 10th ACM con- ference on Computer and communications security ACM, 2003, pp.

[32] S Lortz, H Mantel, A Starostin, T B¨ahr, D Schneider, and A Weber,

“Cassandra: Towards a certifying app store for android,” inProceedings of the 4th ACM Workshop on Security and Privacy in Smartphones &

[33] L Lu, Z Li, Z Wu, W Lee, and G Jiang, “Chex: statically vetting an- droid apps for component hijacking vulnerabilities,” in Proceedings of the 2012 ACM conference on Computer and communications security.

[34] NetworkX, “High-productivity software for complex networks,” http:

[35] D Octeau, D Luchaup, M Dering, S Jha, and P McDaniel, “Compos- ite constant propagation: Application to android inter-component com- munication analysis,” in Proceedings of the 37th International Confer- ence on Software Engineering-Volume 1 IEEE Press, 2015, pp 77–88.

[36] D Octeau, P McDaniel, S Jha, A Bartel, E Bodden, J Klein, and Y Le Traon, “Effective inter-component communication mapping in an- droid: An essential step towards holistic security analysis,” inPresented as part of the 22nd USENIX Security Symposium (USENIX Security 13),

[37] Open Handset Alliance, “Industry leaders announce open platform for mobile devices,” http://www.openhandsetalliance.com/press_110507. html, Nov 2007.

[38] OpenSignal, “Android fragmentation visualized,” http://opensignal. com/reports/2015/08/android-fragmentation/, August 2015.

[39] B Pan, “Dex2jar,” https://github.com/pxb1988/dex2jar, Sep 2014.

[40] É Payet and F Spoto, “Static analysis of android programs,” Informa- tion and Software Technology, vol 54, no 11, pp 1192–1201, 2012.

[41] S Rasthofer, S Arzt, and E Bodden, “A machine-learning approach for classifying and categorizing android sources and sinks,” in 21st Annual Network and Distributed System Security Symposium, NDSS, 2014.

[42] S Rasthofer, S Arzt, E Lovat, and E Bodden, “Droidforce: enforcing complex, data-centric, system-wide policies in android,” inAvailability, Reliability and Security (ARES), 2014 Ninth International Conference on IEEE, 2014, pp 40–49.

[43] Sable Research Group, “Soot: A framework for analyzing and trans- forming java and android applications,” https://sable.github.io/soot/, 2016.

[44] R Vallée-Rai, P Co, E Gagnon, L Hendren, P Lam, and V Sundare- san, “Soot-a java bytecode optimization framework,” in Proceedings of the 1999 conference of the Centre for Advanced Studies on Collabora- tive research IBM Press, 1999, p 13.

[45] K Yaghmour, “Internals primer,” inEmbedded Android O’Reilly Me- dia, Mar 2013, pp 25–78.

[46] D Yan, G Xu, and A Rountev, “Rethinking Soot for summary-based whole-program analysis,” in ACM SIGPLAN International Workshop on the State Of the Art in Java Program Analysis @ PLDI, 2012, pp.

[47] S Yang, D Yan, H Wu, Y Wang, and A Rountev, “Static control-flow analysis of user-driven callbacks in Android applications,” in Interna- tional Conference on Software Engineering, 2015, pp 89–99.

Các bài báo đã công bố

Trong quá trình xây dựng luận văn, chúng tôi đã công bố hai bài báo khoa học tại hội nghị quốc tế MobiSys’16 Companion và SEATUC 2017.

Poster: Android Whole-System Control Flow Analysis for Accurate Ap- plication Behavior Modeling

• Paper name: Poster: Android Whole-System Control Flow Analysis for Accurate Application Behavior Modeling

• Conference: 14th Annual International Conference on Mobile Sys- tems, Applications, and Services Companion (MobiSys ’16 Compan- ion)

• Publisher: ACM, New York, NY, USA

School of Information Systems, Singapore Management University hhnguyen@smu.edu.sg

Android, the modern operating system for smartphones, together with its millions of apps, has become an important part of human life There are many challenges to analyzing them It is important to model the mobile systems in order to analyze the behaviors of apps accurately These apps are built on top of interactions with Android systems We aim to automatically build abstract models of the mobile systems and thus automate the analysis of mobile applications and detect potential issues (e.g., leaking private data, causing unexpected crashes, etc.) The expected results will be the accuracy models of actual various versions of Android system and apps for top apps selected from Google Play Store

• Software and its engineering~Automated static analysis

Android system; Android application; whole-system analysis; control flow; data flow; static analysis; modeling

Android users were able to choose millions of apps The analysis of these application becomes necessary There are some ap- proaches were released such as Flow Droid [1], GATOR [4], Ic- cTA [2] However, these approaches just analyze the control/data flow inside Android apps Different from many studies on mobile application analysis built on top of manually constructed and as- sumed to be correct behavior models of the system (e.g., lifecycle APIs for Android apps, asynchronous task APIs, etc.)

We aim to automatically build the models for the Android systems and identify its interaction points with any mobile application

Then, we carry out mobile application analysis based on com- bined models of the system and the app

With automatically built models, we can deal with various ver- sions of the systems We don't have to assume the availability and the correctness of the system models In addition, we aim to ena- ble a grey-box directed testing of apps that can reveal application behaviors more comprehensively to detect app crashes and private data leaks more accurately

Our approach focuses on whole-system modeling of Android system and application code We follow the steps as

(1) We model Android system behaviors involving system boot- strapping, application start-up, event handling, to automati- cally construct whole-system control-flow and call graphs;

(2) We model interactions between system and apps through GUI elements, callbacks, and system calls, from both system and application bytecode;

(3) We design algorithms for analyzing the whole-system graph- ical representations of the system and app code to identify points of interest more accurately, such as private data leaks

Our approach is based-on Soot framework with call graph con- struction systems such as Spark and the incremental BDD propa- gation algorithm [3]

We evaluate our approach on recent major different versions of Android systems and top apps from Google Play Store First, we focus on the comprehensiveness and accuracy of the abstract models for Android systems, such as various event handlers and thread handlers Second, we measure the coverage and precision of the models for apps when analyzed together with system mod- els Third, we measure test coverages and issue exposition rates for crashes and private data leaks in apps, and compare analysis results against other tools, such as Flow Droid [1]

Static analysis the accurate behavior is essential for modeling the control flow of Android applications There are some approaches such as GATOR [4], a control-flow analysis of user-event-driven callbacks, or IccTA [2], detecting inter-component privacy leaks in Android apps

We build a prototype system that can construct and visualize the interaction model between the system and apps Our system mod- els whole-system control flow for accurate app behaviors

This research is supported by the NRF, Prime Minister’s Office, Singapore under its IDM Futures Funding Initiative

[1] Arzt, S., Rasthofer, S., Fritz, C., Bodden, E., Bartel, A., Klein, J., &

McDaniel, P (2014, June) Flowdroid: Precise context, flow, field, ob- ject-sensitive and lifecycle-aware taint analysis for android apps In ACM

SIGPLAN Notices (Vol 49, No 6, pp 259-269)

[2] Li, L., Bartel, A., Bissyandé, T F., Klein, J., Le Traon, Y., Arzt, S., &

McDaniel, P (2015, May) IccTA: Detecting inter-component privacy leaks in Android apps In Proceedings of the 37th International Confer- ence on Software Engineering-Volume 1 (pp 280-291) IEEE Press

[3] Vallée-Rai, R., Co, P., Gagnon, E., Hendren, L., Lam, P., & Sundaresan, V (1999, November) Soot-a Java bytecode optimization framework In

Proceedings of the 1999 conference of the Centre for Advanced Studies on Collaborative research (p 13) IBM Press

[4] Yang, S., Yan, D., Wu, H., Wang, Y., & Rountev, A (2015, May) Static control-flow analysis of user-driven callbacks in Android applications

InProceedings of the 37th International Conference on Software Engi- neering-Volume 1 (pp 89-99) IEEE Press

Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page Copyrights for third-party components of this work must be honored For all other uses, contact the Owner/Author

Copyright is held by the owner/author(s)

MobiSys'16 Companion, June 25-30, 2016, Singapore, Singapore

ACM 978-1-4503-4416-6/16/06 http://dx.doi.org/10.1145/2938559.2948874

Interactions of system and callbacks Motivation

Android Whole-System Control Flow Analysis for Accurate

NGUYEN Huu Hoang School of Information Systems, Singapore Management University

• Android, the modern operating system for smartphones, together with its millions of apps, has become an important part of human life.

• These apps are built on top of interactions with Android systems.

• Analysis of these application becomes necessary.

• It is important to model the mobile systems in order to analyze the behaviors of apps accurately.

• Our approach focuses on whole-system modeling of Android system and application code.

• We model Android system behaviors involving system bootstrapping, application start-up, event handling.

• We model interactions between system and apps through GUI elements, callbacks, system calls.

• The model could be used to identify points of interest more accurately, such as private data leaks, unwanted purchases.

• Our approach has the challenges in the analysis such as scalability in handling huge graphs via summary-based call graph analysis.

[1] Arzt, S., Rasthofer, S., Fritz, C., Bodden, E., Bartel, A., Klein, J., &

McDaniel, P (2014, June) Flowdroid: Precise context, flow, field, object- sensitive and lifecycle-aware taint analysis for android apps In ACM SIGPLAN Notices (Vol 49, No 6, pp 259-269).

[2] Yang, S., Yan, D., Wu, H., Wang, Y., & Rountev, A (2015, May) Static control-flow analysis of user-driven callbacks in Android applications In

Proceedings of the 37th International Conference on Software Engineering- Volume 1 (pp 89-99) IEEE Press.

• We evaluate our approach on Android ICS 4.0 to Marshmallow 6.0 and top apps from Google Play Store.

• We focus on the comprehensiveness and accuracy of the abstract models for Android systems.

• We measure the coverage and precision of the models for apps when analyzed together with system models.

• We measure test coverages and issue exposition rates for crashes and private data leaks in apps, and compare analysis results against other tools.

Call graph of word card app

Whole-System Analysis For Understanding Publicly Accessible Functions In Android

• Paper name:Whole-System Analysis For Understanding Publicly Ac- cessible Functions In Android

• Authors: Nguyen Huu Hoang, Lingxiao Jiang, Quan Thanh Tho

• Conference: 11th South East Asean Technical University Consortium Symposium (SEATUC 2017)

• Location: Ho Chi Minh City, Vietnam

WHOLE-SYSTEM ANALYSIS FOR UNDERSTANDING PUBLICLY ACCESSIBLE FUNCTIONS IN ANDROID

Nguyen Huu Hoang (1) (2) * , Lingxiao Jiang (2) , Quan Thanh Tho (1)

(1) Ho Chi Minh City University of Technology, Viet Nam

(2) School of Information Systems, Singapore Management University, Singapore

Email: hhnguyen@smu.edu.sg

Android has become the most popular mobile system

Millions of applications, including many malwares, haven been developed for it Since Android itself evolves constantly with changing features and higher complexities, it is challenging for application developers to keep up with the changes and maintain the compatibility of their apps across Android versions; and it is challenging for application analysis tools to accurately model and analyze app behaviors across Android versions

Even though the overall system architecture of Android and many APIs are documented, many other APIs and implementation details are not, not to mention potential bugs and vulnerabilities Techniques and tool supports are thus needed to automatically extract information from different versions of Android to help programmers understand system behaviors and APIs across different versions This paper aims to address the need It performs whole-system analysis for different versions of Android by using both backward and forward static analysis of intra-procedural and inter-procedural control-flow and data-flow graphs It can collect information about functions in Android that can be invoked by applications, which are referred to as publicly accessible functions in this paper Such information can help programmers better understand the ways in which their applications utilize system functions We have analyzed Android versions 4.1.1, 4.2.2, 4.3, 4.4.4, 5.1.0, 6.0.1, and show basic statistics about the publicly accessible functions in different Android versions We also use an example to illustrate that the information about publicly accessible functions can be useful in identifying unprotected system functions whose invocations may not be protected by proper permissions and may lead to security and privacy violations

* This work is done when the first author is a visiting student in the School of Information Systems at Singapore Management University

KEYWORDS: android, call graph, control flow analysis, data flow analysis, program comprehension, permission check

Android now accounts for more than 80% of the global smartphone operating system (OS) market [8]

There have been more than 8 million mobile application programmers worldwide in 2014 [7] To help programmers, especially novice ones, to develop applications for a mobile OS quickly, often a first step is to get them become familiar with the architecture of the mobile OS and all APIs available in the OS so that programmers can structure their apps according to the ways in which the OS manages apps and be able to invoke needed OS functionalities via the APIs Even though the overall system architecture of Android and many of its APIs are documented, many APIs have evolved much across different versions of the Android system from API level 1 to API level 24 for Nougat 7.0, exhibiting different behaviors and causing incompatibility across versions and inconsistencies between actual code behaviors and the documentations There are also many undocumented APIs in the system that could be invoked by apps, not to mention many potential bugs and vulnerabilities that can be exploited by apps too

Understanding system behaviors and APIs becomes even more challenging when Android faces the fragmentation problem: there are over 1000 brands and more than 24000 models of Android phones in 2015 [15]; the manufacturers of the brands and models often customize the Android system for their phones in different ways without sufficient documentations for programmers

Manually going through documents and source code to track and understand the relations among different system APIs and behaviors is very time-consuming and error- prone; such tasks should be facilitated by tools (e.g., code navigation via Android X Ref [6]) that can work across different versions and fragments of the system

In the area of static analysis of Android systems and applications, much work [4,12,16,19] that focuses on analyzing Android applications require expert knowledge and models of the Android systems, such as the lifecycle callbacks used by the system to manage individual app activities [1], the back stack used in the system to manage sets of running activities [2], etc Such expert (and manual) modelling of the systems cannot keep up with the evolution and fragmentation of the systems, leading to inaccurate models and analysis results So, there are also needs to automate the modeling of various versions of the Android system, and more generally, to automate the modeling of large-scale frameworks and libraries used for application development, so that analysis of apps can be more accurate

The ultimate goal of this work is to achieve automated modeling of Android systems and facilitate programmers to understand system behaviors and APIs One way towards this goal is to perform whole-program analysis of a version of Android together with an application, so as to avoid the need to manually construct a behavior model of the system before analyzing the app This way has been considered in the literature and comes with many challenges (e.g., [18])

This paper takes a first step to analyze whole Android systems in different versions, to automatically curate Android system functions that are accessible by applications, providing a “navigation map” for different versions of Android systems for programmers to understand what functionalities in different versions of Android systems can be invoked by which APIs

Technically, we construct Java class hierarchies, call graphs and control-flow graphs for different versions of Android systems using the Soot analysis framework [17], and then identify public functions in Android that can be invoked by applications with suitable parameters that can be obtained by the applications too Such curated functions can reveal to programmers how system APIs, documented or undocumented, can be invoked in applications, helping them to understand the capabilities of the APIs We have analyzed six versions of Android:

Ngày đăng: 09/09/2024, 06:17

HÌNH ẢNH LIÊN QUAN

Hình 1: Tổng quan kiến trúc Android [45] - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 1 Tổng quan kiến trúc Android [45] (Trang 12)
Hình 2: Các dịch vụ hệ thống [45] - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 2 Các dịch vụ hệ thống [45] (Trang 14)
Hình 3: Trình tự khởi động của Android [45] - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 3 Trình tự khởi động của Android [45] (Trang 15)
Hình 4: Cấu trúc của tập tin .class và .dex [27] - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 4 Cấu trúc của tập tin .class và .dex [27] (Trang 18)
Hình 5: Các bước xây dựng và phân tích đồ thị cuộc gọi của Android - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 5 Các bước xây dựng và phân tích đồ thị cuộc gọi của Android (Trang 21)
Hình 6: Tổng quan hướng tiếp cận - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 6 Tổng quan hướng tiếp cận (Trang 28)
Hình 7: Đồ thị cuộc gọi tất cả dịch vụ hệ thống Android - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 7 Đồ thị cuộc gọi tất cả dịch vụ hệ thống Android (Trang 30)
Hình 8: Sự thay đổi các phương thức và cạnh qua từng phiên bản Android - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 8 Sự thay đổi các phương thức và cạnh qua từng phiên bản Android (Trang 35)
Hình 9: Phân bổ của in-degree - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 9 Phân bổ của in-degree (Trang 36)
Hình 11: Giao tiếp dịch vụ hệ thống và ứng dụng - Luận văn thạc sĩ Khoa học máy tính: Xây dựng đồ thị luồng điều khiển từ mã nhị phân ứng dụng Android
Hình 11 Giao tiếp dịch vụ hệ thống và ứng dụng (Trang 39)

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w