Aspect-Oriented Code Obfuscation Keshnee Padayachee University of South Africa Pretoria, South Africa padayk@unisa.ac.za Abstract— This paper reports on an exploratory study investigating the feasibility of using aspect-oriented constructs to instrument objects for the purposes of code obfuscation. With Java programs it is difficult to protect the intellectual property rights and secret information in untrusted environments. Consequently the utilization of software obfuscation techniques has become relevant. It has been found that Aspect-Oriented programming might be abused to overcome advanced code obfuscation used in Java Bytecode. In this paper possible intervention strategy to prevent these types of attacks using aspect-oriented programming language such as AspectJ is presented. Index Terms—aspect-oriented programming, code obfuscation I. INTRODUCTION The aspect-oriented paradigm has been recommended for several design issues, such as security [1, 2], persistence [3], exception handling [4] and program instrumentation [5, 6]. The principal argument supporting the utilization of aspect-oriented programming (AOP) to develop software is that some software requirements tend to crosscut objects, resulting in the code tangling phenomenon. Aspect-orientation has the potential to enhance the implementation of such crosscutting concerns in terms of reusability and extensibility, thereby improving the robustness and maintainability of a system. As the popularity of AOP matures [7], the issue surrounding exploiting aspectoriented programs for malicious purposes is of critical concern. It has been found that AOP may now be abused for sinister purposes such as, overcoming code obfuscation and thereby modifying software code to render security protection mechanisms ineffective. The aim of this paper is to investigate aspect-oriented tampering and propose a possible intervention to this problem. A code obfuscator is a tool which converts a program into an equivalent one that is more difficult to understand and reverse engineer [8]. There exist several obfuscation tools for preventing Java bytecode from being decompiled. Most of these tools simply scramble the names of the identifiers stored in a bytecode by substituting the identifiers with meaningless names [9]. It has been found that AOP may expose code obfuscators and render systems vulnerable to malicious purposes [10]. For instance, to extract propriety algorithms, or to subvert protection checks of commercial Java packages. Unfortunately encryption cannot resolve these type of problems since encrypted programs must be eventually decrypted in to executable programs and the adversaries can intercept them in hostile environments[11]. Chen and Chen [10] have shown that 978-1-4244-3519-7/09/$25.00 ©2009 IEEE is possible for the join point model and the code instrumentation mechanism of aspect-oriented programming to render code obfuscation ineffective for some intended protection. They highlighted the following concern: the 'binary weaving tools of AOP may become a new breed of productivity tools that facilitate the tampering of software integrity and malicious attacks'. The realization of software with tamper-resistance, which means the difficulty to read and modify the software in an unauthorized manner, becomes increasingly important. Software obfuscation transforms a program into a tamper resistant form [11]. This paper presents an exploratory study on aspect instrumentation for the purposes of obfuscation. Zhang and Wen [12] have also considered using AOP to protect Java source code, however they focus on enlarging the range of encryption to protect J2EE applications. It is important to note that although aspect-orientation is a form of instrumentation, it is not instrumentation in the typical sense as the code instrumented may be an essential requirement to the final application such as error handling or exception handling. This type of instrumentation is more formalized than typical instrumentation as it is language-based. It is much more precise and pervasive than traditional methods. This paper does not present any new techniques for code obfuscation nor is the technique presented evaluated with respect to their potency that is, to 'what degree is a human reader confused' [8]. Additionally the author does not negate the need for obfuscators in general. This paper addresses one particular type of attack when code obfuscation may not be adequate. That is specifically when 'malicious users with rudimentary knowledge of Java byte code and cryptography can exploit the join point model and code instrumentation of AspectJ to render code obfuscation and string encryption ineffective for some intended protection' [10]. The rest of the paper is structured as follows. Section 2, elaborates on aspectoriented programming in general. In Sections 3 and 4 explores how aspect-oriented programming may be exploited for malicious purposes and possible ways to avert to these types of attacks, respectively. Finally, Section 5 concludes, with possible future research opportunities. II. ASPECT-ORIENTED PROGRAMMING The object-oriented paradigm was found to be inadequate in terms of design and implementation of crosscutting concerns, as there is no elegant way of modularising these crosscutting concerns. AOP provides explicit language support for modularising design decisions that crosscut a functionally ICCSE 2009 decomposed program [13], allowing the developer to maintain the code (crosscutting functionality) in a modularised form. It is important to note that aspect-orientation maintains all the benefits of the object-oriented paradigm and should be viewed as an extension rather than a replacement of object-oriented technologies. An aspect-oriented system consists of two concepts: components and aspects. The components form the atomic and loosely coupled concerns of the system, and the aspects implement the additional crosscutting functionality of the system. According to Kiczales et al. [14], aspects consist of constructs named pointcuts and advices. A join point is a definable interception point in a system where the aspect could possibly take action. Specifically, join points refer to welldefined points in a program's execution such as when an object is instantiated, when a method is called, or when an exception is thrown, etc. The pointcuts are a set of join points described by a pointcut expression. An advice defines the functionality to be executed before (i.e. the before advice) or after (i.e. the after advice) a defined join point, or even possibly instead of the defined join point (i.e. the around advice). An aspect weaver is then used to merge components and aspects into a final program. Aspect-orientation has the potential to reduce the complexity of programs and to improve maintainability of software due the additional level of abstraction offered. However, despite the benefits offered by aspect-orientation, there are some drawbacks. Alexander and Bieman [15] maintain that as a result of the weaving process, the isolation of faults will be difficult, as faults may reside in the source code, the aspect, or the woven code. Another challenge, as noted by Chen [16], is that of understandability – a many-to-many relationship may exist between aspects and the primary abstractions they integrate with, thus potentially requiring understanding of many other aspects to understand only one. request to data checking, and a return forged success result. In view of the fact that encryption and decryption of string literals are not a standard service of Java Runtime, at some point the program under attack must decrypt the string literal by itself before they are displayed to the user. Control flow based tracing generates a method call log that will assist a malicious individual with identifying these methods, with the intent of subverting them. These types attack begins with bottom-up control flow tracing and data flow tracing. Both forms of tracing rely on using thisJoinPoint, or thisEnclosingJoinPointStaticPart variables that are available in AspectJ. These variables are visible in an advice and each is bound to an object that encapsulates some of the context of the advice's current or enclosing join point. (AspectJ has three such variables thisJoinPoint, thisJoinPointStaticPart, and thisEnclosingJoinPointStaticPart.) These variables exist because some pointcuts may pick out very large collections of join points [17] and these variables can be used to differentiate join points. For example, these variables can provide information regarding the methods called and arguments passed at a specific point in the program's execution. If this information trawling exercise were to be prevented in the first instance and obfuscated information returned then further attacks may become much more difficult to realize. The author recommends that every shipped system should have built in aspect that can not only thwart an attack from any malicious aspect but also return obfuscated information. This aspect which essentially prevents information flow and obfuscates information should not have any impact on the main program and only becomes active when another aspect is attempting to solicit information from the system. As demonstrated in figure 1, the Obfuscator Aspect sends back obfuscated information to the malicious user thus preventing any further attack. Typically when a programmer cannot decipher code, he/she will instrument such code to determine the context. There are several methods of program instrumentation such as binary code transformation, link time manipulation or source code transformation. Typically program analysis tools often rely on profiling information obtained from the programs they analyse. Obtaining such information can be a tedious task and the data achieved may be more abstract and non-specific [5, 6]. The more generic the instrumentation approach, the more abstract is the achievable data. Aspect-orientation resolves this problem, as the code introduced can extract data in more controlled way. However just as AOP may be used for useful purposes, it may be exploited for malicious purposes. III. USING ASPECT-ORIENTED PROGRAMMING FOR MALICIOUS PURPOSES Soliciting information about software for malicious purposes may be achieved with designing tracing aspects using the pointcut and advice mechanisms of AspectJ. Control flow tracing supplies the calling sequence of Java methods. While data flow based tracing employs field access join points to track where decoding and checking related strings are accessed. Once the exact code segment that reports the check result is located, then one may devise an aspect that will intercept a Figure 1. Showing how a Malicious Aspect can be thwarted with obfuscated information IV. PRACTICAL EXAMPLE OF ASPECT-ORIENTED OBSFUSCATION A simple program called SJEA which encrypts a file was downloaded from Google to demonstrate how encryption methods may be revealed with AOP. SJEA is a simple command-line binary encryption algorithm written in JAVA. As [10] has shown, aspect-orientation may utilized to expose and subvert encryption methods. It found that using an aspectoriented programming language such as AspectJ, one can easily determine the methods used for encryption. An aspect named Trace was use to trace through SJEA's execution history (Listing 1). It works by exploiting the thisJoinPointStaticPart variable, which provides reflective information about the current join point. The method getSignature() is used obtain information about this variable. The aspect-oriented paradigm allows a more generic implementation of the Trace aspect through the use of wildcards. Using wildcards eliminates the need for explicit naming [18]. Hence this pointcut will track any method executed in a program's history. Listing 2 shows how the following Aspect Trace exposes the methods for encryption in program SJEA. Listing 1: Aspect Trace public aspect Trace { before(): execution(* *.*(..)) { System.out.println(thisJoinPointStaticPart. getSignature()); } } Listing 2: Program SJEA advised by Aspect Trace void enc.main(String[]) SJEA 1.0 ENCRYPT Usage: java enc <input-file> <password> Input file size: 10 bytes > Encrypting... > Generating checksum...int enc.create(String) byte[] enc.createChecksum(String) . MD5: 5bdf74912a51c34815f11e9a3d20b609 DONE! Output file "c:\test\keshnee.txt.enc" created. File size: 15 Bytes Checksum file "c:\test\keshnee.txt.md5" created. Password length: 7 character(s) The solution to this problem was to define an aspect to obfuscate the method names so that is indecipherable to the attacker. Aspect XYZ was developed to counter this type of "attack". The pointcut risk1 picks out each join point where a getSignature() method is being called. As this is an indication that a joinpoint is being exposed. The keyword within() is used to define scope, in this case pointcut risk1 does not pick joinpoints within aspect XYZ. Once this joinpoint is identified then a method to obfuscate this joinpoint should be used. In order to improve the modularity of the aspect, a method obfuscate() was defined for this purpose. Unfortunately this presented a problem as aspect Trace's pointcut picks up obsfuscate() as a method to expose. This resulted in infinite recursive calls from Aspects XYZ and Trace. If no special precautions are taken, aspects which advise other aspects can easily and unintentionally advise each other recursively. The resolution to this problem was to create another pointcut preventcrosscut which essentially wrapped around the pointcut from Trace and prevented Trace from exposing this joinpoint as well. This pointcut then performed the obfuscation. Please note as the paper does not focus on obfuscation techniques, a rudimentary method was applied where the all method names were given aliases. For example method createCheckSum() was changed to "Rt m(Ar2 x)" which serves the purpose of obfuscation. Name obfuscation is the process of using meaningless or difficult to read string to replace the variable name [12]. However as code defined for obfuscation was separated - other more advanced and verifiable techniques may be substituted. It is plausible that preventcrosscut could be extended to avert all joinpoints picked by aspect Trace, however it could prevent other innocuous aspects that were in the original system from delivering a function that is essential to the system. The around advise for pointcut risk1, obfuscates the joinpoint that Trace was attempting to expose in system. As getSignature() returns a signature, the advice is forced to return the same type of object otherwise the system will throw an exception. The advice for risk1 returns the signature of the joinpoint in aspect Trace instead of the joinpoint in program SJEA. The output produced with both aspects Trace and XYZ advising program SJEA is shown in Listing 4. Listing 3: Aspect XYZ public aspect XYZ { pointcut risk1(Object js): !within(XYZ) target(js); Object around(Object js): risk1(js){ obsfuscation(js); return thisJoinPoint.getSignature(); } && call(* *.getSignature(..)) && void obsfuscation(Object obj){ //Do nothing as the Aspect Tracer will pick up this method to advise } pointcut preventcrosscut(Object obj): within(XYZ) && call( * *.obsfuscation(..)) && args(obj) ; void around(Object obj):preventcrosscut(obj){ String s = obj.toString(); if (s.contains("create")) { s = "Rt m(Arg1 x)"; } if (s.contains("createChecksum")){ s = "Rt m(Ar2 x)"; } if (s.contains( "main")){ s = "Rt. m(Arg3 x)"; } System.out.println(s); } } Listing 4: Program SJEA advised by both Aspect Trace and Aspect XYZ Rt. m(Arg3 x) Signature org.aspectj.lang.JoinPoint.StaticPart.getSignature() SJEA 1.0 ENCRYPT Usage: java enc <input-file> <password> Input file size: 10 bytes > Encrypting... > Generating checksum...Rt m(Arg1 x) Signature org.aspectj.lang.JoinPoint.StaticPart.getSignature() Rt m(Arg1 x) Signature org.aspectj.lang.JoinPoint.StaticPart.getSignature() . MD5: 5bdf74912a51c34815f11e9a3d20b609 DONE! Output file "c:\test\keshnee.txt.enc" created. File size: 15 Bytes Checksum file "c:\test\keshnee.txt.md5" created. Password length: 7 character(s) The solution presented is simplistic however, attackers can easily rewrite this Trace aspect in other ways to illicit the same information and foil Aspect XYZ in more innocuous ways. For instance with Java, println statements could be used to expose a joinpoint. There four possible ways of rewriting the same code to gather similar information. We now explore four such cases. We termed these risks, The first risk, is namely using method calls on the thisJoinPoint, thisJoinStaticPart or thisEnclosingJoinPointStaticPart such as getSignature(). Aspect XYZ can easily obfuscate these calls. If method call is made to some other member function such as getSourceLocation(), getArgs() or getKind() then Aspect XYZ would not be able to handle these. However pointcut risk1 (Listing 5) could be expanded to handle all of these cases. Of course the return type will be have adapted accordingly otherwise the system will throw an exception. The next risk, is when reflective information can be concatenated with string. Currently Aspect XYZ cannot identify this type of attack. For instance, the following statement will be overlooked by Aspect XYZ:System.out.println("thisJoinPoint" +thisJoinPoint) In this case, incorporating pointcut risk2 to Aspect XYZ (see Listing 2) will be one way of subverting this type of statement. Pointcut risk2, essentially checks every string that is passed to a function, which then obfuscates it if is revealing any critical information. This pointcut could also be useful in preventing illegal flows. Information is exchanged among by messages in object-oriented systems. An illegal flow arises when information is transmitted from one object to another object in violation of the information flow security policy [19] . The next two risks are similar but require two different pointcuts to subvert them. These risks, involve merely passing either thisJoinPoint, thisJoinStaticPart or thisEnclosingJoinPointStaticPart variable to a function which may then expose it. For example:"System.out.println(thisJoinPoint);". Here two poincuts risk3 and risk4 were developed which essentially tracks down any join point where thisJoinPoint was being passed to any method. Whereas risk4 tracks down any join point where thisJoinPointStaticPart or thisEnclosingJoinPointStaticPart is being passed as an argument. Listing 5: Pointcuts to be integrated into Aspect XYZ pointcut risk1(Object js): !within(XYZ) && (call(* *.getSignature(..)) || call(* *.getArgs(..) ) || call * *.getKind (..) ) etc..) () && target(js); pointcut risk2(String s): !within(XYZ) && call(void *.*(..)) && args(..,s) ; void around(String s): risk2(s){ obsfuscation(s); } pointcut risk3(JoinPoint jp): !within(XYZ) && call(void *.*(..)) && args(jp,..); void around(JoinPoint jp): risk3(jp){ System.out.println("risk 3 - output only joinpoint" +jp); obsfuscation(jp); } pointcut risk4(JoinPoint.StaticPart jp): !within(XYZ) && call(void *.*(..)) && args(jp,..); void around(JoinPoint.StaticPart jp): risk4(jp){ System.out.println("risk4 - outupt only staticpart" +jp); obsfuscation(jp); } V. CONCLUSION Obfuscators are a necessary requirement however as shown by Chen and Chen [10], attackers with a rudimentary knowledge of Java byte code and cryptography can exploit the join point model and code instrumentation of AspectJ to render code obfuscation, string encryption and other security mechanisms ineffective for some intended protection. In the worked example, it was demonstrated how a program may be abused. The author then presented an approach to thwart this type of attacks using aspect-oriented programming and obfuscation to prevent reverse-engineering. Chen and Chen [10] suggests that AspectJ should provide a mechanism to "hide" or encapsulate critical join points in a program. However this is subject to whether a programmer deems a point in a program's execution as critical or in fact bears in mind to do so. Unfortunately, incorporating security into software development takes time and developers tend to focus more on the features of the software application. The author does not proclaim this solution could prevent all possible attacks however it is step forward towards trying to prevent this type of attacks. This is analogous to anti-viruses, the attackers will always figure out other ways of defeating anti-virus packages. However this does not negate the need for this type of software. Future research would involve in determining the performance issues relating to aspect-oriented obfuscation. REFERENCES De Win, B., W. Joosen, and F. Piessens, Developing Secure Applications through Aspect-Oriented Programming, in Aspect-Oriented Software Development, M. Aksit, et al., Editors. 2002, Addison-Wesley: Boston. p. 633–650. [2] Vanhaute, B. and B. De Win, AOP, Security and Genericity, in 1st Belgian AOSD Workshop. 2001: Vrije Universiteit Brussel, Brussels, Belgium. p. 1-2. [3] Rashid, A. and R. Chitchyan. Persistence as an aspect. in Proceedings of the 2nd International Conference on Aspect-Oriented Software Development. 2003. Enschede, The Netherlands. [4] Lippert, M. and C.V. Lopes. A study on exception detection and handling using aspect-oriented programming. in Proceedings of the 22nd International Conference on Software Engineering. 2000. Limerick, Ireland. [5] Deters, M. and R.K. Cytron, Introduction of Program Instrumentation using aspects, in Proceedings of the OOPSLA 2001 (Workshop on Advanced Separation of Concerns). 2001: Tampa Bay, Florida. [6] Debusmann, M. and K. Geihs. Efficient and Transparent Instrumentation of Application Components Using an Aspect-Oriented Approach. in 14th IFIP/IEEE Workshop on Distributed Systems: Operations and Management (DSOM 2003). 2003. [7] Padayachee, K. and J.H.P. Eloff. The Next Challenge: Aspect-Oriented Programming. in Proceedings of the Sixth IASTED International Conference on Modelling, Simulation and Optimization. 2006. Gaborone, Botswana: ACTA Press. [8] Collberg, C., C. Thomborson, and D. Low, A Taxonomy of Obfuscating Transformations. 1998. [9] Chan, J. and W. Yang, Advanced obfuscation techniques for java bytecode. Journal of Systems and Software, 2004. 71(1-2): p. 1-10. [1] Chen, K. and J. Chen. On Instrumenting Obfuscated Java Bytecode with Aspects. in SESSO6. 2006. Shanghai, China. [11] Sakabe, Y., M. Soshi, and A. Miyaji, Java Obfuscation Approaches to Construct Tamper-Resistant Object-Oriented Programs. Information and Media Technologies, 2006. 1(1): p. 134-146. [12] Zhang, X. and Q. Wen. AOP-Based J2EE Source Code Protection. in Computational Intelligence and Security Workshops, 2007. CISW 2007. 2007. [13] Walker, R.J., E.L.A. Baniassad, and G.C. Murphy. An initial assessment of aspect-oriented programming. in Proceedings of the 21st international conference on Software engineering. 1999. Los Angeles, California. [14] Kiczales, G., et al., Getting Started with AspectJ. Communications of the ACM, 2001. 44(10): p. 59-65. [15] Alexander, R.T. and J.M. Bieman, Challenges with Aspect-oriented Technology, in ICSE Workshop on Software Quality. 2002: Orlando, Flordia. [16] Chen, L., Aspect-Oriented Programming in Software Engineering. 2004, Wake Forest University, Department of Computer Science. [17] Development Aspects. 2009 [cited; Available from: http://www.eclipse.org/aspectj/doc/released/progguide/exam ples-development.html (Last access 1/02/2009). [18] Kiczales, G., et al. Semantics-Based Crosscutting in AspectJ. in Workshop on Multi-Dimensional Separation of Concerns inSoftware Engineering (ICSE 2000). 2000. [19] Samarati, P., et al., Information Flow Control in ObjectOriented Systems. IEEE Transactions on Knowledge and Data Engineering, 1997. 9(4): p. 624-538. [10]