Android apk快速定位、灰色按钮克星--DroidSword
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80994434
在進行Android應用程序的逆向分析時,經常需要對Android應用程序的按鈕事件、Activity界面等類的代碼進行定位分析,傳統的代碼定位方法就是進行按鈕或者Activity界面等顯示的 字符串信息 進行全局的搜索,然后找他們的id或者類進行代碼的定位,比較繁瑣,這里介紹一個基于Xposed Hook實現的Android apk快速定位,灰色按鈕克星工具DroidSword,當然了亦可以使用我前面的博客中提到的《Xposed框架Hook Android應用的所有類方法打印Log日志》和《查找和定位Android應用的按鈕點擊事件的代碼位置基于Xposed Hook實現》進行Android應用程序的需要分析的代碼的定位。
DroidSword工具的功能介紹:
1.快速定位Activity,以及點擊View的信息
2.點擊懸浮窗口獲取Fragment
3.灰色按鈕克星
4.文字修改神器
DroidSword工具的github地址:https://github.com/githubwing/DroidSword
DroidSword工具作者的學習博客:http://androidwing.net
DroidSword工具是基于Xposed Hook實現的,但是作者githubwing是使用Kotlin語言實現的,對于Kotlin語言不熟悉,但是對于DroidSword工具的實現思路還是能看明白,下面簡要的分析一下。
1.類IHooker是作者編寫的xposed hook的接口類,代碼如下:
2.類net.androidwing.droidsword.Init是DroidSword工具xposed hook的入口類:
3.類ViewClickedHooker主要用于實現Hook類android.view.View的方法onTouchEvent,獲取到View類的名稱和View類的id以及View的事件監聽類對象的類名稱;Hook類android.view.View的方法dispatchTouchEvent,獲取到的View類的名稱、View類的id、View的事件監聽類對象的類名稱并在設備的界面上顯示出來。
源碼文件路徑:/frameworks/base/core/java/android/view/View.java
一般View組件情況下,Hook類android.view.View的類方法onTouchEvent函數,View組件通過獲取實例對象View中的成員變量mListenerInfo->mOnClickListener所屬的類名稱,得到響應View按鈕單擊事件的監聽響應類OnClickListener的信息。
對于AdapterView類型的View組件,通過Hook類android.view.View的方法dispatchTouchEvent,AdapterView組件獲取實例對象View中的成員變量mOnItemClickListener的類(事件響應類)的類名稱,得到監聽和響應用戶單擊事件的處理類OnItemClickListener的信息。
/*** Pass the touch screen motion event down to the target view, or this* view if it is the target.** @param event The motion event to be dispatched.* @return True if the event was handled by the view, false otherwise.*/public boolean dispatchTouchEvent(MotionEvent event) {if (mInputEventConsistencyVerifier != null) {mInputEventConsistencyVerifier.onTouchEvent(event, 0);}if (onFilterTouchEventForSecurity(event)) {//noinspection SimplifiableIfStatementListenerInfo li = mListenerInfo;if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED&& li.mOnTouchListener.onTouch(this, event)) {return true;}if (onTouchEvent(event)) {return true;}}if (mInputEventConsistencyVerifier != null) {mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);}return false;}4.類ActivityHooker主要用于實現Hook類android.app.Activity的方法onResume,獲取類方法onResume所屬類Activity的實例對象的類名稱并顯示出來。
/*** Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or* {@link #onPause}, for your activity to start interacting with the user.* This is a good place to begin animations, open exclusive-access devices* (such as the camera), etc.** <p>Keep in mind that onResume is not the best indicator that your activity* is visible to the user; a system window such as the keyguard may be in* front. Use {@link #onWindowFocusChanged} to know for certain that your* activity is visible to the user (for example, to resume a game).** <p><em>Derived classes must call through to the super class's* implementation of this method. If they do not, an exception will be* thrown.</em></p>* * @see #onRestoreInstanceState* @see #onRestart* @see #onPostResume* @see #onPause*/protected void onResume() {if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);getApplication().dispatchActivityResumed(this);mCalled = true;}5.類FragmentHooker用于實現Hook類"android.support.v4.app.Fragment"的方法onResume和方法setUserVisibleHint,獲取類Fragment的類名稱并進行顯示。
源碼文件路徑:/frameworks/support/v4/java/android/support/v4/app/Fragment.java
有作者gtict112將DroidSword工具的功能用java代碼進行了實現并添加了新的功能構建成工程xposedhook,xposedhook工程的github地址:https://github.com/gtict112/xposedhook,后面有時間我再看下將這部分代碼集成到我自己的Xposed模塊中。
DroidSword工具的類ViewClickedHooker的代碼:
package net.androidwing.droidsword.hookerimport android.app.AlertDialog import android.app.AndroidAppHelper import android.app.Dialog import android.content.DialogInterface import android.view.MotionEvent import android.view.View import android.widget.* import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.callbacks.XC_LoadPackage import net.androidwing.droidsword.func.TextViewChanger import net.androidwing.droidsword.func.ViewEnabler import net.androidwing.droidsword.utils.LogUtils/*** Created on 28/10/2017.*/ class ViewClickedHooker : IHooker {override fun hook(lp: XC_LoadPackage.LoadPackageParam) {// Hook類android.view.View的方法onTouchEvent// public boolean onTouchEvent(MotionEvent event)XposedHelpers.findAndHookMethod(View::class.java,"onTouchEvent",MotionEvent::class.java, object : XC_MethodHook() {override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)// 獲取類方法onTouchEvent所在的實例對象Viewval view = param?.thisObject as View// 獲取類方法onTouchEvent的傳入參數MotionEvent實例對象val event = param.args!![0] as MotionEvent// 對用戶點擊屏幕的事件進行判斷if (event.action == MotionEvent.ACTION_UP) {// 獲取實例對象View中的成員變量mListenerInfo->mOnClickListener所屬的類名稱val listener = XposedHelpers.getObjectField(XposedHelpers.getObjectField(view, "mListenerInfo"),"mOnClickListener").javaClass.name// 顯示獲取到的View類的名稱、View類的id、View的事件監聽類對象的類名稱ActivityHooker.setActionInfoToMenu("","${view.javaClass.name} ${view.id} \nListener: $listener")antiDisable(view)}}})// Hook類android.view.View的方法dispatchTouchEvent// public boolean dispatchTouchEvent(MotionEvent event)XposedHelpers.findAndHookMethod(View::class.java,"dispatchTouchEvent",MotionEvent::class.java, object : XC_MethodHook() {override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)// 獲取類方法dispatchTouchEvent所在類View的實例val view = param?.thisObject as View// 獲取類方法onTouchEvent的傳入參數MotionEvent實例對象val event = param.args!![0] as MotionEvent// 進行用戶點擊屏幕的事件類型的判斷if (event.action == MotionEvent.ACTION_DOWN) {// 進行View類型的判斷(AdapterView)if (view is AdapterView<*>) {// 獲取實例對象View中的成員變量mOnItemClickListener的類(事件響應類)的類名稱val listener = XposedHelpers.getObjectField(view,"mOnItemClickListener").javaClass.name// 顯示獲取到的View類的名稱、View類的id、View的事件監聽類對象的類名稱ActivityHooker.setActionInfoToMenu("","${view.javaClass.name} ${view.id} \nListener: $listener")}}}})// 文字修改功能的實現XposedHelpers.findAndHookMethod(View::class.java,"onTouchEvent",MotionEvent::class.java, object : XC_MethodHook() {override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)val targetView = param?.thisObject as Viewif (true) {// ??showChangeTextDialog(targetView, param)}}})}private fun antiDisable(view: View) {//TODO 默認開啟待添加配置文件if (false) {ViewEnabler.antiDisable(view)}}/*** 文本修改神器功能*/private fun showChangeTextDialog(targetView: View,param: XC_MethodHook.MethodHookParam) {//TODO 默認開啟待添加配置文件val event = param.args!![0] as MotionEventif (false) {TextViewChanger.showChangeDialog(targetView, event)}}DroidSword工具的類ActivityHooker的代碼:
package net.androidwing.droidsword.hookerimport android.app.Activity import android.app.AndroidAppHelper import android.app.Fragment import android.content.Context import android.graphics.Color import android.os.Build import android.os.Bundle import android.support.v7.widget.AppCompatImageHelper import android.text.TextUtils import android.view.LayoutInflater import android.view.ViewGroup import android.widget.FrameLayout import android.widget.TextView import android.widget.Toast import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.callbacks.XC_LoadPackage import net.androidwing.droidsword.utils.LogUtils import java.util.ArrayList/*** Created on 30/10/2017.*/ class ActivityHooker : IHooker {// /frameworks/base/core/java/android/app/Activity.javaoverride fun hook(lp: XC_LoadPackage.LoadPackageParam) {// Hook類android.app.Activity的方法onResume// protected void onResume()XposedHelpers.findAndHookMethod(Activity::class.java, "onResume", object : XC_MethodHook() {override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)// 獲取類方法onResume所屬類Activity的實例對象val activity = param?.thisObject as Activity// 顯示類對象實例Activity的類名稱addTextView(activity)// Hook類Fragment的類方法,獲取類Fragment實例對象的類名稱FragmentHooker().hookFragment(param)}})}// 顯示類對象實例Activity的類名稱private fun addTextView(activity: Activity) {// 獲取類對象實例Activity的類名稱val className = activity.javaClass.name.toString()// 構建TextView實例對象if (sTextView == null) {genTextView(activity)}if (sTextView?.parent != null) {val parent = sTextView?.parentif (parent is ViewGroup) {parent.removeView(sTextView)}}(activity.window.decorView as FrameLayout).addView(sTextView)// 顯示類對象實例Activity的類名稱setActionInfoToMenu(className, "")sTextView?.bringToFront()}// 創建TextView的實例對象private fun genTextView(activity: Activity) {sTextView = TextView(activity)with(sTextView!!) {textSize = 8fy = 48 * 2fsetBackgroundColor(Color.parseColor("#cc888888"))setTextColor(Color.WHITE)layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT)}}companion object {var sTextView: TextView? = nullprivate var sActivityName = ""private var sViewName = ""fun setActionInfoToMenu(activityName: String, viewName: String) {sTextView?.text = getActionInfo(activityName, viewName)}public var sFragmentName = ""private fun getActionInfo(activityName: String, viewName: String): CharSequence? {if (activityName.isEmpty().not()) {sActivityName = activityName}if (viewName.isEmpty().not()) {sViewName = viewName}val pid = android.os.Process.myPid()return "Activity: $sActivityName \nPid: $pid \nClick: $sViewName \nFragment:$sFragmentName"}}DroidSword工具的類FragmentHooker的代碼:
package net.androidwing.droidsword.hookerimport de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedHelpers import de.robv.android.xposed.callbacks.XC_LoadPackage import net.androidwing.droidsword.utils.LogUtils/*** Created on 30/10/2017.*/ class FragmentHooker : IHooker {override fun hook(lp: XC_LoadPackage.LoadPackageParam) {}// /frameworks/support/v4/java/android/support/v4/app/Fragment.javafun hookFragment(param: XC_MethodHook.MethodHookParam?) {// Hook類"android.support.v4.app.Fragment"的方法onResume// public void onResume()XposedHelpers.findAndHookMethod(param?.thisObject?.javaClass?.classLoader?.loadClass("android.support.v4.app.Fragment"),"onResume",object : XC_MethodHook() {override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)// 獲取類Fragment的類名稱ActivityHooker.sFragmentName = (param?.thisObject?.javaClass?.name!!)// 進行類Fragment的類名稱顯示的設置ActivityHooker.setActionInfoToMenu("","")}override fun beforeHookedMethod(param: MethodHookParam?) {super.beforeHookedMethod(param)}})// Hook類"android.support.v4.app.Fragment"的方法setUserVisibleHint// public void setUserVisibleHint(boolean isVisibleToUser)XposedHelpers.findAndHookMethod(param?.thisObject?.javaClass?.classLoader?.loadClass("android.support.v4.app.Fragment"),"setUserVisibleHint", Boolean::class.java,object : XC_MethodHook() {override fun afterHookedMethod(param: MethodHookParam?) {super.afterHookedMethod(param)if (param?.args!![0] == true) {LogUtils.e("fragment showing:")LogUtils.e("fragment ${param?.thisObject?.javaClass?.name}")// 獲取類Fragment的類名稱ActivityHooker.sFragmentName = (param?.thisObject?.javaClass?.name!!)// 進行類Fragment的類名稱顯示的設置ActivityHooker.setActionInfoToMenu("","")}}override fun beforeHookedMethod(param: MethodHookParam?) {super.beforeHookedMethod(param)}})}}總結
以上是生活随笔為你收集整理的Android apk快速定位、灰色按钮克星--DroidSword的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下运行springboot项目
- 下一篇: 如何用VC 2005打开VC 2008的