当前位置: 首页 > 科技观察

AndroidHOOK工具CydiaSubstrate详解

时间:2023-03-13 21:31:56 科技观察

CydiaSubstrate是一个代码修改平台。它可以修改任何主进程的代码,无论是用Java还是C/C++(本机代码)编写的。而Xposed只支持HOOKapp_process中的java函数,所以CydiaSubstrate是一款强大实用的HOOK工具。官网地址:http://www.cydiasubstrate.com/演示地址:https://github.com/zencodex/cydia-android-hook官方教程:http://www.cydiasubstrate.com/id/20cf4700-6379-4a14-9bc2-853fde8cc9d1SDK下载地址:http://asdk.cydiasubstrate.com/zips/cydia_substrate-r2.zipSubstrate介绍几个重要的APIMS.hookClassLoad函数原型:voidhookClassLoad(Stringname,MS.ClassLoadHookhook);此方法在加载指定类时实现通知。因为类可以随时加载,所以Substrate提供了一种方法来检测何时加载了用户感兴趣的类。参数说明name包名+类名,使用java的.symbolhookMS.ClassLoadHook的一个实例,当这个类被加载时,它的classLoaded方法就会被执行。MS.hookMethod这个API允许开发者提供一个回调函数来替换原来的方法。这个回调函数是一个实现了MS.MethodHook接口的对象,是一个典型的匿名内部类。它包含一个调用的函数。函数原型:voidhookMethod(Class_class,Membermember,MS.MethodHookhook,MS.MethodPointerold);voidhookMethod(Class_class,Membermember,MS.MethodAlterationalteration);参数说明(1)参数说明_classloadedtargetClass,即classLoaded传下来的类参数成员。需要hook的方法(或构造函数)是通过反射获取的。注意:HOOK字段是不能勾选的(编译时会检测到)。hookMS.MethodHook的一个实例,包含被调用的方法将被调用以替换成员中的代码(2)参数说明_class加载的目标类,从classLoaded传下来的类参数成员需要通过反射挂钩的方法(或构造函数)。注意:不能使用HOOK域(编译时会检测到)。alterationMS.MethodAlteration的实例,其boxedinvoked方法将被调用而不是成员。该实例也将使用原始实现中的信息填充,允许您使用invoke调用原始方法实现。推荐开发者使用第二种方法,使用简单,很少出错,而且不需要单独实例化MS.MethodPointer类。下面使用方法以官网为例来说明cydiasubstrate的使用。本例是将多个界面组件的颜色改为紫色。需要安装:http://www.cydiasubstrate.com/download/com.saurik.substrate.apk第一步:创建一个空的Android工程。由于创建的项目会以插件的形式加载,所以不需要activity。将SDK中的substrate-api.jar复制到project/libs文件夹下。第二步:配置Manifest文件(1)需要指定权限:cydia.permission.SUBSTRATE(2)添加meta标签,名称为cydia.permission.SUBSTRATE,值为下一步创建的类名.Main第2步:创建一个名为Main的类。该类包含一个静态方法初始化。当插件加载完成后,该方法中的代码就会运行,完成一些必要的初始化工作。导入com.saurik.substrate.MS;publicclassMain{staticvoidinitialize(){//...codetorunwhenextensionisloaded}}第三步:为了实现HOOK,达到修改目标类中代码的目的,我们需要获取目标类的一个实例,如示例在资源中。publicclassMain{staticvoidinitialize(){MS.hookClassLoad("android.content.res.Resources",newMS.ClassLoadHook(){publicvoidclassLoaded(Classresources){//...codetomodifytheclasswhenloaded}});}}步骤4:对原代码的修改是通过MS.MethodHook实例实现的。为了调用原代码中的方法,我们需要创建一个MS.MethodPointer类的实例,它可以随时运行原代码。这里我们通过调用和修改原代码中资源对象的原代码,将所有的绿色都变成了紫色。publicvoidclassLoaded(Classresources){MethodgetColor;try{getColor=resources.getMethod("getColor",Integer.TYPE);}catch(NoSuchMethodExceptione){getColor=null;}if(getColor!=null){finalMS.MethodPointerold=newMS.MethodPointer();MS.hookMethod(resources,getColor,newMS.MethodHook(){publicObjectinvoked(Objectresources,Object...args)throwsThrowable{intcolor=(Integer)old.invoke(resources,args);returncolor&~0x0000ff00|0x00ff0000;}},old);}}安装运行,重启系统后,很多字体颜色都变了。如下图所示:例子中MS.hookMethod的代码可以改成:throwsThrowable{intcolor=invoke(resources,args);returncolor&~0x0000ff00|0x00ffee00;}});短信监听示例下面的例子中,我们实现了短信监听功能,并打印出短信的发件人、收件人和短信内容:1importjava.lang.reflect.方法;2importandroid.app.PendingIntent;3importandroid.util.Log;4importcom.saurik.substrate.MS;567publicclassMain{89staticvoidinitialize(){1011MS.hookClassLoad("android.telephony.SmsManager",newMS.ClassLoadHook(){121314@Override1516Loadedublic类SmsManager){1718//加载时修改类的代码1920MethodsendTextMessage;2122try{2324sendTextMessage=SmsManager.getMethod("sendTextMessage",2526newClass[]{String.class,String.class,String.class,PendingIntent.class,PendingIntent.class});272829}catch(NoSuchMethodExceptione){3031sendTextMessage=null;3233}3435MS.hookMethod(SmsManager,sendTextMessage,newMS.MethodAlteration(){3637publicObjectinvoked(Object_this,Object..._args)throwsThrowable{3839Log.i("SMSHOOK","SEND_SMS");4041Log.i("SMSHOOK","destination:"+_args[0]);4243Log.i("SMSHOOK","source:"+_args[1]);4445Log.i("SMSHOOK","text:"+_args[2]);4647returninvoke(_this,_args);4849}5051});525354}5556});5758}5960}运行后的结果为: