In this section, we elaborate how to assemble code according to the constructed malicious behavior in BDL. The input of this step is a list of malicious behaviors, in the form of BDL. The output of this step is the assembled source code of the malware. There are two traverse iteration processes in this step. First, we traverses the existing flows in BDL, then traverses functions in each flow. As described in the previous section, one function consists of three elements, i.e., component, pointcut and operation. It checks whether the component exists or not. It would create a new component if not, and add this component into the app. The corresponding operation is instrumented into the specific pointcut (i.e., method), and then the pointcut is instrumented into the very component. Meanwhile, in this step, we also write scripts to automatically check constraints from feature dependencies and context, and generate the configuration files, such as AndroidManifest.xml.
Constraints in Assembly. To assure the soundness and validity of the assembled code, we have the following rules:
• Feature dependency constraint. Feature model has features dependencies inside, which are constraints to be satisfied in code assembly. For example, permission feature android.permission. READ_SMS is needed for the BDL example; the permission feature android.permission.READ_PHONE_STATE is needed for feature getDeviceId . When a component attempts to start an activity via ICC, in order to maintain the activity list in the history stack, it has to set the flag FLAG_ACTIVITY_NEW_TASK.
• Context constraint. BDL model embeds extra constraints to be verified in code assembly, specifically, some operations can only occur in a specific context. For example, the incoming SMS message is only accessed in the context of onReceive , and the receipt of ICC in a service is onStartCommand. All these constraints are not feature-relevant at requirement level, but specific to implementation. All these constraints should be satisfied to avoid runtime exception.