TÓM TÁT KHÓA LUẬN
Chương 3. PHƯƠNG PHAP VÀ QUY TRÌNH THỰC HIỆN
3.1. Xây dựng feature view graph
Trong khóa luận này, chúng em thay vì áp dụng các vết bớt truyền thông dựa trên cấp độ mã, chúng em chọn một phương pháp dựa trên giao diện người dùng, cụ thể là feature view graph. Nó chủ yêu dựa vào các activity có tương tác với người dùng và sự kiện chi phối tạo nên mối quan hệ điều hướng. Feature view graph thé hiện mức độ trừu tượng cao hơn về ngữ nghĩa của ứng dụng Android. Do đó, nó có tiềm năng mạnh mẽ hơn khi chống lại các nỗ lực làm rối mã. Dé đáp ứng yêu cầu về
khả năng mở rộng của phát hiện đóng gói lại ứng dụng Android, feature view graph
được xây dựng bằng cách phân tích tĩnh tệp gói ứng dụng Android (tệp APK).
Original
AIPKs
Is Original app
ơ : ”” Sosỏnh Feature view graph graph |
a
Is
Repackage
APKs
Repackage app
Hình 3.1: Mô hình cua công cụ
Feature view graph gồm 3 thành phan chính:
- Sơ đồ thể hiện mối liên hệ giữa các activity gồm các nút (node) là các activity và các cạnh thê hiện mối quan hệ điều hướng.
- Thuộc tính cạnh chứa sự kiện kích hoạt chuyển activity.
- Thuộc tinh node chứa các API của Android framework đã được gọi trong activity đó.
35
3.1.1. Xây dựng view graph
Trong gói ứng dụng Android, các bố cục giao diện người dùng của một ứng
dung Android thường được xác định trong các tệp XML trong thư mục res/layout/.
Hoạt động của một khung cửa số (View) được thực hiện trong classes.dex, được biên dịch dưới dạng mã Dalvik bytecode. Do đó, dé phân tích gói ứng dụng nhằm xây dựng view graph, chúng em tiến hành phân tích trên các lớp activity (activity class), lớp này xác định chức năng của View và chỉ ra mối quan hệ điều hướng giữa các view. Bố cục của một cửa số ứng dụng (view) thường được xác định trong các tệp tài nguyên XML và được tải bằng mã activity trong quá trình thực thi đề hiển thị cho người dùng. Hầu hết các hoạt động tải một view bằng cách gọi hàm setContentView() với tên tệp XML làm tham sé, trong ham onCreate() của nó. Một
số view đặc biệt được tải bởi các chức năng khác, ví dụ như cửa số cài đặt (setting view) được tải bởi hàm addPreferencesFromResource(). Điều hướng view được
thực hiện bằng cách chuyển đổi activity. Khi một activity gọi một activity khác, một
đối tượng của activity callee được tạo, một view mới được liên kết với callee sẽ
được tải và đưa lên đầu ngăn xếp view của hệ thống đề hiền thị cho người dùng.
Một activity chuyển sang một activity khác thường bằng cách gọi ham
startActivity() hoặc startActivityForResultQ với một đối tượng Intent làm tham số.
Kết quả là, chúng ta có thé xây dựng sơ đồ cửa số (view graph) bằng cách phân tích
tĩnh các lệnh gọi hàm này [1].
36
==>
A3E ) mm
= Ea
ls
Hình 3.2: Mô hình xây dựng view graph và thuộc tính cạnh từ công cụ A°E
Sự kiện 2
Sự kiện 4
Để phân tích, trích xuất sơ đồ các view (View graph) hay cụ thể hơn là sơ đồ chuyển đổi giữa các activity (Activity Transition Graph). Chúng em sử dụng chức
năng phân tích tĩnh của công cụ Automatic Android App Explorer (A?E) [20]. Như
đã trình bày ở mục 2.4, công cụ này sử dụng kỹ thuật truy vết từ các source đến các sink nhằm tìm ra các mối quan hệ điều hướng giữa các activity và sự kiện kích hoạt hành động chuyền tiếp activity đó. Kết quả sẽ cho ra một tệp xml bao gồm các
activity chứa source được đặt là các activity cha và các activity trong sink được đặt
là các activity con. Kèm theo mỗi quan hệ cha con giữa các activity là một sự kiện
được định nghĩa trong Android framework (ví dụ như: onCreateQ,
onBackPressed(), onAnimationEnd(), onReceive(),...) đã kích hoạt chuyển đôi giữa
hai activity.
37
0” encodinge"atf-8" standalones"no"?>
inactivity” >
ce. receive RenindReceiver” encoded_ callbacks" Leon/falcon/cleaner/ui /MainActivity:=Sgt sonCreate (Landroid/os/Bandle.
ee AntoProtectService” encoded_callback="Lcon/falcon/cleaner/ai /MainActivity =4gt sonCreate(Landroid/os/Bandle:)V"/
<Activity naneeFcơn,fa1eon.elearer,#erviee,AdtofrotectServioe"
snew"com. facon.cleaner. service .NotificationlliService” eacode4 ce11oace”Leoa/fa1eon/e1eaner/serviee/AntoFroteet'Serv1ee ;=gt:onStartCowaan4(Lar snew"com. facon.cleaner. service .AntoProtectService” encoded celiback="Lcon/ falcon/cleaner/service/AutoProtectService:=igt /onDestroy ()V"/>
<Activity nanea"con, falcon, cleaner. service, receive.BoostReceiver" >
"2ene^"cow, falcon, cleaner. service. receive, RemindReceiver” encoded_calLbscik="Leon/falcon/cleaner/service/receive/BoostRecei ver '=Kgtsonfeceive (Lane
ity nanea*com, falcon, cleaner. service, receive. Uninstall FackageRecei ve"
AldActivity nene="com.faicon.cleaner,module., junk.ti .JankCleanActivity" jed_celiback="Loon/falcon/cleaner/service/receive/OninstallFackageReceive;=Egt sor
‘Leon £aicon/cleaner /moduie/nenory/ai /ManageMenoryActivity:=SgtonBackPressed()V"/>
Hình 3.3: Ví dụ vê kết quả thu được sau khi phân tích tĩnh bang công cu ASE
Sau đó, chúng em thực hiện xử lý kết quả thu được ở trên để xây dựng view graph. Cụ thé, đầu vào sẽ là kết quả thu được khi phân tích tĩnh bằng công cụ A3E
và tệp AndroidManifest.xml của ứng dụng (thu được bằng công cụ apktool). Mã xử
lý được nói đến ở trên được viết bằng Python 3. Đầu tiên, chúng em duyệt qua tệp AndroidManifest.xml dé tìm activity chính, hay main activity (là activity thực hiện hiển thị cửa số đầu tiên khi người dùng khởi chạy ứng dụng). Main activity sẽ được
khai báo trong tệp AndroidManifest.xml với thẻ <intent-filter> chứa các thẻ
<action> và <category> có thuộc tính android:name có các giá trị lần lượt là
“android.intent.action.MAIN” và "android.intent.category.LAUNCHER".
<activity android:clearTaskOnLaunch="true" android:name="com.falcon.cleaner.ui.SplashActivity" anc
<intent-filter>
<action android:name="android. intent. action.MAIN"/>
<category android:name="android. intent.category . LAUNCHER" />
</intent-filter>
</activity>
Hình 3.4: Ví dụ khai báo main activity trong tệp AndroidManifest.xml
Tiếp theo, chúng em thực hiện duyệt qua tệp kết quả thu được từ công cụ A3E
để thu thập tất cả các activity và mỗi quan hệ cha con giữa chúng [25]. Sau đó, chúng em xóa bỏ một số lớp activity cha thuộc thư viện quảng cáo. Bởi nếu hai ứng dụng sử dụng chung thư viện quảng cáo này thì có thể gây ảnh hưởng đến kết quả,
38
gây kết quả đương tính giả. Tiếp theo, chúng em xây dựng các nút và cạnh từ tập
các activity đã thu thập. Hơn nữa, chúng em cũng đưa main activity đã tìm được
trong AndroidManifest.xml lên làm nút đầu tiên, góp phan tăng tỉ lệ ghép các nút và cạnh phù hợp trong thuật toán VF2. Kết thúc quá trình này, ta thu được sơ đồ các nút (là các activity) và các cạnh nối các nút với nhau. Mỗi nút được đánh số, các số này sẽ đại diện cho các nút, cấu thành view graph với các nút là các số tương ứng với các activity, chúng được nối với nhau tương ứng với quan hệ giữa các activity.
© com.falcon.cleaner.ui.SplashActivity --> com.falcon.cleaner.ui.MainActivity
en 9 --> 1
© com.falcon.cleaner.ui.MainActivity --> com. falcon.cleaner.service.receive.RemindReceiver
en 1 --> 2
© com.falcon.cleaner.wi.MainActivity --> com. falcon.cleaner.service AutoProtectService
en 1 ——> 3
© com.falcon.cleaner.service.AutoProtectService --> com. falcon.cleaner.service.NotificationUiService
en 3 —> 4
© com.falcon.cleaner.service.AutoProtectService --> com. falcon.cleaner.service AutoProtectService
en 3 --> 3
© com.falcon.cleaner.ui.SafeResultActivity --> com.falcon.cleaner.ui.MainActivity
en 5 --> 1
© com.falcon.cleaner-module.cpucooler-ui.CpuCoolerActivity --> com.falcon.cleaner.ui.MainActivity
en 6 ——> 1
© com.falcon.cleaner.module.battery.SavingBatteryActivity --> com.falcon.cleaner.ui.MainActivity
en 7 > 1
© com.falcon.cleaner.ui.SettingActivity --> com.falcon.cleaner.ui.MainActivity
en 8 --> 1
© com. falcon.cleaner.module
en 9 —> 1
emory.ui.ManageMemoryActivity --> com.falcon.cleaner.ui.MainActivity
Hình 3.5: View graph với tên activity class và số node tương ứng
39
3.1.2. Xây dựng thuộc tính cạnh
Sau khi xây dựng view graph với các node và các cạnh như đã trình bay ở trên.
Chúng em thêm vào view graph các thuộc tính trích xuất từ ứng dụng để xây dựng
feature view graph. Các thuộc tính được thêm vào view graph bao gồm thuộc tính
node và thuộc tính cạnh. Việc trích xuất thuộc tính node sẽ được trình bày ở mục
3.1.3. Dưới đây sẽ trình bày về vấn đề trích xuất và thêm thuộc tính cạnh vào view
graph.
Để giảm thiểu kết quả khớp sai và cải thiện hiệu quả của phép phát hiện đồ thị đẳng cấu ở giai đoạn sau, chúng em thêm một thuộc tính cho mỗi cạnh. Sự kiện do người dùng gây ra sẽ kích hoạt chuyển đổi view và activity tương ứng. Trong quá trình phân tích tĩnh, chúng ta có thể xác định vị trí các hàm startActivity() hoặc startActivityForResult() và phân tích lệnh gọi hàm nào thực sự kích hoạt chuyển đổi view [1]. Điều kiện kích hoạt (trigger) có thể là trình lắng nghe sự kiện do thư viện Android cung cấp liên quan đến các sự kiện do người dùng tương tác với giao diện tạo Ta như onClick(), onBackPressed(), onOptionsItemSelected(),
onCheckedChanged(),... các sự kiện trong vòng đời cua activity như onCreate(),
onStart(), onResume(), onPause(), onStop(),... hay trong vòng đời của các thành
phần khác như onBind(), onStartCommand(), onReceive(),... hoặc cũng có thé là các hàm, phương thức do nhà phát triển ứng dụng tự định nghĩa. Những trình kích hoạt này sẽ được lay làm thuộc tính của các cạnh.
Để trích xuất các trình kích hoạt sự kiện làm thuộc tính cạnh, chúng em cũng dựa trên kết quả đầu ra của công cụ phân tích tĩnh A3E đã nói ở trên. Từ view graph
đã xây dựng ở trên, chúng em duyệt qua kết quả của công cụ đề lấy tên các hàm, phương thức kích hoạt hoạt động chuyển đổi giữa các cặp view trong view graph. Đối với các cặp quan hệ có nhiều hơn một sự kiện kích hoạt, thuộc tính của cạnh đó
40
sẽ là một danh sách tên các phương thức lắng nghe các sự kiện kích hoạt. Ngoài ra, như đã trình bày ở trên thì các phương thức này ngoài việc được sử dụng, kế thừa từ các phương thức trong Android framework, chúng còn có thẻ là các phương thức do nhà phát triển tự định nghĩa. Các phương thức tự định nghĩa này có thể dễ dàng bị
kẻ tấn công đặt lại tên trong quá trình đóng gói lại. Do đó chúng em sử dụng một danh sách (whitelist) tên các phương thức lắng nghe sự kiện được định nghĩa trong Android framework để lọc ra các phương thức được lấy làm thuộc tính cạnh cho view graph. Ngược lại, tất cả các phương thức không nằm trong danh sách sẽ được lấy làm thuộc tinh cach dưới cùng một tên (ví dụ như selfDefinedMethod).
= com,falcon.cleaner.ui,SplashActivity --> com.falcon.cleaner.ui.MainActivity => onCreate();
eno > 1
© com.falcon.cleaner.ui.MainActivity --> com.falcon.cleaner.service.receive.RemindReceiver => onCreate();
en 1 —> 2
© com.faicon.cleaner.ui.MainActivity --> com.falcon.cleaner.service.AutoProtectService => onCreate();
en l > 3
+ com.falcon.cleaner.service AutoProtectService --> com. falcon.
_— 4
falcon.cleaner.service AutoProtectSezvice --> com,falccn,cieanl
> 3
© com,falcon.cleaner.ui,SafeResultActivity --> com.falcon.cleaner.ui.MainActivity => onBackPressed();
en 5 > 1
falcon.cleaner.module.cpucocler.ui.CpucoolerActivity --> com.falcon.cleaner.ui-MainActivity => onBackPressed();
h con.cleaner.module.battery.SavingBatteryActivity --> com.falcon,cleaner.ui.MainActivity => cnBackPressed();
a con.cleaner.ui.Settinghctivity --> com.falcon.cleaner.ui.MainActivity => onBackPressed():
en 8 > 1
er. service NotificaticnUsservice => cnSrartComman4()z
iservice AutoPzotectService => onDestroy():
© com.faicon.cleaner-module.memory.ui-ManageMemoryActivity --> com.falcon.cleaner-ui-MainActivity => onBackPressed();
en 8 > 1
© com.falcon.cleaner.service.receive.BoostReceiver --> com. falcon.cleaner.service.receive.RemindReceiver => cnReceive();
en 10 --> 2
Hình 3.7 : View graph với tên activity class, số node tương ứng và phương thức
kích hoại.
41
onCreate();
onCreate();
onCreate();
onStartCommand () ; onDestrov();
onBackPressed();
onBackPressed();
onBackPressed();
onBackPressed();
onBackPressed();
2 onReceive ();
11 5 onAnimationEnd();
12 1 onBackPressed();
13 1 onBackPressed();
14 13 onReceive();
15 1 onBackPressed();
ơ.. . PER BBO we
bw=
baStarCommand0;
Hình 3.9: Hình mình họa view graph với thuộc tính cạnh
3.1.3. Xây dựng thuộc tinh node
Đối với các thuộc tính của các nút trong view graph, chúng em chỉ tập trung vào các API riêng biệt của Android framework. Nền tảng Android có sử dụng các Java API được xây dựng trên một tập hợp con của việc triển khai Apache Harmony Java [1]. Ngoài ra, trong một ứng dụng Android, nhà phát triển có thé tự định nghĩa các API hoặc sử dụng một sé thư viện API khác. Các bộ API này dễ bị tan công đổi
42
tên hơn và những kẻ tấn công có thê dễ dàng tìm thấy các API tương tự hoặc tương đương về ngữ nghĩa từ các nguồn khác. Tuy nhiên, rất khó thay thế bộ các API của
Android, ví dụ như các phương thức từ các lớp android.view. View, android.util.Log
, android.security.KeyChain, android.nfc.NfeManager [1]. Dé tương tác với nền tảng Android, ứng dụng phải đăng ký một số quyền nhất định trong tệp kê khai và
sử dụng các API có liên quan để thực hiện các tác vụ. Dựa trên quan sát này, chúng
em xây dựng thuộc tính cho từng node trong view graph cho phù hợp. Trước tiên,
chúng em phân tích từng tệp activity class được liên kết với view node dé trích xuất
một tập hợp các lệnh gọi của các API của Android. Sau đó, xây dựng một tập các
vector tạo nên từ các lớp định nghĩa API và tên API được gọi cho mỗi view node. Tap hợp sẽ liệt kê các vector thể hiện các API được gọi, không thực hiện liệt kê lặp lại hay đếm số lần gọi của cùng một API. Điều này có thể bảo vệ ViewDroid khỏi cuộc tấn công chèn mã rác và cũng có thể cải thiện hiệu quả so sánh thuộc tính node
(1).
`" 4 7 [ + Context->getResources()
= ` NEEL) + Intent->setAction()
Androguard Method 4 Method 2 * Intent->getAction()
Node 1 EInevnimoNB mm | * GridView->setAdapter()
* move-object *® invoke-super we
* invoke-virtual _ fa
Hình 3.10: Mô hình xây dựng thuộc tinh node
Để trích xuất thuộc tính node, chúng em sử dụng công cụ phân tích tĩnh Androguard [26] dé dịch ngược tệp apk và tạo sơ đồ luồng điều khiển (control flow graph). Dé giảm thời gian thực thi công cụ xuống thấp nhất có thé, chúng em duyệt qua view graph để thu thập các activity class cần phân tích và thực thi công cụ
43
Androguard [26] với tùy chọn “--limit” là đường dẫn tới activity class cụ thé dé giới hạn phạm vi công cụ cần phân tích.
1£ Lcon/faLcon/cLeaner /ut/SpLashActtv†ty; ->getAnimatton()Landroid/view/animatton/Animattonset;
[access_flags=private]
28
3 # Parameters:
4# local registers: vô.
S#
6# - return:android.view.animation.AnimationSet
7
8 getAntmaton-BB@0x6 :
v12
9 9 (99999998) new-instance ve, Landrotd/view/antmatton/AntmationSet;
10 1 (98000004) invoke-virtual v12, Lcom/falcon/cleaner/ui/SplashActivity; -
>getApplicationContext()Landroid/content/Context;
11 2 (0000000) move-result-object v1
12 3 (9800000c) const /4 v2, 0
13 4 (9800968e) invoke-direct vO, vi, v2, Landrotd/vtew/antnatton/AntnattonSet; -
><init>(Landroid/content/Context; Landrotd/uttL/Attrtbuteset; )V
14 5 (00000014) new-instance v1, Landroid/view/animation/TranslateAnimation;
15 6 (98998618) const/4 v4, 1
16 7 (9890901a) const/4 vs, 0
17 8 (099961c) const /4 vo, 1
18 9 (9800901e) const/4 v7, 0
19 10 (98000026) const/4 v8, 2
20 11 (0099022) const/htgh16 v9, 16256 # [1.0] i
21 12 (99969626) const/4 v19, 2 :
22 13 (99009028) const/4 v11, 0
23 14 (98000024) move-object v3, vi
Hình 3.11: Kết quả phân tích tĩnh của một phương thức trong một activity class
bang công cụ Androguard
Sau khi thu được các tệp hợp ngữ thể hiện CFG của từng activity class tương ứng với các node trong view graph, chúng em duyệt qua kết quả phân tích của
Androguard [26] và thu thập các API của Android framework được gọi trong mỗi
activity class. Các API này thường được gọi bằng cách gọi phương thức tĩnh (invoke-static) hay gọi phương thức ảo (invoke-virtual) và được gọi từ các lớp nằm trong đường dẫn bắt đầu bằng là “Landroid”. Từ đó, chúng em xây dựng thuộc tính node gồm tập các vector thé hiện các API đã được gọi trong các activity class tương ứng với các node va class đã định nghĩa các API day.
44
com, falcon.cleaner.ui.SplashActivity View->setVisibility(), Animation->setStartOffset(), com, falcon.cleaner.ui.MainActivit ontext->getPackageManager(), Context->getPackageName com, falcon. cleaner. service. receive. RemindReceive: Log->d(),
com, falcon. cleaner. service AutoProtectService:::::IntentFilter->addAction(), IntentFilter->z com, falcon. cleaner. service .NotificationUiService :NotificationManager->cancel(), Intent-: com, falcon. cleaner.ui.SafeResultActivity Animation->setDuration(), | AnimationSet->addAnir com. falcon. cleaner .module.cpucooler.ui.CpuCoolerActivit Intent->setFlags(), InfoCpuTasl com. falcon.cleaner.module.battery.SavingBatteryActivity ntent->setFlags(), Window->geti com, falcon.cleaner.ui.SettingActivity:::::Intent->setFlags(), Contexr->gstResources(), Re: com, fa1con.cleaner,modu1e .memory. ai .ManageMemozvActivity:::::ActionBar->hide(), TextView->s¢ com, fa1con.cLeanerservice.zeceive.BoostReceiver : ::::Tntent->getAction(), PendingTntent->get com, falcon. cleaner.module.cpucooler.ui.CpuCoolerSuccessActivity:::::Resources->getString(), com, falcon. cleaner .module.memory.ui.MemorySpeedActivity: View->getId(), ActionBar->hide() com. falcon.cleaner.module.junk.ui.JunkCleanActivity: intent->setFlags(), SparseArray->get com, falcon. cleaner. service. receive .UninstallPackageReceiv rIntent->getData(), Uri->getEr com, falcon.cleaner.module.virus.SafeActivity:::::Resources->getColor(), — Window->setStatusBai
Hình 3.12: Các API được gọi trong các activity được lấy làm thuộc tính của các
node tương ứng
3.2. So sánh và phát hiện feature view graph tương đồng
Để so sánh và phát hiện gói ứng dụng (tệp apk) tương đồng, chúng em tạo ra các feature view graph là một sơ đồ với các thuộc tính node và thuộc tính cạnh như
đã trình bày ở trên. Sau đó, chúng em sử dụng thuật toán VF2 [16] của package
Networkx (python) dé so sánh sự tương đồng của hai feature view graph. Hai đồ thị được coi là tương đồng nếu tồn tại một phép đăng cấu đồ thị con (Subgraph Isomorphism hay Graph-Subgraph Isomorphism) giữa hai đồ thi. Hai đồ thị G1, G2 được gọi là đẳng cấu đồ thị con (Subgraph Isomorphism hay Graph-Subgraph Isomorphism) nếu tồn tại một cách ánh xạ các cặp node giữa đồ thi con của G1 với G2 hoặc đồ thị con của G2 với G1. Ngoài ra, dé lọc bớt các cặp mà chúng em cho là không thể tương đồng nhau, chúng em thực hiện so sánh số lượng node là cạnh của hai feature view graph. Nếu số lượng node hoặc số lượng cạnh của hai feature view graph chênh lệch nhau 3 lần trở lên sẽ được bỏ qua và được xem là không tương đồng nhau.
Để xác định hai node có được ánh xạ với nhau hay không, chúng em so sánh
độ tương đồng của các thuộc tính node và các thuộc tính cạnh. Đối với mỗi node ứng với một activity của ứng dụng, chúng em so sánh dựa vào các vector gọi thé
hiện các API của Android framework được gọi trong node đó như đã trình bày ở
45