本文內容摘自吾愛破解論壇正己的《安卓逆向這檔事》系列教程,略有刪改、補充。
工具
廣告類型
一般有三種類型的廣告:
-
啟動廣告
-
彈窗廣告
-
橫幅廣告
啟動廣告
原理
啟動廣告流程:啟動Activity->廣告Activity->主頁Activity
安卓四大組件
組件 | 描述 |
---|---|
Activity(活動) | 在應用中的一個Activity可以用來表示一個界面,意思可以理解為「活動」,即一個活動開始,代表 Activity組件啟動,活動結束,代表一個Activity的生命周期結束。一個Android應用必須通過Activity來運行和啟動,Activity的生命周期交給系統統一管理。 |
Service(服務) | Service它可以在後台執行長時間運行操作而沒有用戶界面的應用組件,不依賴任何用戶界面,例如後台播放音樂,後台下載文件等。 |
Broadcast Receiver(廣播接收器) | 一個用於接收廣播信息,並做出對應處理的組件。比如我們常見的系統廣播:通知時區改變、電量低、用戶改變了語言選項等。 |
Content Provider(內容提供者) | 作為應用程序之間唯一的共享數據的途徑,Content Provider主要的功能就是存儲並檢索數據以及向其他應用程序提供訪問數據的介面。Android內置的許多數據都是使用Content Provider形式,供開發者調用的(如視頻,音頻,圖片,通訊錄等) |
定位方法
Activity 切換定位
MT管理器的 Activity記錄 功能,能夠將當前的 Activity 記錄下來。
打開側邊欄->Activity記錄->啟動服務,就會有一個懸浮框彈出,它會記錄下當前的 Activity:
打開任意一款軟體,可以看到一系列 Activity 被記錄了下來:
記錄下來的 Activity 可以在MT管理器里看到,長按可以複製結果:
將複製下來的Activity類名到 classes.dex 文件中進行搜索,可以快速定位到啟動廣告。
去除方法
一、修改載入時間
定位到程序廣告載入時間的邏輯,將其改為0。
二、修改 Intent 的 Activity 類名
AndroidMainifest.xml:
<!---聲明實現應用部分可視化界面的 Activity,必須使用 AndroidManifest 中的 <activity> 元素表示所有 Activity。系統不會識別和運行任何未進行聲明的Activity。----->
<activity
android:label="@string/app_name"
android:name="com.zj.wuaipojie.ui.MainActivity"
android:exported="true"> <!--當前Activity是否可以被另一個Application的組件啟動:true允許被啟動;false不允許被啟動-->
<!---指明這個activity可以以什麼樣的意圖(intent)啟動--->
<intent-filter>
<!--表示activity作為一個什麼動作啟動,android.intent.action.MAIN表示作為主activity啟動--->
<action
android:name="android.intent.action.MAIN" />
<!--這是action元素的額外類別信息,android.intent.category.LAUNCHER表示這個activity為當前應用程序優先順序最高的Activity-->
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.zj.wuaipojie.ui.ChallengeFirst" />
<activity
android:name="com.zj.wuaipojie.ui.ChallengeFifth"
android:exported="true" />
<activity
android:name="com.zj.wuaipojie.ui.ChallengeFourth"
android:exported="true" />
<activity
android:name="com.zj.wuaipojie.ui.ChallengeThird"
android:exported="false" />
<activity
android:name="com.zj.wuaipojie.ui.ChallengeSecond"
android:exported="false" />
<activity
android:name="com.zj.wuaipojie.ui.AdActivity" />
直接把主 activity 替換成廣告載入後的 activity 就可以跳過廣告。
由於主 activity 中往往要執行一些初始化操作,如果直接把它替換掉,可能會導致各種奇怪的問題產生,因此不推薦這種方法。
三、修改切換 activity 的代碼
從 classes.dex 搜索 activity 的類名,複製出該 activity 在 smali 代碼中的名稱進行代碼搜索來進一步定位。用 smali 代碼中的名稱搜索,搜到的結果會更多。
在其他類中進一步定位找到切換該 activity 的代碼,並進行修改。因為切換 activity 一般都是由別的類調用的,所以自身的類中的代碼可以排除,直接到其他類中找切換的代碼。
彈窗廣告
原理
一般在 Activity 的 onCreate 方法初始化時創建 Dialog,調用 show 方法來顯示彈框。
Activity 生命周期
這些函數都是 Activity 的回調函數,只有當 Activity 到達對應生命周期時才會被調用,無法主動調用。
函數名稱 | 描述 |
---|---|
onCreate() | 一個 Activity 啟動後第一個被調用的函數,常用來在此方法中進行 Activity 的一些初始化操作。例如創建 View,綁定數據,註冊監聽,載入參數等。 |
onStart() | 當 Activity 顯示在屏幕上時,此方法被調用但此時還無法進行與用戶的交互操作。 |
onResume() | 這個方法在 onStart() 之後調用,也就是在 Activity 準備好與用戶進行交互的時候調用,此時的 Activity 一定位於 Activity 棧頂,處於運行狀態。 |
onPause() | 這個方法是在系統準備去啟動或者恢復另外一個 Activity 的時候調用,通常在這個方法中執行一些釋放資源的方法,以及保存一些關鍵數據。 |
onStop() | 這個方法是在 Activity 完全不可見的時候調用的。 |
onDestroy() | 這個方法在 Activity 銷毀之前調用,之後 Activity 的狀態為銷毀狀態。 |
onRestart() | 當 Activity 從停止 stop 狀態恢進入 start 狀態時調用狀態。 |
去除方法
一、修改 xml 中的 versionCode(針對更新彈框)
部分更新彈框的邏輯會比對後台的版本號與當前 app 里的 versionCode 是否一致,不一致就彈出更新彈框。
對於這種更新彈框,修改 AndroidManifest.xml 中的 versionCode 可以去除。比如,將下圖的 versionCode="1" 改成 "2":
二、Hook 彈窗
這裡用的是演算法助手來 hook 彈窗,也可以用別的有類似功能的軟體。
演算法助手里開啟彈窗定位,可以讓彈窗被返回鍵取消(即使彈窗劫持了返回鍵)。
屏蔽關鍵詞彈窗,可以把帶有關鍵詞的彈框屏蔽掉。
三、修改 dex 彈窗代碼
通過演算法助手的彈窗定位功能,在日誌里可以看到彈框的一些調試信息。
根據調試信息在 classes.dex 中可以定位到彈框的代碼,然後進行修改。
一般彈框都會調用 show 方法來顯示,只要注釋掉對應語句即可。比如:
四、抓包修改響應體(也可以路由器攔截)
略,後面會講
橫幅廣告
原理
橫幅廣告指出現在 UI 布局中的廣告,在資源目錄下的 XML 文件中有對應元素。
去除方法
使用開發助手的布局查看功能,抓取對應廣告布局,得到對應的 16 進位 id:
將得到的 id 到MT管理器中通過XML搜索定位到對應的 XML 文件,然後在文件中搜索 id 定位到 XML 代碼。
需要注意的是,複製下來的 id 開頭帶有 0x,在到 XML 代碼中搜索時要去掉 0x 前綴。
如果還是搜索不到的話,看下是否開啟了ID轉名稱,開啟了的把它關掉就可以搜到了。
比如這裡搜到的布局元素是這樣的:
<ImageView
android:id="@7f0801ca"
android:background="@7f0d0017"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="100dp" />
一、將寬高改為 0
把 layout_width 或 layout_height 改為 0。比如這裡就把上面搜到的元素的 layout_width 改成了 0:
<ImageView
android:id="@7f0801ca"
android:background="@7f0d0017"
android:layout_width="0dp"
android:layout_height="150dp"
android:layout_marginTop="100dp" />
二、將可見性改為不可見
在對應元素中增加下面這樣的語句:
android:visibility="gone"
比如對於上面搜到的元素增加後的代碼是這樣的:
<ImageView
android:id="@7f0801ca"
android:background="@7f0d0017"
android:layout_width="wrap_content"
android:layout_height="150dp"
android:layout_marginTop="100dp"
android:visibility="gone" />
本文鏈接:https://linuxstory.org/android-reverse-ad-and-popup-removal-guide/
原文鏈接:https://www.52pojie.cn/thread-1706691-1-1.html
Linux Story 整理,對原文有刪節、補充;轉載請註明,否則將追究相關責任!