写这篇随笔,是因为最近在分析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差不多,只需要改包名即可。