-- @path ICC=/DetectionAndroidMalwareByICC/metamodels/ICC.ecore
-- @path FeatureModel=/DetectionAndroidMalwareByICC/metamodels/FeatureModel.ecore
-- @path ASEC=/DetectionAndroidMalwareByICC/metamodels/ASEC.ecore

module ICCPatternDetection;
create OUT : ICC from IN : ASEC, IN1 : FeatureModel;


--Check list for Malicious Actions:
helper def:all_actions_of_malicious_intentfilter:Sequence(OclAny)=
	Sequence{'android.intent.action.BOOT_COMPLETED',
	'android.intent.action.PACKAGE_ADDED',
	'android.intent.action.POWER_CONNECTED',
	'android.intent.action.SMS_RECEIVED',
	'android.intent.action.PHONE_STATE',
	'android.intent.action.SIG_STR'
	         };
	         
	         helper context ASEC!Action def:isMalicious: Boolean=
		if thisModule.all_actions_of_malicious_intentfilter.includes(self.name)  then
			true
		   else
		  false
	   endif;


--check number of component:
helper context OclAny def:isMoreRec:Boolean=
	if (ASEC!BroadcastReceiver.allInstances().size()> ASEC!Activity.allInstances().size() and ASEC!BroadcastReceiver.allInstances().size()> ASEC!Service.allInstances().size()) then
	true
	 else
	false
	endif;

--check number of component:
helper context OclAny def:isMoreForRECIVER:Boolean=
	if (FeatureModel!IntentFilterForActivityService.allInstances()->select(c | c.TypeOwnedComp=#Receiver).size()> FeatureModel!IntentFilterForActivityService.allInstances()->select(c | c.TypeOwnedComp=#Activity).size() and FeatureModel!IntentFilterForActivityService.allInstances()->select(c | c.TypeOwnedComp=#Receiver).size()> FeatureModel!IntentFilterForActivityService.allInstances()->select(c | c.TypeOwnedComp=#Service).size()) then
	true
	else
	false
endif;

helper context ASEC!ApplicationPolicyFile def : haveSufficientReceivers:Boolean=
	if thisModule.isMoreRec then
	  true
	    
	  else
	  	false
		endif;

helper context FeatureModel!IntentFilterForActivityService def : haveSufficientIntentFilterReceivers:Boolean=
	if thisModule.isMoreForRECIVER then
	  true
	    
	  else
	  	false
		endif;


--check pattern of component:
helper context ASEC!ApplicationPolicyFile def: determine_have_Pattern_of_Component:String=
	if self.haveSufficientReceivers then
	     'This App has few Activities, Services, Providers, and sufficient Receivers'
    else
	    
    	OclUndefined
	endif;

--check pattern of IntentFilter:
helper context OclAny def: determine_have_Pattern_of_IntentFilter:String=
	if FeatureModel!IntentFilterForActivityService.isMoreForRECIVER then
	     'This App Receive various system-wide broadcasts and external Implicit Intents'
    else
	    
    	OclUndefined
	endif;

helper context OclAny def:get_all_asction_of_intentfilter:Sequence(ASEC!Action)=
	ASEC!intentFilter.allInstances()->select(c | c.actions);

--check pattern of explicit intent:
helper context ASEC!ApplicationPolicyFile def:determine_have_Pattern_of_ExplicitIntent :String=
	if self.Intents->select(c | c.IntentKind = #explicit).notEmpty() then
	    if self.Intents->select(c | c.IntentKind = #explicit)->flatten()->select(c | not c.SendToInternalComp).notEmpty() then
		 if self.Intents->select(c | c.IntentKind = #explicit)->flatten()->select(c | not c.TargetComponentName.oclIsUndefined()).notEmpty() then
		   -- if self.Intents->select(c | c.IntentKind = #explicit)->flatten()->select(c | not c.TargetComponentName.startsWith('com.')).notEmpty() then
		     'This App generates Explicit Intents, sends these to internal components and external components'
	         --else
		   --  OclUndefined
	        -- endif
		  else
		 OclUndefined
		  endif
		 else
		 	OclUndefined
	     endif
		 else
		 	OclUndefined
			endif;

--check of user defiened action:
helper context ASEC!Intent def:has_user_defined_action:Boolean=
if  not self.Action.oclIsUndefined() then
	if self.Action.startsWith('"package_name.') then
	true
	else
	false
	endif
  else
  	false
	endif;

--check pattern of implicit intent:
helper context ASEC!ApplicationPolicyFile def: determine_have_Pattern_of_Implicit_Intent:String=
	if self.Intents->select(c | c.IntentKind = #implicit)->flatten()->select(c | not c.Action.oclIsUndefined())->flatten().notEmpty() then
	    if self.Intents->select(c | c.IntentKind = #implicit)->flatten()->select(c | c.has_user_defined_action).notEmpty() then
		    'This App sends intent to internal components, external components with system action and user defined action'
		else 
			OclUndefined
		endif
	 else
	 	OclUndefined
		endif;



rule APP2ICCDetection
{
	from
	    s:ASEC!ApplicationPolicyFile
	to 
	    t:ICC!ICCDetect(
	    	
	  --  DescriptionofComponent  <- s.determine_have_Patten_of_Component,
	 -- Description <- s.determine_have_Pattern_of_Component
	 DescriptionofComponent <- s.determine_have_Pattern_of_Component,
	 DescriptionOfIntentFilter <- s.determine_have_Pattern_of_IntentFilter,
	 DescriptionOfExplicitIntent <- s.determine_have_Pattern_of_ExplicitIntent,
	-- DescriptionOfImplicitIntent <- s.determine_have_Pattern_of_Implicit_Intent
	DescriptionOfImplicitIntent <- s.determine_have_Pattern_of_Implicit_Intent
	 
	-- SensitiveIntentFilter <- thisModule.get_all_asction_of_intentfilter->collect(c | thisModule.CreateSensitive(c))
	 
		
	    )
	}
 rule CreateSensitive
{
	from
	s:ASEC!Action (s.isMalicious)
	to
	t:ICC!IntentFilterSensitive
	(
	Description <- if thisModule.all_actions_of_malicious_intentfilter.includes(s.name)	 then
	': The Application is Malicous because exist a IntentFilter with Malicous Action : ' + s.name
	else
		OclUndefined
		endif
	)
	
}

