Example #1
0
def test(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    for k in d.get_classes():
        print(dp.get_source_class(k))
def Get_APK_Words(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    class_code_dic, is_amd_class_code_dic = Build_APK_Corpus(apkfile)
    for k in d.get_classes():  # 用于遍历每一个class
        all_orig_methods = []  # 用于统计一个class里面的所有的method
        # print(type(k))
        print('class_name+super_name::' + k.get_name() + ':' +
              k.get_superclassname())
        for m in dx.find_methods(
                classname=k.get_name()):  # 用于将一个class里面所有的原始方法提取到
            orig_method = m.get_method()
            if isinstance(orig_method, ExternalMethod):
                is_this_external = True
            else:
                is_this_external = False
            CFG.add_node(orig_method, external=is_this_external)
            if not isinstance(orig_method, ExternalMethod):
                all_orig_methods.append(orig_method)  # 用于得到所有的原始方法
        for m in dx.find_methods(
                classname=k.get_name()):  # 用于遍历一个class里面的所有的方法
            orig_method = m.get_method()
            if not isinstance(orig_method, ExternalMethod):
                if (orig_method.get_name() in all_callback) or (
                        orig_method.get_name()
                        in APK_Method_Key_Words.key_registers):
                    print('method_name+method_descriptor::' +
                          orig_method.get_name() +
                          orig_method.get_descriptor())
                    print(class_code_dic[k.get_name()][
                        orig_method.get_name() + orig_method.get_descriptor()])
Example #3
0
def Deal_one_apk_new(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    apk_word = []
    for k in d.get_classes():
        print('class_name:' + k.get_name())
        # print(dp.get_source_class(k))
        for m in dx.find_methods(classname=k.get_name()):
            orig_method = m.get_method()
            # print(type(orig_method))
            if isinstance(orig_method, ExternalMethod):
                is_this_external = True
            else:
                is_this_external = False
            CFG.add_node(orig_method, external=is_this_external)
            if is_this_external == False:  # 用于获取一个class里面的所有方法
                print('orig::' + orig_method.get_name())
            else:
                print('orig+externalmethod::' + orig_method.get_name())
            for other_class, callee, offset in m.get_xref_to():
                if isinstance(callee, ExternalMethod):
                    is_external = True
                else:
                    is_external = False
                if callee not in CFG.node:
                    CFG.add_node(callee, external=is_external)
                    if is_external == False:
                        print('external+callee::' + callee.get_name())
                    else:
                        print('callee:' + callee.get_name())
Example #4
0
def write_one_apk_source(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    with open(
            'F:\\2018年第一学年科研\\APK科研\\数据集\\Word2vec_ao_yuliaoku\\test\\successed_1.txt',
            'w') as txtData:
        for k in d.get_classes():
            print('class_name:' + k.get_name())
            txtData.writelines(dp.get_source_class(k))
            for m in dx.find_methods(classname=k.get_name()):
                orig_method = m.get_method()
                if isinstance(orig_method, ExternalMethod):
                    is_this_external = True
                else:
                    is_this_external = False
                CFG.add_node(orig_method, external=is_this_external)
                if is_this_external == False:  # 用于获取一个class里面的所有方法
                    print('orig::' + orig_method.get_name())
                else:
                    print('orig+external::' + orig_method.get_name())
                for other_class, callee, offset in m.get_xref_to():
                    if isinstance(callee, ExternalMethod):
                        is_external = True
                    else:
                        is_external = False
                    if callee not in CFG.node:
                        CFG.add_node(callee, external=is_external)
                        if is_external == False:
                            print('external+callee::' + callee.get_name())
                        else:
                            print('callee:' + callee.get_name())
Example #5
0
def Deal_one_apk(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    apk_word = []
    class_code_dic, is_amd_class_code_dic = Update_one_apk_dictory(apkfile)
    for k in d.get_classes():
        amd_p1 = 'Lmy/app/client/Client;'
        if k.get_name() == amd_p1:
            # print(dp.get_source_class(k))
            all_orig_methods = []
            for m in dx.find_methods(
                    classname=amd_p1):  #用于将一个class里面所有的原始方法提取到
                orig_method = m.get_method()
                if isinstance(orig_method, ExternalMethod):
                    is_this_external = True
                else:
                    is_this_external = False
                CFG.add_node(orig_method, external=is_this_external)
                if not isinstance(orig_method, ExternalMethod):
                    all_orig_methods.append(orig_method)
            for m in dx.find_methods(classname=amd_p1):  #用于遍历一个class里面的所有的方法
                orig_method = m.get_method()
                if not isinstance(orig_method, ExternalMethod):
                    if (orig_method.get_name() in all_callback) or (
                            orig_method.get_name()
                            in APK_Method_Key_Words.key_registers):
                        callees = []  # 用于将所有的不在这个class里面的函数保存下来
                        for other_class, callee, offset in m.get_xref_to():
                            if isinstance(callee, ExternalMethod):
                                is_external = True
                            else:
                                is_external = False
                            if callee not in CFG.node:
                                CFG.add_node(callee, external=is_external)
                                callees.append(callee)
                        for callee in callees:
                            if callee in all_orig_methods:
                                class_code_dic[k.get_name()][
                                    orig_method.get_name() + orig_method.
                                    get_descriptor()] += class_code_dic[
                                        k.get_name()][callee.get_name() +
                                                      callee.get_descriptor()]
                        print(class_code_dic[k.get_name()]
                              [orig_method.get_name() +
                               orig_method.get_descriptor()])
                        print(is_amd_class_code_dic[k.get_name()]
                              [orig_method.get_name() +
                               orig_method.get_descriptor()])

    return apk_word
def Get_Apk_Source_Code(apkfile):

    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    #用于获取源码
    with open('F:\\2018年第一学年科研\\APK科研\\数据集\\Word2vec_ao_yuliaoku\\source.txt',
              'w') as txtfile:
        for k in d.get_classes():  # 对于每一个class
            # print(dp.get_source_class(k))
            txtfile.writelines(dp.get_source_class(k))
Example #7
0
def decompileMethod(className, methodName, sess):
    print("Decompiling whole method...")
    className = className.replace("_", "/")
    dalv = next(sess.get_objects_dex())[1]
    dx = next(sess.get_objects_dex())[2]
    dad = decompiler.DecompilerDAD(dalv, dx)

    classes = dalv.get_classes_names()
    for c in classes:
        if className in c:
            for m in dalv.get_methods_class(c):
                if methodName in str(m):
                    dad.display_source(m)
Example #8
0
def decompileClass(className, sess):
    print("Class name is: " + className)
    print("Decompiling whole class...")

    className = className.replace("_", "/")
    dalv = next(sess.get_objects_dex())[1]
    dx = next(sess.get_objects_dex())[2]
    dad = decompiler.DecompilerDAD(dalv, dx)


    classes = dalv.get_classes()
    for c in classes:
        if className in str(c):
            dad.display_all(c)
Example #9
0
def AnalyzeAPK(_file, session=None, raw=False):
    """
    Analyze an android application and setup all stuff for a more quickly
    analysis!
    If session is None, no session is used at all. This is the default
    behaviour.
    If you like to continue your work later, it might be a good idea to use a
    session.
    A default session can be created by using :meth:`~get_default_session`.

    :param _file: the filename of the android application or a buffer which represents the application
    :type _file: string (for filename) or bytes (for raw)
    :param session: A session (default: None)
    :param raw: boolean if raw bytes are supplied instead of a filename
    :rtype: return the :class:`~androguard.core.bytecodes.apk.APK`, list of :class:`~androguard.core.bytecodes.dvm.DalvikVMFormat`, and :class:`~androguard.core.analysis.analysis.Analysis` objects
    """
    log.debug("AnalyzeAPK")

    if session:
        log.debug("Using existing session {}".format(session))
        if raw:
            data = _file
            filename = hashlib.md5(_file).hexdigest()
        else:
            with open(_file, "rb") as fd:
                data = fd.read()
                filename = _file

        digest = session.add(filename, data)
        return session.get_objects_apk(filename, digest)
    else:
        log.debug("Analysing without session")
        a = APK(_file, raw=raw)
        # FIXME: probably it is not necessary to keep all DalvikVMFormats, as
        # they are already part of Analysis. But when using sessions, it works
        # this way...
        d = []
        dx = Analysis()
        for dex in a.get_all_dex():
            df = DalvikVMFormat(dex, using_api=a.get_target_sdk_version())
            dx.add(df)
            d.append(df)
            df.set_decompiler(decompiler.DecompilerDAD(d, dx))

        dx.create_xref()

        return a, d, dx
Example #10
0
def RunDecompiler(d, dx, decompiler_name):
    """
    Run the decompiler on a specific analysis

    :param d: the DalvikVMFormat object
    :type d: :class:`DalvikVMFormat` object
    :param dx: the analysis of the format
    :type dx: :class:`VMAnalysis` object
    :param decompiler: the type of decompiler to use ("dad", "dex2jad", "ded")
    :type decompiler: string
    """
    if decompiler_name is not None:
        log.debug("Decompiler ...")
        decompiler_name = decompiler_name.lower()
        # TODO put this into the configuration object and make it more dynamic
        # e.g. detect new decompilers and so on...
        if decompiler_name == "dex2jad":
            d.set_decompiler(
                decompiler.DecompilerDex2Jad(d, androconf.CONF["BIN_DEX2JAR"],
                                             androconf.CONF["BIN_JAD"],
                                             androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_name == "dex2fernflower":
            d.set_decompiler(
                decompiler.DecompilerDex2Fernflower(
                    d, androconf.CONF["BIN_DEX2JAR"],
                    androconf.CONF["BIN_FERNFLOWER"],
                    androconf.CONF["OPTIONS_FERNFLOWER"],
                    androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_name == "ded":
            d.set_decompiler(
                decompiler.DecompilerDed(d, androconf.CONF["BIN_DED"],
                                         androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_name == "jadx":
            d.set_decompiler(
                decompiler.DecompilerJADX(d,
                                          dx,
                                          jadx=androconf.CONF["BIN_JADX"]))
        else:
            d.set_decompiler(decompiler.DecompilerDAD(d, dx))
Example #11
0
def Deal_one_apk(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    apk_word = []
    for k in d.get_classes():
        # print('class_name:'+k.get_name())
        amd_p1 = 'Lcom/mix_four/dd/LockReceiver;'
        amd_p2 = 'Lcom/mix_four/dd/CoreService$MyOrderRunnable;'
        amd_p3 = 'Landroid/support/v4/content/IntentCompat$IntentCompatImplBase;'
        amd_p4 = 'Lcom/mix_four/dd/CoreService$MyOrderRunnable;'
        if k.get_name() == amd_p1:
            print('class_name:' + k.get_name())
            print(dp.get_source_class(k))
            for m in dx.find_methods(classname=amd_p1):
                orig_method = m.get_method()
                if isinstance(orig_method, ExternalMethod):
                    is_this_external = True
                else:
                    is_this_external = False
                CFG.add_node(orig_method, external=is_this_external)
                if is_this_external == False:  # 用于获取一个class里面的所有方法
                    print('orig::' + orig_method.get_name())
                for other_class, callee, offset in m.get_xref_to():
                    if isinstance(callee, ExternalMethod):
                        is_external = True
                    else:
                        is_external = False
                    if callee not in CFG.node:
                        CFG.add_node(callee, external=is_external)
                        if is_external == False:
                            print('external+callee::' + callee.get_name())
                        else:
                            print('callee:' + callee.get_name())
    return apk_word
Example #12
0
def Update_one_apk_dictory(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    class_code_dic, is_amd_class_code_dic = Get_one_apk_dictory(apkfile)
    for k in d.get_classes():
        if k.get_name() == k.get_name():
            for m in dx.find_methods(
                    classname=k.get_name()):  # 用于遍历一个class里面的所有的方法
                orig_method = m.get_method()
                if isinstance(orig_method, ExternalMethod):
                    is_this_external = True
                else:
                    is_this_external = False
                CFG.add_node(orig_method,
                             external=is_this_external)  #将原始结点保存在CFG中
                callees = []  # 用于将所有的不在这个class里面的函数保存下来
                for other_class, callee, offset in m.get_xref_to():
                    if isinstance(callee, ExternalMethod):
                        is_external = True
                    else:
                        is_external = False
                    if callee not in CFG.node:
                        CFG.add_node(
                            callee,
                            external=is_external)  #将不在此method的所有的函数保存在CFG中
                        callees.append(callee)
                '----------提出一个问题-----对于一个class里面的函数调用另外一个class里面的函数'
                orig_method_key_words = []
                if not isinstance(orig_method,
                                  ExternalMethod):  # 用于将属于这个class的所有method提取出来
                    b = 'false'
                    orig_method_key_words += (class_code_dic[k.get_name()][
                        orig_method.get_name() + orig_method.get_descriptor()])
                    for callee in callees:  # 用于统计非该class里面的函数,并且更新origin函数的所有关键字
                        if callee.get_class_name() in class_code_dic.keys():
                            # 如果函数在字典里面,则将其关键字提取出来
                            if (callee.get_name() +
                                    callee.get_descriptor()) in class_code_dic[
                                        callee.get_class_name()].keys():

                                orig_method_key_words += class_code_dic[
                                    callee.get_class_name()][
                                        callee.get_name() +
                                        callee.get_descriptor()]

                                if is_amd_class_code_dic[callee.get_class_name(
                                )][callee.get_name() +
                                   callee.get_descriptor()] == 'true':
                                    b = 'true'
                                else:
                                    pass
                            else:
                                orig_method_key_words += (
                                    Get_Word(callee.get_name() +
                                             callee.get_descriptor()))

                    # -------用于更新一下原始函数的key值
                    class_code_dic[k.get_name()][
                        orig_method.get_name() +
                        orig_method.get_descriptor()] = orig_method_key_words
                    if b == 'true':
                        is_amd_class_code_dic[k.get_name()][
                            orig_method.get_name() +
                            orig_method.get_descriptor()] = 'true'

    return class_code_dic, is_amd_class_code_dic
Example #13
0
def Get_one_apk_dictory(apkfile):
    a = apk.APK(apkfile, False, 'r', None, 2)
    d = dvm.DalvikVMFormat(a.get_dex())
    vmx = analysis.Analysis(d)
    dp = decompiler.DecompilerDAD(d, vmx)  # DAD是androguard内部的decompiler
    a1, d1, dx = AnalyzeAPK(apkfile)
    CFG = nx.DiGraph()
    class_code_dic = {}  # 用于将class里面的所有关键的代码保存下来
    # 其格式为 class_code_dic={'class1':'key_class1','class2':'key_class2'}
    is_amd_class_code_dic = {}  #用于将class里面的所有method里面是否含有amd数据保存下来
    for k in d.get_classes():
        method_dic = {
        }  # 用于将一个方法里面的所有关键代码保存下来,其形式是method_dic={'method1':'key_word1','method2':'....}
        is_amd_method_dic = {}
        # print('class_name:' + k.get_name())
        # print(dp.get_source_class(k))
        for m in dx.find_methods(classname=k.get_name()):
            orig_method = m.get_method()
            if isinstance(orig_method, ExternalMethod):  #将原始结点保存在CFG中
                is_this_external = True
            else:
                is_this_external = False
            CFG.add_node(orig_method, external=is_this_external)
            callees = []  # 用于将所有的不在这个class里面的函数保存下来
            for other_class, callee, offset in m.get_xref_to():
                if isinstance(callee, ExternalMethod):
                    is_external = True
                else:
                    is_external = False
                if callee not in CFG.node:  #将非原始结点,即外部的结点保存在CFG中
                    CFG.add_node(callee, external=is_external)
                    callees.append(callee)
            orig_method_code = []
            orig_method_key_words = []
            if not isinstance(orig_method,
                              ExternalMethod):  # 用于将这个class创建的所有函数获取到
                orig_method_code = orig_method.get_source().split('\n')
                orig_method_code = [i.strip() for i in orig_method_code]
                orig_method_key_words += Get_Word(orig_method.get_name() +
                                                  '==' +
                                                  orig_method.get_descriptor())
                for callee in callees:
                    if not isinstance(callee, ExternalMethod):
                        if callee.get_name() != orig_method.get_name():
                            callee_code = callee.get_source().split('\n')
                            callee_code = [i.strip() for i in callee_code]
                            orig_method_code += callee_code  # 得到一个method的内部的所有的源代码
                            orig_method_key_words += Get_Word(
                                callee.get_name() + '==' +
                                callee.get_descriptor())
            if not isinstance(
                    orig_method,
                    ExternalMethod):  # 如果在一个class里面的method是非外部方法,则提取其内部代码
                amd_num = 0  # 用于统计这个method是否是包含amd的method
                # --------------用于判断amd数据---------------
                for key in APK_Method_Key_Words.amd_key_words:
                    for code in orig_method_code:  # 得到一个method内部的所有的源码
                        if key in code:
                            amd_num += 1
                            orig_method_key_words += Get_Word(key)
                #  ----------用于判断intent代理机制-------------
                for key in APK_Method_Key_Words.key_Intent:
                    for code in orig_method_code:  # 得到一个method内部的所有的源码
                        if key in code:
                            key_word = Get_Word(key)
                            key_word.append('Rbracket')
                            orig_method_key_words += key_word
                if amd_num > 0:
                    #  用于判断此函数里面是否含有恶意代码
                    is_amd_method_dic[orig_method.get_name() +
                                      orig_method.get_descriptor()] = 'true'
                else:
                    is_amd_method_dic[orig_method.get_name() +
                                      orig_method.get_descriptor()] = 'false'
                method_dic[
                    orig_method.get_name() +
                    orig_method.get_descriptor()] = orig_method_key_words
        class_code_dic[k.get_name()] = method_dic  # 用于将一个class里面的所有关键代码保存下来
        is_amd_class_code_dic[k.get_name()] = is_amd_method_dic
    # print(is_amd_class_code_dic)
    # print(class_code_dic)
    #用于将俩个字典返回,目的是为了进行后面的工作
    return class_code_dic, is_amd_class_code_dic
Example #14
0
def main(projectName, className, methodName):

    if methodName and (not className):
        print('Must provide class name "-c" in order to decompile specific method "-m"')
        exit()

    #Increase recursion limit to save session file
    sys.setrecursionlimit(100000)
    r2 = r2pipe.open()

    fileName = r2.cmd("i~file[1]")
    fileName = fileName.split("/")[2]
    if fileName.split("."):
        sessionName = fileName.split(".")[0]
        sessionName = sessionName+".session"
        sessionFile = Path(sessionName)

    currentClassMethod = r2.cmd("afi.")

    if "_" in currentClassMethod:
        currentClassMethod = str(currentClassMethod).replace("_", "/")

    currentClass = str(currentClassMethod).split(".")[1]
    print("Current class: " + currentClass)

    currentMethod = str(currentClassMethod).split(".")[3]

    apkMethod = currentMethod.split("/")[0]

    if apkMethod == "method":

        currentMethod = str(currentClassMethod).split(".")[4]
        apkMethod = currentMethod.split("(")[0]

    print("    Current Method: " +  apkMethod + "\n")

    sess = misc.get_default_session()

    #Check if project name is passed
    if projectName != None:
        projectSession = r2ProjectName(projectName, sessionName, fileName, sess)

        if className and methodName:
            decompileMethod(className, methodName, projectSession)
            exit()
        if className:
            decompileClass(className, projectSession)
            exit() 

        dalv = next(projectSession.get_objects_dex())[1]
        dx = next(projectSession.get_objects_dex())[2]
        print("Decompiling method " + apkMethod + " in the class" + currentClass)

        dad = decompiler.DecompilerDAD(dalv, dx)

        classNames = dalv.get_classes_names()
        autoDecompile(dalv, dx, dad, classNames, currentClass, apkMethod)
        exit()

    # Check if session file exists    
    if sessionFile.is_file(): 
            
        print("Loading session file, please wait... \n")
        sess = session.Load(sessionName)

        if className and methodName:
            decompileMethod(className, methodName, sess)
            exit()
        if className:
            decompileClass(className, sess)
            exit() 
        

        dalv = next(sess.get_objects_dex())[1]
        dx = next(sess.get_objects_dex())[2]
        dad = decompiler.DecompilerDAD(dalv, dx)

        classNames = dalv.get_classes_names()
        autoDecompile(dalv,dx,dad,classNames, currentClass, apkMethod)

    # Create sesssion file
    else:
        print("No session file found, creating one! Please wait...")
        fileName = fileName.replace("\\n\\x00","")
        fileName = fileName.split("\'")[0]
        apk, d, dx = misc.AnalyzeAPK(fileName, session=sess)
        session.Save(sess, sessionName)

        print("Session file created: " + sessionName)
        print("    Will load session file for future calls... \n")

        if className and methodName:
            decompileMethod(className, methodName, sess)
            exit()

        if className:
            decompileClass(className, sess)
            exit() 

        dalv = next(sess.get_objects_dex())[1]
        dx = next(sess.get_objects_dex())[2]
        dad = decompiler.DecompilerDAD(dalv, dx)

        classNames = dalv.get_classes_names()
        autoDecompile(dalv,dx,dad,classNames,currentClass, apkMethod)
Example #15
0
#!/usr/bin/env python

import sys

PATH_INSTALL = "./"
sys.path.append(PATH_INSTALL)

from androguard.core.bytecodes import dvm
from androguard.core.analysis import analysis
from androguard.decompiler import decompiler

TEST = "examples/android/TestsAndroguard/bin/classes.dex"

j = dvm.DalvikVMFormat(open(TEST).read())
jx = analysis.VMAnalysis(j)

#d = decompiler.DecompilerDex2Jad( j )
#d = decompiler.DecompilerDed( j )
d = decompiler.DecompilerDAD(j, jx)

j.set_decompiler(d)

# SHOW METHODS
for i in j.get_methods():
    if i.get_name() == "onCreate":
        print i.get_class_name(), i.get_name()
        i.source()

#    if i.get_name() == "testWhileTrue" :
#        i.source()
Example #16
0
    def run(self):
        if androconf.is_android_raw(self.raw) == "DEY":
            dex_object = dvm.DalvikOdexVMFormat(self.raw)
        else:
            dex_object = dvm.DalvikVMFormat(self.raw)

        ana_object = analysis.uVMAnalysis(dex_object)
        gvm_object = ganalysis.GVMAnalysis(ana_object, None)

        dex_object.set_vmanalysis(ana_object)
        dex_object.set_gvmanalysis(gvm_object)

        for i in androconf.CONF:
            if is_setting(i):
                androconf.CONF[i] = get_setting(i)

        decompiler_option = get_setting("DEFAULT_DECOMPILER", "dad")

        if decompiler_option == "dex2jad":
            dex_object.set_decompiler(
                decompiler.DecompilerDex2Jad(dex_object,
                                             androconf.CONF["PATH_DEX2JAR"],
                                             androconf.CONF["BIN_DEX2JAR"],
                                             androconf.CONF["PATH_JAD"],
                                             androconf.CONF["BIN_JAD"],
                                             androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_option == "ded":
            dex_object.set_decompiler(
                decompiler.DecompilerDed(dex_object,
                                         androconf.CONF["PATH_DED"],
                                         androconf.CONF["BIN_DED"],
                                         androconf.CONF["TMP_DIRECTORY"]))
        else:
            dex_object.set_decompiler(
                decompiler.DecompilerDAD(dex_object, ana_object))

        dex_object.create_xref()
        dex_object.create_dref()

        self.view.set_name("%s.ag" % (self.filename))

        self.view.set_scratch(True)
        edit = self.view.begin_edit()
        self.view.sel().clear()
        self.view.set_syntax_file("Packages/ag-st/ag.tmLanguage")

        by_package = {}
        for current_class in dex_object.get_classes():
            name = current_class.get_name()

            try:
                by_package[os.path.dirname(name)].append(current_class)
            except KeyError:
                by_package[os.path.dirname(name)] = []
                by_package[os.path.dirname(name)].append(current_class)

        b_buffer = ""
        line = 0

        AG_METHODS_LINE[self.view.id()] = {}
        AG_CLASSES_LINE[self.view.id()] = {}
        AG_FIELDS_LINE[self.view.id()] = {}
        for key in sorted(by_package.iterkeys()):
            b_buffer += "%s\n" % key
            line += 1

            for c_class in sorted(by_package[key], key=lambda k: k.get_name()):
                b_buffer += "\t%s extends %s\n" % (c_class.get_name(
                )[1:-1], c_class.get_superclassname()[1:-1])
                AG_CLASSES_LINE[self.view.id()][line] = c_class
                line += 1

                for j in c_class.get_methods():
                    b_buffer += "\t\tmethod: %s %s [%s] size:%d\n" % (
                        j.get_name(), j.get_descriptor(),
                        j.get_access_flags_string(), j.get_length())
                    AG_METHODS_LINE[self.view.id()][line] = j
                    line += 1

                b_buffer += "\n"
                line += 1

                for j in c_class.get_fields():
                    b_buffer += "\t\tfield: %s %s [%s %s]" % (
                        j.get_name(), j.get_descriptor(),
                        j.get_access_flags_string(),
                        dvm.get_type(j.get_descriptor()))

                    init_value = j.get_init_value()
                    if init_value != None:
                        b_buffer += " (%s)" % repr(str(init_value.get_value()))
                    b_buffer += "\n"

                    AG_FIELDS_LINE[self.view.id()][line] = j
                    line += 1

                b_buffer += "\n"
                line += 1

        l = dex_object.get_classes_hierarchy()
        h_buffer = ""
        for i in l:
            h_buffer += i + "\n"

        b_buffer += h_buffer

        self.view.replace(edit, sublime.Region(0, self.view.size()), b_buffer)
        self.view.end_edit(edit)
        self.view.set_read_only(True)
        AG_DEX_VIEW[self.view.id()] = (dex_object, ana_object)
        FILENAMES[self.view.id()] = hashlib.sha1(
            dex_object.get_buff()).hexdigest()
Example #17
0
    apk_path = "./app-debug.apk"

print("[*] Begin")

a = apk.APK(apk_path)
f_path = apk_path+"-JavascriptInterface"+".java"
f2_path = apk_path+"-JavascriptInterface-list"+".txt"
f3_path = apk_path+"-method-list"+".txt"

dvm = DalvikVMFormat(a.get_dex())

print("[*] DalvikVMFormat Finish!")

dx = Analysis()
dx.add(dvm)
dvm.set_decompiler(decompiler.DecompilerDAD(dvm, dx))

print("[*] Analysis Finish!")

savedStdout = sys.stdout
with open(f_path, 'w+') as file:
    sys.stdout = file

    f2 = open(f2_path, 'w+')
    f3 = open(f3_path, 'w+')

    for adi in dvm.map_list.get_item_type("TYPE_ANNOTATIONS_DIRECTORY_ITEM"):
        if adi.get_method_annotations() == []:
            continue

        # Each annotations_directory_item contains many method_annotation
Example #18
0
def export_apps_to_format(filename,
                          a,
                          output,
                          methods_filter=None,
                          jar=None,
                          decompiler_type=None,
                          format=None):
    print "Dump information %s in %s" % (filename, output)

    if not os.path.exists(output):
        print "Create directory %s" % output
        os.makedirs(output)
    else:
        print "Clean directory %s" % output
        androconf.rrmdir(output)
        os.makedirs(output)

    methods_filter_expr = None
    if methods_filter:
        methods_filter_expr = re.compile(methods_filter)

    output_name = output
    if output_name[-1] != "/":
        output_name = output_name + "/"

    dump_classes = []
    for vm in a.get_vms():
        print "Analysis ...",
        sys.stdout.flush()
        vmx = analysis.VMAnalysis(vm)
        print "End"

        print "Decompilation ...",
        sys.stdout.flush()

        if not decompiler_type:
            vm.set_decompiler(decompiler.DecompilerDAD(vm, vmx))
        elif decompiler_type == "dex2jad":
            vm.set_decompiler(
                decompiler.DecompilerDex2Jad(vm,
                                             androconf.CONF["PATH_DEX2JAR"],
                                             androconf.CONF["BIN_DEX2JAR"],
                                             androconf.CONF["PATH_JAD"],
                                             androconf.CONF["BIN_JAD"],
                                             androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_type == "dex2winejad":
            vm.set_decompiler(
                decompiler.DecompilerDex2WineJad(
                    vm, androconf.CONF["PATH_DEX2JAR"],
                    androconf.CONF["BIN_DEX2JAR"], androconf.CONF["PATH_JAD"],
                    androconf.CONF["BIN_WINEJAD"],
                    androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_type == "ded":
            vm.set_decompiler(
                decompiler.DecompilerDed(vm, androconf.CONF["PATH_DED"],
                                         androconf.CONF["BIN_DED"],
                                         androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_type == "dex2fernflower":
            vm.set_decompiler(
                decompiler.DecompilerDex2Fernflower(
                    vm, androconf.CONF["PATH_DEX2JAR"],
                    androconf.CONF["BIN_DEX2JAR"],
                    androconf.CONF["PATH_FERNFLOWER"],
                    androconf.CONF["BIN_FERNFLOWER"],
                    androconf.CONF["OPTIONS_FERNFLOWER"],
                    androconf.CONF["TMP_DIRECTORY"]))
        else:
            raise ("invalid decompiler !")
        print "End"

        if options.jar:
            print "jar ...",
            filenamejar = decompiler.Dex2Jar(
                vm, androconf.CONF["PATH_DEX2JAR"],
                androconf.CONF["BIN_DEX2JAR"],
                androconf.CONF["TMP_DIRECTORY"]).get_jar()
            shutil.move(filenamejar, output + "classes.jar")
            print "End"

        for method in vm.get_methods():
            if methods_filter_expr:
                msig = "%s%s%s" % (method.get_class_name(), method.get_name(),
                                   method.get_descriptor())
                if not methods_filter_expr.search(msig):
                    continue

            filename_class = valid_class_name(method.get_class_name())
            create_directory(filename_class, output)

            print "Dump %s %s %s ..." % (method.get_class_name(),
                                         method.get_name(),
                                         method.get_descriptor()),

            filename_class = output_name + filename_class
            if filename_class[-1] != "/":
                filename_class = filename_class + "/"

            descriptor = method.get_descriptor()
            descriptor = descriptor.replace(";", "")
            descriptor = descriptor.replace(" ", "")
            descriptor = descriptor.replace("(", "-")
            descriptor = descriptor.replace(")", "-")
            descriptor = descriptor.replace("/", "_")

            filename = filename_class + method.get_name() + descriptor
            if len(method.get_name() + descriptor) > 250:
                all_identical_name_methods = vm.get_methods_descriptor(
                    method.get_class_name(), method.get_name())
                pos = 0
                for i in all_identical_name_methods:
                    if i.get_descriptor() == method.get_descriptor():
                        break
                    pos += 1

                filename = filename_class + method.get_name() + "_%d" % pos

            buff = method2dot(vmx.get_method(method))

            if format:
                print "%s ..." % format,
                method2format(filename + "." + format, format, None, buff)

            if method.get_class_name() not in dump_classes:
                print "source codes ...",
                current_class = vm.get_class(method.get_class_name())
                current_filename_class = valid_class_name(
                    current_class.get_name())
                create_directory(filename_class, output)

                current_filename_class = output_name + current_filename_class + ".java"
                fd = open(current_filename_class, "w")
                fd.write(current_class.get_source())
                fd.close()

                dump_classes.append(method.get_class_name())

            print "bytecodes ...",
            bytecode_buff = dvm.get_bytecodes_method(vm, vmx, method)
            fd = open(filename + ".ag", "w")
            fd.write(bytecode_buff)
            fd.close()

            print
Example #19
0
def decompile(apkname, output):
    print "Dump information %s in %s" % (apkname, output)
    apk_vm_serial = []
    a = Androguard([apkname])
    decompiler_type = None

    if not os.path.exists(output):
        print "Create directory %s" % output
        os.makedirs(output)
    else:
        print "Clean directory %s" % output
        androconf.rrmdir(output)
        os.makedirs(output)

    output_dir = output
    if output_dir[-1] != "/":
        output_name = output_dir + "/"
    print "Output dir: %s" % output_dir

    for vm in a.get_vms():
        vm_list = []  #vm_list = [vm, vmx]
        print "Analysis ...",
        sys.stdout.flush()
        vmx = analysis.VMAnalysis(vm)
        vm_list.append(vm)
        vm_list.append(vmx)
        print "End"

        print "Decompilation ...",
        sys.stdout.flush()

        if not decompiler_type:
            vm.set_decompiler(decompiler.DecompilerDAD(vm, vmx))
        elif decompiler_type == "dex2jad":
            vm.set_decompiler(
                decompiler.DecompilerDex2Jad(vm,
                                             androconf.CONF["PATH_DEX2JAR"],
                                             androconf.CONF["BIN_DEX2JAR"],
                                             androconf.CONF["PATH_JAD"],
                                             androconf.CONF["BIN_JAD"],
                                             androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_type == "dex2winejad":
            vm.set_decompiler(
                decompiler.DecompilerDex2WineJad(
                    vm, androconf.CONF["PATH_DEX2JAR"],
                    androconf.CONF["BIN_DEX2JAR"], androconf.CONF["PATH_JAD"],
                    androconf.CONF["BIN_WINEJAD"],
                    androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_type == "ded":
            vm.set_decompiler(
                decompiler.DecompilerDed(vm, androconf.CONF["PATH_DED"],
                                         androconf.CONF["BIN_DED"],
                                         androconf.CONF["TMP_DIRECTORY"]))
        elif decompiler_type == "dex2fernflower":
            vm.set_decompiler(
                decompiler.DecompilerDex2Fernflower(
                    vm, androconf.CONF["PATH_DEX2JAR"],
                    androconf.CONF["BIN_DEX2JAR"],
                    androconf.CONF["PATH_FERNFLOWER"],
                    androconf.CONF["BIN_FERNFLOWER"],
                    androconf.CONF["OPTIONS_FERNFLOWER"],
                    androconf.CONF["TMP_DIRECTORY"]))
        else:
            raise ("invalid decompiler !")
        apk_vm_serial.append(vm_list)
        print "End"
    return apk_vm_serial