本篇是《Android逆向入门教程》的第八章第1.2节,具体课程详情可点击下方图片查看:
每一章节详细内容及实验材料可通过加入底部免费的【Android逆向成长计划】星球获得!
声明:所有实验含部分虚构,纯属技术练习,未对真实环境造成任何影响。也请勿将相关技术用于非法操作,否则责任自负。
0x01 Hook修改变量
在编写hook类的时候会去实现一个IXposedHookLoadPackage接口(加载应用程序,即“ Android软件包”时获得通知), 重写了handleLoadPackage方法(加载应用程序时将调用此方法),该方法有一个参数lpparam(有关该应用程序的信息), 这个方法向被实现的模块提供更多关于运行环境上下文的信息。首先我们实验的app是一款编写好的XposedDemo,将其安装到模拟器上,打开运行后没有任何效果,如图所示:
使用jadx-gui反编译工具查看其代码,注意在一个Activity在启动的时候,都会在onCreat()方法中执行setContentView(R.layout.activity_main)这行代码,来将指定的资源xml文件加载到对应的activity中。
然后定位到res/layout/activity_main.xml,可以发现当我们点击button的时候会触发myTest方法,回到MainActivity,跟进myTest()的Demo类。
经过分析test()方法可以发现,当我们点击按钮时会在日志中输出很多对应的日志信息,其中包括静态变量staticInt = 100,注意静态全局变量hook的时候调用的是使用的XposedHelpers.setStaticIntField(),若是全局普通变量用XposedHelpers.setIntField()。
我们再次运行app点击按钮,不过此次打开我们的ddms查看日志输出。
然后编写hook代码如下:
import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; import android.util.Log;
public class Hook implements IXposedHookLoadPackage { public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable { Log.d("feichen", "hook..."); //日志输出方式一 XposedBridge.log("Loaded app: " + lpparam.packageName); //日志输出方式二 if (lpparam.packageName.equals("com.feichen.xposeddemo")){ final Class clazz = XposedHelpers.findClass("com.feichen.xposeddemo.Demo",lpparam.classLoader); XposedHelpers.setStaticIntField(clazz,"staticInt",520); } } } |
将写好的xposed编译安装到xposed后,勾选上写好的xposed模块,并重启手机,然后运行app,打开ddms,点击button按钮,查看ddms中的staticInt初始化值已经被我们hook修改为520,如图:
然后hook字符串变量的话使用XposedHelpers.setStaticObjectField(clazz,"Tag","Lvmeng");这一条语句,具体的效果这里不再演示,有兴趣的小伙伴下去可以自己尝试。
0x02 Hook普通方法
Hook普通方法使用的是XposedHelpers下的findAndHookMethod(类的字节码,方法名,回调函数)方法(用于Hook当前类下的所有方法),它有一个重载函数接收四个参数,
findAndHookMethod(类名全路径,类加载器,方法名,回调函数),其中回调函数除了使用
XC_MethodHook()之外,还有XC_MethodReplacement()。对于有参数的函数需要带上参数的字节码。在0x03的地方就是四个参数的findAndHookMethod。
因此,Hook普通方法的代码如下:
XposedHelpers.findAndHookMethod(clazz, "test", new XC_MethodHook(){ public void beforeHookedMethod(MethodHookParam param){ Log.d("Lvmeng","Lvmeng===============before"); } public void afterHookedMethod(MethodHookParam param){ Log.d("Lvmeng","Lvmeng=============after"); } }); |
其中beforeHookedMethod 会在调用原方法前执行,如果使用setResult则跳过原方法,并返回setResult参数中的值。
afterHookedMethod 会在调用原方法后执行,setResult可改变返回值。
replaceHookedMethod 会完全替换原方法,即原方法不执行,且返回值可以直接return,setResult不生效。
然后将写好的xposed编译安装到xposed后,勾选上写好的xposed模块,并重启手机,然后运行app,打开ddms,点击button按钮,查看ddms中日志情况如下,可以发现test()函数已经被成功hook,并且添加上两条日志信息
0x03 Hook获取参数与返回值
Hook获取参数是方法中要传入的参数,我们也是可以在beforeHookedMethod和afterHookedMethod方法中获取我们的参数值,其hook代码如下:
XposedHelpers.findAndHookMethod(clazz, "publicFunc",String.class, new XC_MethodHook(){ public void beforeHookedMethod(MethodHookParam param){ Log.d("Lvmeng","Lvmeng===============before"); Log.d("before-获取参数", ""+param.args[0]); } public void afterHookedMethod(MethodHookParam param){ Log.d("Lvmeng","Lvmeng=============after"); Log.d("after-获取参数", ""+param.args[0]); } }); |
其中,我们hook的方法是publicFunc,查看代码可以发现该方法是接收参数的,如图所示:
然后安装运行后的日志信息如下:
Hook获取返回值一般都是在afterHookedMethod方法中,Hook的代码如下:
public void afterHookedMethod(MethodHookParam param){
Log.d("Lvmeng", ""+param.getResult());
}
在这里不再进行演示获取返回值,有兴趣的小伙伴可以下去自行测试。
0x04 Hook构造函数
Hook构造函数可分为有参构造函数前、无参构造函数前、有参构造函数后和无参构造函数后。这里Hook构造函数使用的是XposedHelpers下的findAndHookConstructor,详细代码如下:
XposedHelpers.findAndHookConstructor(clazz, new XC_MethodHook() {
public void beforeHookedMethod(MethodHookParam param) throws Throwable { Log.d("===================", "这是无参构造函数前"); }
public void afterHookedMethod(MethodHookParam param) throws Throwable { Log.d("===================", "这是无参构造函数后"); XposedHelpers.setIntField(param.thisObject, "publicInt", 20000000); } });
XposedHelpers.findAndHookConstructor(clazz, String.class, new XC_MethodHook() { public void beforeHookedMethod(MethodHookParam param) throws Throwable { Log.d("===================", "这是有参构造函数前"); param.args[0] = "= - ="; }
public void afterHookedMethod(MethodHookParam param) throws Throwable { Log.d("===================", "这是有参构造函数后"); } }); |
然后安装运行后的Hook日志如下:
获取《Android逆向入门教程》前7章打包下载链接:
链接: https://pan.baidu.com/s/1_Ab94XhTVlama1ZXNnBdYw 密码: ri7n
团队公开知识库链接:
https://www.yuque.com/books/share/f7515884-c39f-4d2b-ab15-55921c8205b8?# 《WhITECat公开知识积累》密码:kstn(重新开放)
知识星球:
原文始发于微信公众号(WhITECat安全团队):Android逆向(前7章打包下载)|Xposed Hook(上)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论