zoukankan      html  css  js  c++  java
  • 金山手机毒霸工作原理

    本文章由Jack_Jia编写,转载请注明出处。  
    文章链接:
    http://blog.csdn.net/jiazhijun/article/details/8804402

    作者:Jack_Jia    邮箱: 309zhijun@163.com


    一、序言


           金山手机毒霸(http://m.duba.com/)是金山网络推出的首款Android APP行为管理软件,是首家拦截软件恶意广告、智能防御病毒行为、查杀最新病毒和自主管理高危隐私权限的安卓手机安全管理软件。

          它具有如下特色功能:

             1、有效清除软件内置广告,拦截软件恶意广告。

             2、依托于首创的Java虚拟机拦截技术,更精准更深入的拦截APP的高危行为。

          本文将对金山手机毒霸的进行简单的逆向分析,以达到了解其工作原理的目的。金山手机毒霸的最新版本为V2.0,但为了使我们的分析过程简单高效,我们特意选择金山手机毒霸V1.0Beta版本作为分析样本。博友可以通过如下链接下载(http://bbs.xda.cn/thread-11186508-1-1.html)。


    二、基本信息


            1、安装包关键路径文件信息


                  lib\srmeabi\:

              

              

                   res\raw :


                  其中ksremote.mp3、libksrootclient.mp3、rootkeeper.mp3通过后缀名伪装成mp3文件,其实这三个文件为jar包。


                AndroidMainfest.xml:

    [html] view plaincopy
    1. <application android:theme="@style/MainStyle" android:label="@string/app_name_desktop" android:icon="@drawable/main_icon_big" android:name="com.ijinshan.duba.main.MobileDubaApplication" android:allowClearUserData="false" android:debuggable="false">  
    2.     <activity android:label="@string/app_name" android:name="com.ijinshan.duba.main.MainActivity" android:launchMode="singleTask" android:screenOrientation="portrait" />  
    3.     <activity android:name="com.ijinshan.duba.main.SplashActivity" android:clearTaskOnLaunch="true" android:launchMode="singleTop" android:screenOrientation="portrait">  
    4.         <intent-filter>  
    5.             <action android:name="android.intent.action.MAIN" />  
    6.             <category android:name="android.intent.category.LAUNCHER" />  
    7.         </intent-filter>  
    8.     </activity>  
    9.     <activity android:name="com.ijinshan.duba.main.AuthorityActivity" android:screenOrientation="portrait" />  
    10.     <activity android:name="com.ijinshan.duba.AdUI.AdwareNotifyListActivity" android:screenOrientation="portrait" />  
    11.     <activity android:name="com.ijinshan.duba.AdUI.AdPrivacyActivty" android:screenOrientation="portrait" />  
    12.     <activity android:name="com.ijinshan.duba.AdUI.AdScanActivty" android:screenOrientation="portrait" />  
    13.     <activity android:name="com.ijinshan.duba.AdUI.AdwareLogActivty" android:screenOrientation="portrait" />  
    14.     <activity android:name="com.ijinshan.duba.AdUI.AdDetailActivty" android:screenOrientation="portrait" />  
    15.     <activity android:name="com.ijinshan.duba.common.NotifyEntryActivity" android:screenOrientation="portrait" />  
    16.     <activity android:name="com.ijinshan.duba.malware.MalwareActivity" android:screenOrientation="portrait" />  
    17.     <activity android:name="com.ijinshan.duba.malware.ScanResultListActivity" android:screenOrientation="portrait" />  
    18.     <activity android:name="com.ijinshan.duba.malware.VirusDetailActivity" android:screenOrientation="portrait" />  
    19.     <activity android:name="com.ijinshan.duba.defend.defendActivityTest" android:screenOrientation="portrait" />  
    20.     <activity android:name="com.ijinshan.duba.privacy.PrivacyActivity" android:screenOrientation="portrait" />  
    21.     <activity android:name="com.ijinshan.duba.privacy.PrivacyDetailActivity" android:screenOrientation="portrait" />  
    22.     <activity android:name="com.ijinshan.duba.privacy.PrivacySortActivity" android:screenOrientation="portrait" />  
    23.     <activity android:theme="@style/DialogActivityStyle" android:name="com.ijinshan.duba.malware.PcConnectActivity" android:launchMode="singleInstance" android:screenOrientation="portrait">  
    24.         <intent-filter>  
    25.             <action android:name="" />  
    26.         </intent-filter>  
    27.     </activity>  
    28.     <activity android:theme="@style/DialogActivityStyle" android:name="com.ijinshan.duba.watcher.FileInstNoticeActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />  
    29.     <activity android:theme="@style/DialogActivityStyle" android:name="com.ijinshan.duba.watcher.AppLaunchMonitorActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />  
    30.     <activity android:name="com.ijinshan.duba.malware.BadNetActivity" android:screenOrientation="portrait" />  
    31.     <activity android:name="com.ijinshan.duba.main.ShowProtocolActivity" android:screenOrientation="portrait" />  
    32.     <activity android:name="com.ijinshan.duba.defend.Activity.IngnoreAppActivity" android:screenOrientation="portrait" />  
    33.     <activity android:theme="@style/DialogActivityStyle" android:name="com.ijinshan.duba.main.ShowRestartTipDialog" android:launchMode="singleInstance" android:screenOrientation="portrait" />  
    34.     <service android:name="com.ijinshan.duba.service.PcConnectService">  
    35.         <intent-filter>  
    36.             <action android:name="" />  
    37.         </intent-filter>  
    38.     </service>  
    39.     <service android:name="com.ijinshan.duba.defend.DefendService" android:exported="false" android:process=":DefendService" />  
    40.     <receiver android:name="com.ijinshan.duba.receiver.AutoRunReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" android:exported="false">  
    41.         <intent-filter>  
    42.             <action android:name="android.intent.action.BOOT_COMPLETED" />  
    43.             <category android:name="android.intent.category.DEFAULT" />  
    44.         </intent-filter>  
    45.     </receiver>  
    46.     <receiver android:name="com.ijinshan.duba.receiver.ShutdownReceiver">  
    47.         <intent-filter>  
    48.             <action android:name="android.intent.action.ACTION_SHUTDOWN" />  
    49.         </intent-filter>  
    50.     </receiver>  
    51.     <provider android:name="com.ijinshan.duba.main.DubaConfigProvidor" android:exported="false" android:authorities="com.ijinshan.duba.config" />  
    52.     <provider android:name="com.ijinshan.duba.Provider.AdRuleProvidor" android:exported="false" android:process=":DefendService" android:authorities="com.ijinshan.duba.adrule" />  
    53.     <provider android:name="com.ijinshan.duba.Provider.MalwareDBProvidor" android:exported="false" android:process=":DefendService" android:authorities="com.ijinshan.duba.malwaredb" />  
    54. </application>  


               2、手机毒霸运行时涉及进程及进程组件分布


                    通过对手机毒霸代码逆向分析及运行时进程状态变化,金山手机毒霸代码共在四类进程中被加载运行。


                    (1)com.ijinshan.duba 进程


                              广告扫描引擎、病毒扫描引擎、金山版本控制等逻辑都在该进程中运行,

                              另外手机毒霸还在15997端口建立监听,PC端可以通过该TCP连接发送命令手机端毒霸扫描。



                  

               (2)com.ijinshan.duba:DefendService进程


                       广告规则和扫描病毒信息由该进程通过Provider提供。


                          

                         


               (2)com.ijinshan.duba.rootkeeper进程

                        

                       该进程以ROOT身份运行,该进程提供了手机毒霸其它进程运行需要root身份才能执行的命令的Binder接口,第三方程序进程的代码注入由该进程完成。


                         


               (4)第三方(injected process)被注入程序进程


                       通过ptrace()注入到第三方程序的代码,ksremote.jar和libksrootclient.so完成java虚拟机hook和底层Socket hook。


                  


    三、JAVA虚拟机hook实现原理

             

           目前Android进程代码的注入都是靠ptrace函数来完成。ptrace进程后完成底层函数的重定向。金山毒霸代码注入包括两部分:


                1、底层C函数HOOK

                2、JAVA虚拟机HOOK


           代码注入基本流程如下:


                1、com.ijinshan.duba.rootkeeper进程ptrace第三方进程,并注入libksrootclient.so文件

                2、libksrootclient.so代码完成底层C函数hook并调用ksremote.jar代码,ksremote.jar完成java虚拟机hook

                      (1)C代码如何完成对java代码的调用呢?


                         基本代码实现如下:

    1. int (*callStatic)(const char* className, const char* methodName);  
    2.        JavaVM* (*getJavaVM)();  
    3.        JNIEnv* (*getJNIEnv)();  
    4.   
    5. void* handle = dlopen("/system/lib/libandroid_runtime.so", RTLD_NOW);  
    6.   
    7. getJNIEnv = dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv");  
    8.        JNIEnv* env = getJNIEnv();  
    9.           
    10.        jclass classloaderClass = (*env)->FindClass(env,"java/lang/ClassLoader");  
    11.        jmethodID getsysloaderMethod = (*env)->GetStaticMethodID(env,classloaderClass<span style="font-family: Arial, Helvetica, sans-serif;"> </span>, "getSystemClassLoader""()Ljava/lang/ClassLoader;");  
    12.        jobject loader = (*env)->CallStaticObjectMethod(env, classloaderClass, getsysloaderMethod);  
    13.   
    14.        jstring dexpath = (*env)->NewStringUTF(env, "dex文件路径");  
    15.        jstring dex_odex_path = (*env)->NewStringUTF(env,"odex文件路径");  
    16.        jclass dexLoaderClass = (*env)->FindClass(env,"dalvik/system/DexClassLoader");  
    17.        jmethodID initDexLoaderMethod = (*env)->GetMethodID(env, dexLoaderClass, "<init>""(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");  
    18.        jobject dexLoader = (*env)->NewObject(env, dexLoaderClass, initDexLoaderMethod,dexpath,dex_odex_path,NULL,loader);  
    19.   
    20.        jmethodID findclassMethod = (*env)->GetMethodID(env,dexLoaderClass,"findClass","(Ljava/lang/String;)Ljava/lang/Class;");   
    21.        jstring javaClassName = (*env)->NewStringUTF(env,"加载类名");  
    22.        jclass javaClientClass = (*env)->CallObjectMethod(env,dexLoader,findclassMethod,javaClassName);  
    23.        jmethodID start_inject_method = (*env)->GetStaticMethodID(env, adInjectClient_class, "调用方法名""()V");  
    24.        (*env)->CallStaticVoidMethod(env,javaClientClass,start_inject_method);  
                  

                   (2)java虚拟机hook如何实现呢?


                           java虚拟机hook都是通过java反射修改系统关键类的关键字段来实现的,我们通过替换LocationManager来看看如何实现的:



                        

                           


        当用户代码运行ServiceManager.getService("location")的时候,得到就是手机毒霸的LocationManager了。


    三、广告拦截原理


           广告拦截逻辑大致包含以下几个方面:

           1、Banner类型广告

                 当Activity显示的时候,手机毒霸遍历Activity View树,判断View类包名是否为广告平台包名,如果是则添加手机毒霸广告关闭图标,当用户点击关闭图标时,隐藏Banner          广告View。

           2、WebView类型广告

               判断WebViewClient类名判断是否为广告。

           3、Notification类型广告

               主要是通过RemoteViews的action来判断是否为广告。



             另外手机毒霸通过hook Socket接口来完成广告的拦截,通过网络层的拦截来完成广告的拦截。
  • 相关阅读:
    XAMPP安装和配置
    Myeclipse下使用Maven搭建spring boot2.0项目
    activemq学习总结 (转)Java消息队列--ActiveMq 实战
    websocket学习总结
    Redis学习总结
    (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片
    当网卡收到的包的目的地址是主机上另一个网卡的地址.arp总结
    当网卡收到一个包的目的地址是本主机其他接口的IP时.2
    网络设置中设置失败
    当网卡收到一个包的目的地址不是自己的地址时
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959798.html
Copyright © 2011-2022 走看看