<commit_before># This file is part of Androguard.
#
# Copyright (C) 2012, <NAME> <desnos at t0t0.fr>
# All rights reserved.
#
# Androguard is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Androguard is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of  
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Androguard.  If not, see <http://www.gnu.org/licenses/>.

from networkx import DiGraph
import os
from xml.sax.saxutils import escape


from androguard.core.analysis import analysis

try :
    from androguard.core.analysis.libsign.libsign import entropy
except ImportError :
    import math
    def entropy(data):
        entropy = 0

        if len(data) == 0 :
            return entropy

        for x in range(256):
            p_x = float(data.count(chr(x)))/len(data)
            if p_x > 0:
                entropy += - p_x*math.log(p_x, 2)
        return entropy

DEFAULT_SIGNATURE = analysis.SIGNATURE_L0_4
def create_entropies(vmx, m) :
    try : 
        default_signature = vmx.get_method_signature(m, predef_sign = DEFAULT_SIGNATURE).get_string()
        l = [ default_signature,
              entropy( vmx.get_method_signature(m, "L4", { "L4" : { "arguments" : ["Landroid"] } } ).get_string() ),
              entropy( vmx.get_method_signature(m, "L4", { "L4" : { "arguments" : ["Ljava"] } } ).get_string() ),
              entropy( vmx.get_method_signature(m, "hex" ).get_string() ),
              entropy( vmx.get_method_signature(m, "L2" ).get_string() ),
            ]
        return l
    except KeyError :
        return [ "", 0.0, 0.0, 0.0, 0.0 ]

def create_info(vmx, m) :
    E = create_entropies(vmx, m)

    H = {}
    H["signature"] = E[0]
    H["signature_entropy"] = entropy( E[0] )
    H["android_api_entropy"] = E[1]
    H["java_api_entropy"] = E[2]
    H["hex_entropy"] = E[3]
    H["exceptions_entropy"] = E[4]

    return H

class Data :
    def __init__(self, vm, vmx, gvmx, a=None) :
        self.vm = vm
        self.vmx = vmx
        self.gvmx = gvmx
        self.a = a

        self.apk_data = None
        self.dex_data = None

        if self.a != None :
            self.apk_data = ApkViewer( self.a )

        self.dex_data = DexViewer( vm, vmx, gvmx )

        self.gvmx.set_new_attributes( create_info )
        self.export_methods_to_gml()

    def export_methodcalls_to_gml(self) :
        return self.gvmx.export_to_gml()

    def export_methods_to_gml(self) :
        print self.gvmx.G
       
        for node in self.gvmx.G.nodes() :
            print self.gvmx.nodes_id[ node ].method_name, self.gvmx.nodes_id[ node ].get_attributes()

    def export_apk_to_gml(self) :
        if self.apk_data != None :
            return self.apk_data.export_to_gml()
    
    def export_dex_to_gml(self) :
        if self.dex_data != None :
            return self.dex_data.export_to_gml()

class DexViewer :
    def __init__(self, vm, vmx, gvmx) :
        self.vm = vm
        self.vmx = vmx
        self.gvmx = gvmx
    

    def _create_node(self, id, height, width, color, label) :
        buff = "<node id=\"%d\">\n" % id
        buff += "<data key=\"d6\">\n"
        buff += "<y:ShapeNode>\n"

        buff += "<y:Geometry height=\"%f\" width=\"%f\"/>\n" % (16 * height, 7.5 * width)
        buff += "<y:Fill color=\"#%s\" transparent=\"false\"/>\n" % color

        buff += "<y:NodeLabel alignment=\"left\" autoSizePolicy=\"content\" fontFamily=\"Dialog\" fontSize=\"13\" fontStyle=\"plain\" hasBackgroundColor=\"false\" hasLineColor=\"false\" modelName=\"internal\" modelPosition=\"c\" textColor=\"#000000\" visible=\"true\">\n"

        buff += escape(label)

        buff += "</y:NodeLabel>\n"
        buff += "</y:ShapeNode>\n"
        buff += "</data>\n"

        buff += "</node>\n"

        return buff
        
    def add_exception_node(self, exception, id_i) :
        buff = ""
       # 9933FF 
        height = 2 
        width = 0
        label = ""
        
        label += "%x:%x\n" % (exception.start, exception.end)
        for i in exception.exceptions :
            c_label = "\t(%s -> %x %s)\n" % (i[0], i[1], i[2].get_name())
            label += c_label

            width = max(len(c_label), width)
            height += 1

        return self._create_node( id_i, height, width, "9333FF", label )

    def add_method_node(self, i, id_i) :
        height = 0 
        width = 0
        label = ""
        
        label += i.get_name() + "\n"
        label += i.get_descriptor()
        
        height = 3 
        width = len(label)

        return self._create_node( id_i, height, width, "FF0000", label )

    def add_node(self, i, id_i) :
        height = 0
        width = 0
        idx = i.start
        label = ""
        for ins in i.ins :
            c_label = "%x %s\n" % (idx, self.vm.dotbuff(ins, idx))<commit_msg>fix bug<commit_after># This file is part of Androguard.
#
# Copyright (C) 2012, <NAME> <desnos at t0t0.fr>
# All rights reserved.
#
# Androguard is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Androguard is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of  
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Androguard.  If not, see <http://www.gnu.org/licenses/>.

from networkx import DiGraph
import os
from xml.sax.saxutils import escape


from androguard.core.analysis import analysis

try :
    from androguard.core.analysis.libsign.libsign import entropy
except ImportError :
    import math
    def entropy(data):
        entropy = 0

        if len(data) == 0 :
            return entropy

        for x in range(256):
            p_x = float(data.count(chr(x)))/len(data)
            if p_x > 0:
                entropy += - p_x*math.log(p_x, 2)
        return entropy

DEFAULT_SIGNATURE = analysis.SIGNATURE_L0_4
def create_entropies(vmx, m) :
    try : 
        default_signature = vmx.get_method_signature(m, predef_sign = DEFAULT_SIGNATURE).get_string()
        l = [ default_signature,
              entropy( vmx.get_method_signature(m, "L4", { "L4" : { "arguments" : ["Landroid"] } } ).get_string() ),
              entropy( vmx.get_method_signature(m, "L4", { "L4" : { "arguments" : ["Ljava"] } } ).get_string() ),
              entropy( vmx.get_method_signature(m, "hex" ).get_string() ),
              entropy( vmx.get_method_signature(m, "L2" ).get_string() ),
            ]
        return l
    except KeyError :
        return [ "", 0.0, 0.0, 0.0, 0.0 ]

def create_info(vmx, m) :
    E = create_entropies(vmx, m)

    H = {}
    H["signature"] = E[0]
    H["signature_entropy"] = entropy( E[0] )
    H["android_api_entropy"] = E[1]
    H["java_api_entropy"] = E[2]
    H["hex_entropy"] = E[3]
    H["exceptions_entropy"] = E[4]

    return H

class Data :
    def __init__(self, vm, vmx, gvmx, a=None) :
        self.vm = vm
        self.vmx = vmx
        self.gvmx = gvmx
        self.a = a

        self.apk_data = None
        self.dex_data = None

        if self.a != None :
            self.apk_data = ApkViewer( self.a )

        self.dex_data = DexViewer( vm, vmx, gvmx )

        self.gvmx.set_new_attributes( create_info )
        self.export_methods_to_gml()

    def export_methodcalls_to_gml(self) :
        return self.gvmx.export_to_gml()

    def export_methods_to_gml(self) :
        print self.gvmx.G
       
        for node in self.gvmx.G.nodes() :
            print self.gvmx.nodes_id[ node ].method_name, self.gvmx.nodes_id[ node ].get_attributes()

    def export_apk_to_gml(self) :
        if self.apk_data != None :
            return self.apk_data.export_to_gml()
    
    def export_dex_to_gml(self) :
        if self.dex_data != None :
            return self.dex_data.export_to_gml()

class DexViewer :
    def __init__(self, vm, vmx, gvmx) :
        self.vm = vm
        self.vmx = vmx
        self.gvmx = gvmx
    

    def _create_node(self, id, height, width, color, label) :
        buff = "<node id=\"%d\">\n" % id
        buff += "<data key=\"d6\">\n"
        buff += "<y:ShapeNode>\n"

        buff += "<y:Geometry height=\"%f\" width=\"%f\"/>\n" % (16 * height, 7.5 * width)
        buff += "<y:Fill color=\"#%s\" transparent=\"false\"/>\n" % color

        buff += "<y:NodeLabel alignment=\"left\" autoSizePolicy=\"content\" fontFamily=\"Dialog\" fontSize=\"13\" fontStyle=\"plain\" hasBackgroundColor=\"false\" hasLineColor=\"false\" modelName=\"internal\" modelPosition=\"c\" textColor=\"#000000\" visible=\"true\">\n"

        buff += escape(label)

        buff += "</y:NodeLabel>\n"
        buff += "</y:ShapeNode>\n"
        buff += "</data>\n"

        buff += "</node>\n"

        return buff
        
    def add_exception_node(self, exception, id_i) :
        buff = ""
       # 9933FF 
        height = 2 
        width = 0
        label = ""
        
        label += "%x:%x\n" % (exception.start, exception.end)
        for i in exception.exceptions :
            c_label = "\t(%s -> %x %s)\n" % (i[0], i[1], i[2].get_name())
            label += c_label

            width = max(len(c_label), width)
            height += 1

        return self._create_node( id_i, height, width, "9333FF", label )

    def add_method_node(self, i, id_i) :
        height = 0 
        width = 0
        label = ""
        
        label += i.get_name() + "\n"
        label += i.get_descriptor()
        
        height = 3 
        width = len(label)

        return self._create_node( id_i, height, width, "FF0000", label )

    def add_node(self, i, id_i) :
        height = 0
        width = 0
        idx = i.start
        label = ""
        for ins in i.get_instructions() :
            c_label = "%x %s\n" % (idx, self.vm.dotbuff(ins, idx))
{'fraction_non_alphanumeric': 0.13528791798409504, 'fraction_numerical': 0.013605442176870748, 'mean_word_length': 2.201840490797546, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3368328', 'n_tokens_mistral': 3594, 'n_tokens_neox': 3465, 'n_words': 894}