美文网首页PythonPython学习程序员
Python之利用机器学习检测安卓恶意软件实现(一)

Python之利用机器学习检测安卓恶意软件实现(一)

作者: CaptainXero | 来源:发表于2016-09-27 09:48 被阅读1992次

    前言

    上一篇文章写了如何使用Python写一个简单的爬虫,批量抓取APK的下载链接。这篇文章记录下如何批量拆包APK文件并提取想要的信息。

    准备工作

    • Androguard环境部署:Androguard下载
    • 在上一篇文章提到的准备工作的基础上,这篇文章需要加入Androguard作为环境。Androguard是一款开源的Android应用程序分析工具,使用Python编写。众多功能模块以Python包的形式存在。
    • 使用方法:首先将GitHub上的Androguard项目下载下来。
    下载Androguard.png

    下载完成后得到一个压缩包,解压后进入目录,把Androguard目录下所有的文件拷贝至Python的根目录下,合并同名文件夹即可。

    • 检查环境是否部署成功:
      打开cmd命令行,输入python进入交互状态。输入from androguard.core.bytecodes import apk, dvm如下图所示没有提示任何错误信息即可。
    检查环境.png

    注意:在cmd下直接调python命令行需要将Python加入到环境变量中。

    基础知识

    首先APK文件可以用普通解压缩的方式拆包,如下图。

    解压完毕.png

    熟悉安卓开发的人肯定对解压完毕后的文件很熟悉。这里主要介绍部分文件的作用。

    • 1.assets文件:这里存放一些资源文件入图片等,一半情况下解压缩完毕后是可以直接看到这些图片的。
    assets.png
    • 2.lib文件:这里存放安卓开发中使用到的库文件
    库文件.png
    • 3.AndroidManifest文件:这是我们这次需要关注的重点。一个安卓应用需要申请的权限信息,以及Activity等组件的注册信息都需要在AndroidMainfest.xml文件中声明。但是直接解压后的AndroidManifest文件查看确是如下这种情况:
    乱码.png

    没错,是乱码。这就说明仅仅使用将APK解压缩的形式去获得我们关心的信息是不可行的。

    使用Python获取APK信息

    到此为止,相信大家对APK的结构有了一定了解。下面以获取APP申请权限为例子使用Python完成APK的拆包提取信息。

    • 首先附上Androguard开发文档:Androguard开发API
    • Androguard是开源的,有兴趣的朋友可以去阅读源码。这里不过多赘述Androguard实现原理,我们从目的入手,直接使用Androguard。
    • 首先在新建的Python工程中引包from androguard.core.bytecodes import apk, dvm
    • 接着调用APIapp.get_permissions()
    • 没错,Androguard就是这么强大,一个API就完成了拆包提权操作。那么为了实现批量拆包提权(以及提取其他信息),我们必须自己编写一个Python脚本。
    • 思路很明了,利用Python写一个遍历文件夹中所有文件的脚本,对每个apk文件执行相应的操作即可。为了让脚本清晰,这里把调取API和遍历文件夹放在两个脚本中。
      首先附上调用Androguard中API获取各种信息的代码:
    __author__ = 'Administrator'
    #coding=utf-8
    from androguard.core.bytecodes import apk, dvm
    from androguard.core.analysis import analysis
    import re
    global count
    count = 1
    
    def get_permissions(path, filename):
        str = "Permission:"
        app = apk.APK(path)
        permission = app.get_permissions()
        file = permission
        print permission
        writeToTxt(str, file, filename)
        return permission
    
    def get_apis(path, filename):
      app = apk.APK(path)
      app_dex = dvm.DalvikVMFormat(app.get_dex())
      app_x = analysis.newVMAnalysis(app_dex)
      methods = set()
      cs = [cc.get_name() for cc in app_dex.get_classes()]
    
      for method in app_dex.get_methods():
        g = app_x.get_method(method)
        if method.get_code() == None:
          continue
    
        for i in g.get_basic_blocks().get():
          for ins in i.get_instructions():
            output = ins.get_output()
            match = re.search(r'(L[^;]*;)->[^\(]*\([^\)]*\).*', output)
            if match and match.group(1) not in cs:
              methods.add(match.group())
    
      methods = list(methods)
      methods.sort()
      print "methods:"+"\n"
      print methods
      str = "Methods:"
      file = methods
      writeToTxt(str, file, filename)
      return methods
    def get_providers(path, filename):
        app = apk.APK(path)
        providers = app.get_providers()
        print "providers:"+"\n"
        print providers
        str = "Providers:"
        file = providers
        writeToTxt(str, file, filename)
        return providers
    def get_package(path, filename):
        app = apk.APK(path)
        packname = app.get_package()
        print "packageName:"+"\n"
        print packname
        str = "PackageName:"
        file = packname
        writeToTxt(str, file, filename)
        return packname
    def get_activities(path, filename):
        app = apk.APK(path)
        activitys = app.get_activities()
        print "ActivityName:"+"\n"
        print activitys
        str = "Activitys:"
        file = activitys
        writeToTxt(str, file, filename)
        return activitys
    def get_receivers(path, filename):
        app = apk.APK(path)
        receivers = app.get_receivers()
        print "Receivers:"+"\n"
        print receivers
        str = "Receivers:"
        file = receivers
        writeToTxt(str, file, filename)
        return receivers
    def get_services(path, filename):
        app = apk.APK(path)
        services = app.get_services()
        print "Services:"+"\n"
        print services
        str = "Services:"
        file = services
        writeToTxt(str, file, filename)
        return services
    def writeToTxt(str, file, filename):
        global count
        fm = open('%d'%count+'.txt', 'w')
        #fm.write(str)
        #fm.write("\n")
        for i in file:
            tmp = i.split('.')
            final = tmp[-1]
            fm.write(final)
            fm.write("\t")
        fm.close()
        count += 1
    
    def main(path, apkname):
      get_permissions(path, apkname)
      #get_apis(path, apkname)
      #get_providers(path, apkname)
      #get_package(path, apkname)
      #get_activities(path, apkname)
      #get_receivers(path, apkname)
      #get_services(path, apkname)
    
    if __name__ == '__main__':
        path = "D:/sample/Good"
        filename = "sampleInfo.txt"
        main(path, filename)
    
    
    • 上面代码中,witeToTex函数将调用API所得到的结果保存在txt文件中,以便查看和日后使用。get_XXXX函数就是获取apk文件中对应的信息,其中get_permissions获取apk中申请的权限,get_apis获取一些api调用信息,顾名思义,get_XXX就获取XXX。
    • 再看如何遍历,这里使用Python 的os.walk遍历目录:
      os.walk(top, topdown=True, onerror=None, followlinks=False) 可以得到一个三元tupple(dirpath, dirnames, filenames), 第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。dirpath代表目录的路径,dirnames包含了dirpath下所有子目录的名字。filenames 包含了非目录文件的名字。
    • 遍历存放众多APK的文件夹,对每个APK文件进行相应操作,代码如下:
    __author__ = 'Administrator'
    #-*- coding:GBK -*-
    import os
    import os.path
    import sys
    import subprocess
    import getFeatures
    
    rootdir = "D:/Sample/Good//"
    destdir = "D:/Sample/workSample/badDone//"
    command = "java -jar D://apktool.jar"
    class Packages:
        def __init__(self, srcdir, desdir):
            self.sdir = srcdir
            self.ddir = desdir
        def check(self):
            print("--------------------starting unpackage!---------------------")
            for dirpath, dirnames, filenames in os.walk(rootdir):
                for filename in filenames:
                    thefile = os.path.join(dirpath, filename)
                    apkfile = os.path.split(thefile)[1]
                    apkname = os.path.splitext(apkfile)[0]
                    print apkfile
                    try:
                        if os.path.splitext(thefile)[1] == ".apk":
                            # name = os.path.splitext(thefile)[0]
                            str1= '"'+thefile+'"'
                            str2= '"'+destdir + os.path.splitext(filename)[0]+'"'
                            # cmdExtract = r'%s d -f %s %s'% (command, str2, str1)
                            getFeatures.main(thefile, apkname)
                            print "******************well done******************"
                    except IOError, err:
                            print err
                            sys.exit()
    
    if __name__ == "__main__":
        dir=Packages(rootdir, 'e:/')
        dir.check()
    
    • 上面这个脚本引入文章中第一个脚本作为模块,共同实现批量拆包提取特征并输出到txt文件中的功能。这里用正则表达式对提取出的权限特征进行处理,去掉冗余部分,仅保留关键字段,并把每个apk文件对应的权限特征输出到各自的txt文本中。
    程序运行.png
    • 这里APK用以编号,以方便后面查找对比。输出的最终结果如下图:
    处理前.png 输出的txt.png
    • 将权限信息取冗余后,写入到txt文件中,以tab键进行分离,方便后面使用。
    txt中权限.png

    总结

    到此为止,我们就把安卓中的权限信息提取出来了。这为后面使用机器学习方式对安卓应用进行检测提供了基本的数据。在接下来的文章中将会进一步介绍如何使用Python实现机器学习的方式检测安卓恶意应用。

    相关文章

      网友评论

      • c39b937e32e7:求楼主 能不能公开所有源代码:pray: :pray: :pray:
      • Harlan1994:能不能把代码开源一下!谢谢:pray:
      • Harlan1994:新手没有看明白androguard环境的安装,博主说只要将相同文件夹合并一下就行,但是我下载的androguard和python目录下的没有一个相同的,我的python环境是Anancoda3,
        任柯榕:@Harlan1994 好的 谢谢了呢:kissing_closed_eyes:
        Harlan1994:@任柯榕 我现在搞定了,其实只需要 下载好androguard-master包,在当前解压缩后到setup.py那个文件夹下,python setup.py install命令就行了,至于作者说的这个方法我也不太明白!
        任柯榕:我也想问这个问题。你是把androguard这个文件直接放在python的根目录下呢?还是只复制了androguard下的文件呢?
      • 40761517a654:还有这两个里面的分别是什么?dir=Packages(rootdir, 'e:/')
      • 40761517a654:您好,您的Python之利用机器学习检测安卓恶意软件实现(一)中想问一下 path = "D:/sample/Good"和rootdir = "D:/Sample/Good//" destdir="D:/Sample/workSample/badDone//"这几个路径分别是什么啊

      本文标题:Python之利用机器学习检测安卓恶意软件实现(一)

      本文链接:https://www.haomeiwen.com/subject/aqjcyttx.html