寫這篇隨筆,是因為最近在分析apk的某些功能代碼時,老是要找相應按鈕的監聽函數。作為一個沒多少經驗的生手,我一開始是在jeb左上角目錄的public.xml中查找可能的按鈕的id號對應的名稱,如發送消息的按鈕,就找帶 “send” 字符的id名稱,雖然最后也能找到,但太費力了,效率也很低,作為新手想熟悉環節可以試一下。
一開始就想找個快捷的方法獲得按鈕的監聽函數,但苦於沒轍,也聽很多人說可以用hook工具來獲得按鈕id,但當時理解還不深。這里就不記怎么使用xposed Hook框架了,這個框架是神器,Java逆向程序員必備。以前的理解是hook onClick函數,每次點擊onClick就可以看到按鈕的信息,但會hook不到,因為該函數所在的類是View.OnClickListener,是一個interface接口類,不能被hook。那只能hook onClick外一層的函數setOnClickListener了,它所在的類是Button,這個函數的this指針就是Button類了,以此可以獲得按鈕的名稱和id,這時hook的只能出現一次了,隨着界面的出現而出現,所以這是必須時按鈕名稱和id一起打印出才能具體是哪個按鈕和按鈕的id。
一般的安卓手機或者安卓虛擬機,我們習慣都會將其改成中文語言,在輸出按鈕名稱時,可能會出現亂碼,因為會字符集不匹配,解決這個問題1)可以調整字符集,2)改安卓手機或者安卓虛擬機的語言為英語,對應apk的名稱便會是英文,然后就能直接打印出正常的英文名稱。
hook 的主要代碼如下:
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
Log.v("MypackageName", lpparam.packageName);
if (!lpparam.packageName.equals("com.***")){//包名是自己分析的apk包名
return;
}
findAndHookMethod(View.class ,"setOnClickListener", OnClickListener.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { View view = (View)param.thisObject; //ImageView String Str = null; if (view instanceof TextView){//也有可能是ImageView,所以得判斷一下 Str = ((TextView)view).getText().toString(); } int btnId = view.getId(); Log.i("ButtonInfo", Str + " " + btnId); XposedBridge.log(Str + ";" + "Id:" + btnId); } }); }
其它的跟普通的xposed hook差不多,只需要改包名即可。命令:adb shell dumpsys activity top 獲得按鈕所在的界面Activity.