XposedHook:hook敏感函数

来源:互联网 发布:淘宝网上有卖烟的吗 编辑:程序博客网 时间:2024/05/16 16:05

Xposed框架

Xposed框架通过修改Android系统的源码,并替换Android的主程序Zygote(Init 是所有Linux程序的起点,而Zygote于Android,正如它的英文意思,是所有java程序的’孵化池’),从而能够控制Android进程的执行流程,hook java层的API。xposed的具体解析可以参考深入理解Android(三):Xposed详解

首先在app_main.cpp中,对appRuntime.cpp进行了修改,其中onVmCreated(JNIEnv* env)修改如下:

在onVmCreate中,它将调用libxposed_dalvik.so中的xposedInitLib函数,然后再调用so中设置的onVmCreated函数。这个onVmCreated函数由xposedInitLib设置。

在app_main.cpp的main方法中,进行了对xposed的环境初始化:

最后,如果xposed框架启用成功,那么zygote的入口类将由以前的com.android.internal.os.ZygoteInit变成de.robv.android.xposed.XposedBridge。

下面我们按照执行流程,把相关函数分析一遍:

AppRuntime的onVmCreated,它最终会导致libxposed_dalvik.so中的onVmCreated被调用。我们直接分析最后这个onVmCreated。

然后AppRuntime里会调用de.robv.android.xposed.XposedBridge.main函数。

所以通过调用XposedBridge.main函数,可以给APK进程的一些特定函数挂上钩子,从而能够监听该函数,进而通过beforeHookedMethod和afterHookedMethod方法可以分别实现调用函数前的操作和调用函数后的操作。


Hook用到的具体函数

下面给出我在做Android恶意程序分析时需要hook的函数的一些操作,该程序参考了halfkiss的框架。

  • 用到的Xposed的函数: 首先定义一个抽象类MethodHookCallBack继承自Xposed的XC_MethodHook类,该类有两个方法:beforeHookedMethod(MethodHookParam param)和AfterHookedMethod(MethodHookParam param)方法,这两个方法分别对应于要hook的函数调用之前所要执行的动作与该函数调用之后所要执行的动作。比如:
    public void beforeHookedMethod(MethodHookParam param)    {            Log.i("Before hook");    }

上面的例子说明在调用要hook的函数之前打印一段log为Before hook。

  • Xposed的hook的主函数hookMethod(Member hookMethod, XC_MethodHook callback),其中参数hookMethod表示要hook的函数,该函数可以通过java的反射机制获得,具体怎么获得在下面会讲到,参数callback就是前面讲到的Xposed函数的XC_MethodHook类,该类主要是表示该对要hook的函数做怎样的处理。具体的hookMethod方法如下图所示:

由hookMethod可知,一个目标函数可以挂多个钩子,这些钩子由一个集合来存储。然后我们将转到JNI层去看看hookMethodNative干了什么事情。这才是hook的核心。分析如下图所示:

所以当apk执行被hook的函数时,实际执行的是hookMethodCallBack函数,该函数就是钩子函数,我们来看看hookmethodCallBack函数具体是怎么执行的,该函数在libXposed_dalvik.cpp中。

在xposedHandleHookedMethod函数中会以此执行钩子函数,即在前面介绍的XC_MethodHook函数,然后再会执行程序的原函数。

在此,Hook需要用到的基本函数已经介绍完毕。接下来会介绍如何利用Xposed来实现hook敏感函数的操作。


hook敏感函数

  • 首先定义MethodHookCallBack类继承自XC_MethodHook,该函数实现了beforeHookedMethod和afterHookedMethod函数,主要是获得HookParam类,该类主要是存储了一些MethodHookParam的一些参数。然后调用该类中beforeHookedMethod(HookParam param)或者afterHookedMethod(HookParam param)。
    public abstract class MethodHookCallBack extends XC_MethodHook {            @Override            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {                // TODO Auto-generated method stub                super.beforeHookedMethod(param);                HookParam hookParam = HookParam.fromXposed(param);                this.beforeHookedMethod(hookParam);                if(hookParam.hasResult())                    param.setResult(hookParam.getResult());            }            @Override            protected void afterHookedMethod(MethodHookParam param) throws Throwable {                // TODO Auto-generated method stub                super.afterHookedMethod(param);                HookParam hookParam = HookParam.fromXposed(param);                this.afterHookedMethod(hookParam);                if(hookParam.hasResult())                    param.setResult(hookParam.getResult());            }            public abstract void beforeHookedMethod(HookParam param);            public abstract void afterHookedMethod(HookParam param);        }
  • 根据字符串找到要hook的函数,主要是利用java的反射函数,如果有兴趣的可以去查阅一下java的反射机制,主要是通过字符串来得到相应的类,函数或变量等,具体代码如下:
    public static Method findMethod(String className, ClassLoader classLoader, String methodName,                Class<?>... parameterTypes)        {            try {            Class clazz = classLoader.loadClass(className);            Method method = clazz.getDeclaredMethod(methodName, parameterTypes);            method.setAccessible(true);            return method;        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return null;    }

我们通过该方法可以获得要hook的具体method。

  • 定义抽象类AbstractBahaviorHookCallBack继承自前面讲到的MethodHookCallBack类,该类具体实现当调用要hook的函数时,就打印该函数。具体实现如下:
    public abstract class AbstractBahaviorHookCallBack extends MethodHookCallBack {        @Override        public void beforeHookedMethod(HookParam param) {            // TODO Auto-generated method stub            /*int length = param.args.length;            Object[] m = param.args;            String args = "/";            for(int i = 0; i < length;i++)            {                args+=(String)m[i]+"/";            }*/            Logger.logD("Invoke "+ param.method.getDeclaringClass().getName()+"->"+param.method.getName());            this.descParam(param);            //this.printStackInfo();        }        @Override        public void afterHookedMethod(HookParam param) {            // TODO Auto-generated method stub            //Logger.log_behavior("End Invoke "+ param.method.toString());        }        private void printStackInfo(){            Throwable ex = new Throwable();            StackTraceElement[] stackElements = ex.getStackTrace();            if(stackElements != null){                StackTraceElement st;                for(int i=0; i<stackElements.length; i++){                    st = stackElements[i];                    if(st.getClassName().startsWith("com.android.binpang")||st.getClassName().startsWith("de.robv.android.xposed.XposedBridge"))                        continue;                    Logger.logD(st.getClassName()+":"+st.getMethodName()+":"+st.getFileName()+":"+st.getLineNumber());                }            }        }        public abstract void descParam(HookParam param);}
  • 具体要实现的hook函数
    Method sendTextMessagemethod =  FindMethod.findMethod(                    "android.telephony.SmsManager", ClassLoader.getSystemClassLoader(),                    "sendTextMessage", String.class,String.class,String.class,PendingIntent.class,PendingIntent.class);            hookhelper.hookMethod(sendTextMessagemethod, new AbstractBahaviorHookCallBack() {                @Override                public void descParam(HookParam param) {                    // TODO Auto-generated method stub                    Logger.logI("Send SMS ->");                    String dstNumber = (String)param.args[0];                    String content = (String)param.args[2];                    Logger.logI("SMS DestNumber:"+dstNumber);                    Logger.logI("SMS Content:"+content);                }            });

该示例函数是hook了android.telephony.SmeManager/sendTextMessage函数,当调用该函数的时候,会打印出来要发送的目标号码,及发送的message的内容。

  • 监听的敏感函数列表

SmsManager

  1. android.telephony.SmsManager/sendTextMessage
  2. android.telephony.SmsManager/getAllMessagesFromIcc
  3. android.telephony.SmsManager/sendDataMessage
  4. android.telephony.SmsManager/sendMultipartTextMessage

TelephonyManager

  1. android.telephony.TelephonyManager/getLine1Number
  2. android.telephony.TelephonyManager/listen

AccountManager

  1. android.accounts.AccountManager/getAccounts
  2. android.accounts.AccountManager/getAccountsByType

ActivityManager

  1. android.app.ActivityManager/killBackgroundProcesses
  2. android.app.ActivityManager/forceStopPackage

AlarmManager

  1. android.app.AlarmManager/setImpl

AudioRecord

  1. android.media.AudioRecord

Camera

  1. android.hardware.Camera/takepicture
  2. android.hardware.Camera/setPreviewCallback
  3. android.hardware.Camera/setPreviewCallbackWithBuffer
  4. android.hardware.Camera/setOneShotPreviewCallback

ConnectivityManager

  1. android.net.ConnectivityManager/setMobileDataEnabled

ContentResolver

  1. android.content.ContentResolver/qurey
  2. android.content.ContentResolver/registerContentObserver
  3. android.content.ContentResolver/insert
  4. android.content.ContentResolver/bulkInsert
  5. android.content.ContentResolver/delete
  6. android.content.ContentResolver/update
  7. android.content.ContentResolver/applyBatch

ContextImpl

  1. android.app.ContextImpl/registerReceiver

MediaRecorder

  1. android.media.MediaRecorder/start
  2. android.media.MediaRecorder/stop

Internet

  1. java.net.URL/openConnection
  2. org.apache.http.impl.client.AbstractHttpClient/execute

NotificationManager

  1. android.app.NotificationManager/notify

ApplicationPackageManager

  1. android.app.ApplicationPackageManager/installPackage
  2. android.app.ApplicationPackageManager/deletePackage
  3. android.app.ApplicationPackageManager/getInstalledPackages

Xposed编程步骤

  • 首先在xposedbridgeapi.jar包导入到项目中,这里采用了XposedBridgeApi-54.jar包
  • 再项目的assets文件夹中新建一个xposed_init文件(没有后缀),该文件表示该xposed模板的主函数类的具体路径,比如该项目为

  • 在AndroidManifest.xml文件的标签下添加xposed的一些信息,以便Xposed能够识别该模板。
    <?xml version="1.0" encoding="utf-8"?>    <manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.methodhook"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk    android:minSdkVersion="18"    android:targetSdkVersion="21" />    <application    android:allowBackup="true"    android:icon="@drawable/ic_launcher"    android:label="@string/app_name"    android:theme="@style/AppTheme" >    <activity    android:name="com.binpang.methodhook.MainActivity"    android:label="@string/app_name" >    <intent-filter>    <action android:name="android.intent.action.MAIN" />    <category android:name="android.intent.category.LAUNCHER" />    </intent-filter>    </activity>    <meta-data    android:name="xposedmodule"    android:value="true" />    <meta-data    android:name="xposedminversion"    android:value="40" />    <meta-data    android:name="xposeddescription"    android:value="Monitor the System's apis" />    </application>    </manifest>
  • 在Android手机(或模拟器,建议使用模拟器,一般的模拟器都已经root过了)中安装XposedInstaller(需要root权限), 由于Xposed替换了Android的一些程序,所以需要重启才能生效。
  • 然后启动该模板程序,使其安装到Android手机中,然后再Xposed的模板中找到它,并打钩,如图所示:

演示hook结果

通过短信软件向5554号码发送”hello,world”内容,如图所示:

结果查找logcat如图所示:


具体可以参考我的github

0 0
原创粉丝点击