def makeFileAnalysis(self, file_path): logger.debug("Performing analysis of file [%s]..." % file_path) a = None d = None dx = None ret_type = androconf.is_android(file_path) if ret_type == "APK": a = apk.APK(file_path) d = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX": try: d = dvm.DalvikVMFormat(open(file_path, "rb").read()) except Exception as e: logger.error("[%s] is not valid dex file!" % file_path, e) return dx = analysis.VMAnalysis(d) invokeMethodPaths = analysis.seccon_get_invoke_method_paths(dx) newInstanceMethodPaths = analysis.seccon_get_newInstance_method_paths( dx) dynamicMethodPaths = analysis.seccon_get_dyncode_loading_paths(dx) if invokeMethodPaths: t = None for path in invokeMethodPaths: src = path.get_src(d.get_class_manager()) dst = path.get_dst(d.get_class_manager()) t = (src, dst) self._sources_invoke.append(t) self._uncovered_invoke.append(t) if newInstanceMethodPaths: t = None for path in newInstanceMethodPaths: src = path.get_src(d.get_class_manager()) dst = path.get_dst(d.get_class_manager()) t = (src, dst) self._sources_newInstance.append(t) self._uncovered_newInstance.append(t) if dynamicMethodPaths: t = None for path in dynamicMethodPaths: src = path.get_src(d.get_class_manager()) dst = path.get_dst(d.get_class_manager()) t = (src, dst) self._sources_dexload.append(t) self._uncovered_dexload.append(t) #building MFG for the file self._stadynaMcg.analyseFile(dx, a)
def makeFileAnalysis(self, file_path): logger.debug("Performing analysis of file [%s]..." % file_path) a = None d = None dx = None ret_type = androconf.is_android(file_path) if ret_type == "APK": a = apk.APK(file_path) d = dvm.DalvikVMFormat(a.get_dex()) elif ret_type == "DEX" : try : d = dvm.DalvikVMFormat(open(file_path, "rb").read()) except Exception as e : logger.error("[%s] is not valid dex file!" % file_path, e) return dx = analysis.VMAnalysis(d) invokeMethodPaths = analysis.seccon_get_invoke_method_paths(dx) newInstanceMethodPaths = analysis.seccon_get_newInstance_method_paths(dx) dynamicMethodPaths = analysis.seccon_get_dyncode_loading_paths(dx) if invokeMethodPaths: t = None for path in invokeMethodPaths: src = path.get_src(d.get_class_manager()) dst = path.get_dst(d.get_class_manager()) t = (src, dst) self._sources_invoke.append(t) self._uncovered_invoke.append(t) if newInstanceMethodPaths: t = None for path in newInstanceMethodPaths: src = path.get_src(d.get_class_manager()) dst = path.get_dst(d.get_class_manager()) t = (src, dst) self._sources_newInstance.append(t) self._uncovered_newInstance.append(t) if dynamicMethodPaths: t = None for path in dynamicMethodPaths: src = path.get_src(d.get_class_manager()) dst = path.get_dst(d.get_class_manager()) t = (src, dst) self._sources_dexload.append(t) self._uncovered_dexload.append(t) #building MFG for the file self._stadynaMcg.analyseFile(dx, a)
def analyseFile(self, vmx, apk): vm = vmx.get_vm() self.androGuardObjects.append((apk, vm, vmx)) # self.internal_methods.extend(vm.get_methods()) #creating real internal nodes internal_called_methods = vmx.get_tainted_packages().stadyna_get_internal_called_methods() for method in internal_called_methods: class_name, method_name, descriptor = method nodeType = None if method_name == "<clinit>": nodeType = NODE_STATIC_INIT elif method_name == "<init>": nodeType = NODE_CONSTRUCTOR else: nodeType = NODE_METHOD n = self._get_node(nodeType, (class_name, method_name, descriptor)) n.set_attribute(ATTR_CLASS_NAME, class_name) n.set_attribute(ATTR_METHOD_NAME, method_name) n.set_attribute(ATTR_DESCRIPTOR, descriptor) self.G.add_node(n.id) #creating real edges (nodes are already there) #currently we are working only with internal packages. for j in vmx.get_tainted_packages().get_internal_packages(): src_class_name, src_method_name, src_descriptor = j.get_src(vm.get_class_manager()) dst_class_name, dst_method_name, dst_descriptor = j.get_dst(vm.get_class_manager()) n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor)) # n1.set_attribute(ATTR_CLASS_NAME, src_class_name) # n1.set_attribute(ATTR_METHOD_NAME, src_method_name) # n1.set_attribute(ATTR_DESCRIPTOR, src_descriptor) n2 = self._get_existed_node((dst_class_name, dst_method_name, dst_descriptor)) # n2.set_attribute(ATTR_CLASS_NAME, dst_class_name) # n2.set_attribute(ATTR_METHOD_NAME, dst_method_name) # n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor) self.G.add_edge(n1.id, n2.id) #adding fake class nodes for method in internal_called_methods: src_class_name, src_method_name, src_descriptor = method if src_method_name == "<init>" or src_method_name == "<clinit>": n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor)) n2 = self._get_node(NODE_FAKE_CLASS, src_class_name, None, False) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) if src_method_name == "<clinit>": self.G.add_edge(n1.id, n2.id) elif src_method_name == "<init>": self.G.add_edge(n2.id, n1.id) #real (external) reflection invoke nodes reflection_invoke_paths = analysis.seccon_get_invoke_method_paths(vmx) for j in reflection_invoke_paths: src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() ) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() ) n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning("Cannot find the node [%s], where reflection invoke is called!" % (src_class_name, src_method_name, src_descriptor)) continue key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_REFL_INVOKE) n2 = self._get_node(NODE_REFL_INVOKE, key, LABEL_REFL_INVOKE, True) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) n2.set_attribute(ATTR_METHOD_NAME, src_method_name) n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor) self.G.add_edge( n1.id, n2.id ) #real (external) reflection new instance nodes reflection_newInstance_paths = analysis.seccon_get_newInstance_method_paths(vmx) for j in reflection_newInstance_paths: src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() ) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() ) n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning("Cannot find the node [%s], where reflection new instance is called!" % (src_class_name, src_method_name, src_descriptor)) continue key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_REFL_NEWINSTANCE) n2 = self._get_node(NODE_REFL_NEWINSTANCE, key, LABEL_REFL_NEWINSTANCE, True) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) n2.set_attribute(ATTR_METHOD_NAME, src_method_name) n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor) self.G.add_edge( n1.id, n2.id ) #adding fake entry points if apk != None: for i in apk.get_activities() : j = bytecode.FormatClassToJava(i) n1 = self._get_existed_node((j, "onCreate", "(Landroid/os/Bundle;)V")) if n1 != None: key = "%s %s %s %s" % (j, "onCreate", "(Landroid/os/Bundle;)V", POSTFIX_ACTIVITY) n2 = self._get_node(NODE_FAKE_ACTIVITY, key, LABEL_ACTIVITY, False) self.G.add_edge( n2.id, n1.id ) self.entry_nodes.append( n1.id ) for i in apk.get_services() : j = bytecode.FormatClassToJava(i) n1 = self._get_existed_node( (j, "onCreate", "()V") ) if n1 != None : key = "%s %s %s %s" % (j, "onCreate", "()V", POSTFIX_SERVICE) n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_SERVICE, False) self.G.add_edge( n2.id, n1.id ) self.entry_nodes.append( n1.id ) for i in apk.get_receivers() : j = bytecode.FormatClassToJava(i) n1 = self._get_existed_node( (j, "onReceive", "(Landroid/content/Context;Landroid/content/Intent;)V") ) if n1 != None : key = "%s %s %s %s" % (j, "onReceive", "(Landroid/content/Context;Landroid/content/Intent;)V", POSTFIX_RECEIVER) n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_RECEIVER, False) self.G.add_edge( n2.id, n1.id ) self.entry_nodes.append( n1.id ) #fake permissions list_permissions = vmx.stadyna_get_permissions([]) for x in list_permissions: for j in list_permissions[x]: if isinstance(j, PathVar): continue src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() ) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() ) n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning("Cannot find node [%s %s %s] for permission [%s]!" % (src_class_name, src_method_name, src_descriptor, x)) continue #SOURCE, DEST, POSTFIX, PERMISSION_NAME key = "%s %s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_PERM, x) n2 = self._get_node(NODE_FAKE_PERMISSION, key, x, False) n2.set_attribute(ATTR_CLASS_NAME, dst_class_name) n2.set_attribute(ATTR_METHOD_NAME, dst_method_name) n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor) n2.set_attribute(ATTR_PERM_NAME, x) n2.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[ x ][0]) self.G.add_edge(n1.id, n2.id) #fake DexClassLoader nodes dyn_code_loading = analysis.seccon_get_dyncode_loading_paths(vmx) for j in dyn_code_loading: src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager() ) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager() ) n1 = self._get_existed_node((src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning("Cannot find dexload node [%s]!" % (src_class_name, src_method_name, src_descriptor)) continue key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_DEXLOAD) n2 = self._get_node(NODE_FAKE_DEXLOAD, key, LABEL_DEXLOAD, False) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) n2.set_attribute(ATTR_METHOD_NAME, src_method_name) n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor) self.G.add_edge( n1.id, n2.id ) # Specific Java/Android library for c in vm.get_classes(): #if c.get_superclassname() == "Landroid/app/Service;" : # n1 = self._get_node( c.get_name(), "<init>", "()V" ) # n2 = self._get_node( c.get_name(), "onCreate", "()V" ) # self.G.add_edge( n1.id, n2.id ) if c.get_superclassname() == "Ljava/lang/Thread;" or c.get_superclassname() == "Ljava/util/TimerTask;" : for i in vm.get_method("run") : if i.get_class_name() == c.get_name() : n1 = self._get_node(NODE_METHOD, (i.get_class_name(), i.get_name(), i.get_descriptor())) n2 = self._get_node(NODE_METHOD, (i.get_class_name(), "start", i.get_descriptor())) # link from start to run self.G.add_edge( n2.id, n1.id ) #n2.add_edge( n1, {} ) # link from init to start for init in vm.get_method("<init>") : if init.get_class_name() == c.get_name(): #TODO: Leaving _get_existed_node to check if all the nodes are included #It is possible that internal_packages does not contain this node. Leaving _get_existed_node to check this n3 = self._get_node(NODE_CONSTRUCTOR, (init.get_class_name(), "<init>", init.get_descriptor())) self.G.add_edge( n3.id, n2.id )
def analyseFile(self, vmx, apk): vm = vmx.get_vm() self.androGuardObjects.append((apk, vm, vmx)) # self.internal_methods.extend(vm.get_methods()) #creating real internal nodes internal_called_methods = vmx.get_tainted_packages( ).stadyna_get_internal_called_methods() for method in internal_called_methods: class_name, method_name, descriptor = method nodeType = None if method_name == "<clinit>": nodeType = NODE_STATIC_INIT elif method_name == "<init>": nodeType = NODE_CONSTRUCTOR else: nodeType = NODE_METHOD n = self._get_node(nodeType, (class_name, method_name, descriptor)) n.set_attribute(ATTR_CLASS_NAME, class_name) n.set_attribute(ATTR_METHOD_NAME, method_name) n.set_attribute(ATTR_DESCRIPTOR, descriptor) self.G.add_node(n.id) #creating real edges (nodes are already there) #currently we are working only with internal packages. for j in vmx.get_tainted_packages().get_internal_packages(): src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager()) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager()) n1 = self._get_existed_node( (src_class_name, src_method_name, src_descriptor)) # n1.set_attribute(ATTR_CLASS_NAME, src_class_name) # n1.set_attribute(ATTR_METHOD_NAME, src_method_name) # n1.set_attribute(ATTR_DESCRIPTOR, src_descriptor) n2 = self._get_existed_node( (dst_class_name, dst_method_name, dst_descriptor)) # n2.set_attribute(ATTR_CLASS_NAME, dst_class_name) # n2.set_attribute(ATTR_METHOD_NAME, dst_method_name) # n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor) self.G.add_edge(n1.id, n2.id) #adding fake class nodes for method in internal_called_methods: src_class_name, src_method_name, src_descriptor = method if src_method_name == "<init>" or src_method_name == "<clinit>": n1 = self._get_existed_node( (src_class_name, src_method_name, src_descriptor)) n2 = self._get_node(NODE_FAKE_CLASS, src_class_name, None, False) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) if src_method_name == "<clinit>": self.G.add_edge(n1.id, n2.id) elif src_method_name == "<init>": self.G.add_edge(n2.id, n1.id) #real (external) reflection invoke nodes reflection_invoke_paths = analysis.seccon_get_invoke_method_paths(vmx) for j in reflection_invoke_paths: src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager()) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager()) n1 = self._get_existed_node( (src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning( "Cannot find the node [%s], where reflection invoke is called!" % (src_class_name, src_method_name, src_descriptor)) continue key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_REFL_INVOKE) n2 = self._get_node(NODE_REFL_INVOKE, key, LABEL_REFL_INVOKE, True) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) n2.set_attribute(ATTR_METHOD_NAME, src_method_name) n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor) self.G.add_edge(n1.id, n2.id) #real (external) reflection new instance nodes reflection_newInstance_paths = analysis.seccon_get_newInstance_method_paths( vmx) for j in reflection_newInstance_paths: src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager()) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager()) n1 = self._get_existed_node( (src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning( "Cannot find the node [%s], where reflection new instance is called!" % (src_class_name, src_method_name, src_descriptor)) continue key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_REFL_NEWINSTANCE) n2 = self._get_node(NODE_REFL_NEWINSTANCE, key, LABEL_REFL_NEWINSTANCE, True) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) n2.set_attribute(ATTR_METHOD_NAME, src_method_name) n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor) self.G.add_edge(n1.id, n2.id) #adding fake entry points if apk != None: for i in apk.get_activities(): j = bytecode.FormatClassToJava(i) n1 = self._get_existed_node( (j, "onCreate", "(Landroid/os/Bundle;)V")) if n1 != None: key = "%s %s %s %s" % (j, "onCreate", "(Landroid/os/Bundle;)V", POSTFIX_ACTIVITY) n2 = self._get_node(NODE_FAKE_ACTIVITY, key, LABEL_ACTIVITY, False) self.G.add_edge(n2.id, n1.id) self.entry_nodes.append(n1.id) for i in apk.get_services(): j = bytecode.FormatClassToJava(i) n1 = self._get_existed_node((j, "onCreate", "()V")) if n1 != None: key = "%s %s %s %s" % (j, "onCreate", "()V", POSTFIX_SERVICE) n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_SERVICE, False) self.G.add_edge(n2.id, n1.id) self.entry_nodes.append(n1.id) for i in apk.get_receivers(): j = bytecode.FormatClassToJava(i) n1 = self._get_existed_node( (j, "onReceive", "(Landroid/content/Context;Landroid/content/Intent;)V")) if n1 != None: key = "%s %s %s %s" % ( j, "onReceive", "(Landroid/content/Context;Landroid/content/Intent;)V", POSTFIX_RECEIVER) n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_RECEIVER, False) self.G.add_edge(n2.id, n1.id) self.entry_nodes.append(n1.id) #fake permissions list_permissions = vmx.stadyna_get_permissions([]) for x in list_permissions: for j in list_permissions[x]: if isinstance(j, PathVar): continue src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager()) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager()) n1 = self._get_existed_node( (src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning( "Cannot find node [%s %s %s] for permission [%s]!" % (src_class_name, src_method_name, src_descriptor, x)) continue #SOURCE, DEST, POSTFIX, PERMISSION_NAME key = "%s %s %s %s %s %s %s %s" % ( src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_PERM, x) n2 = self._get_node(NODE_FAKE_PERMISSION, key, x, False) n2.set_attribute(ATTR_CLASS_NAME, dst_class_name) n2.set_attribute(ATTR_METHOD_NAME, dst_method_name) n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor) n2.set_attribute(ATTR_PERM_NAME, x) n2.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[x][0]) self.G.add_edge(n1.id, n2.id) #fake DexClassLoader nodes dyn_code_loading = analysis.seccon_get_dyncode_loading_paths(vmx) for j in dyn_code_loading: src_class_name, src_method_name, src_descriptor = j.get_src( vm.get_class_manager()) dst_class_name, dst_method_name, dst_descriptor = j.get_dst( vm.get_class_manager()) n1 = self._get_existed_node( (src_class_name, src_method_name, src_descriptor)) if n1 == None: logger.warning( "Cannot find dexload node [%s]!" % (src_class_name, src_method_name, src_descriptor)) continue key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name, src_descriptor, dst_class_name, dst_method_name, dst_descriptor, POSTFIX_DEXLOAD) n2 = self._get_node(NODE_FAKE_DEXLOAD, key, LABEL_DEXLOAD, False) n2.set_attribute(ATTR_CLASS_NAME, src_class_name) n2.set_attribute(ATTR_METHOD_NAME, src_method_name) n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor) self.G.add_edge(n1.id, n2.id) # Specific Java/Android library for c in vm.get_classes(): #if c.get_superclassname() == "Landroid/app/Service;" : # n1 = self._get_node( c.get_name(), "<init>", "()V" ) # n2 = self._get_node( c.get_name(), "onCreate", "()V" ) # self.G.add_edge( n1.id, n2.id ) if c.get_superclassname( ) == "Ljava/lang/Thread;" or c.get_superclassname( ) == "Ljava/util/TimerTask;": for i in vm.get_method("run"): if i.get_class_name() == c.get_name(): n1 = self._get_node(NODE_METHOD, (i.get_class_name(), i.get_name(), i.get_descriptor())) n2 = self._get_node( NODE_METHOD, (i.get_class_name(), "start", i.get_descriptor())) # link from start to run self.G.add_edge(n2.id, n1.id) #n2.add_edge( n1, {} ) # link from init to start for init in vm.get_method("<init>"): if init.get_class_name() == c.get_name(): #TODO: Leaving _get_existed_node to check if all the nodes are included #It is possible that internal_packages does not contain this node. Leaving _get_existed_node to check this n3 = self._get_node( NODE_CONSTRUCTOR, (init.get_class_name(), "<init>", init.get_descriptor())) self.G.add_edge(n3.id, n2.id)