U.S. Pat. No. 12,050,668

METHOD AND SYSTEM FOR OBFUSCATING AND PROTECTING GAME LOGIC AND VARIABLES DURING VIDEO GAME COMPILATION

AssigneeTAKE-TWO INTERACTIVE SOFTWARE, INC.

Issue DateJanuary 7, 2022

Illustrative Figure

Abstract

A system and method for producing video games in order to prevent cheating in a video game environment by obfuscating game logic and variables during compilation.

Description

DETAILED DESCRIPTION OF PREFERRED EMBODIMENTS As previously discussed, currently-available security systems are deficient because they only operate on compiled executables on a single machine. The number and type of protection transformations are thereby limited and any attempt for security is easily identifiable to the naked eye. Accordingly, a security-based compilation system that implements security measures during development and applies them during the compilation process can prove desirable and provide a basis for a wide range of software applications. This result can be achieved, according to one embodiment disclosed herein, by an exemplary compilation process1000as illustrated inFIG.2. Turning toFIG.2, the compilation process1000begins by transforming the source code10into a target executable1008. The source code10can be written in a high-level programming language that is easier for humans to write and understand. For example, software engineers can choose from several popular languages like C, C++, Java, Python, C#, Rust, or myriad others depending on their goals and needs. Once software engineers have completed development, the source code10is transformed through several processes. The compilation process1000can generally be split into three stages: a front end, a middle end, and a back end of a compiler toolchain. The front end of the compiler toolchain takes in source code10written in a high-level programming language. The front end is also responsible for producing an intermediate representation (IR)1004that contains the substance of the source code10but in a different form that is amenable to optimization. The front end of the compiler toolchain is generally designed for a specific programming language or family of programming languages but can produce a modular and independent IR1004. The middle end of the compiler toolchain takes in the IR1004as input and performs a series of optimizations on the IR1004. As the IR1004is no longer tied to any specific programming language in the source code10, the middle ...

DETAILED DESCRIPTION OF PREFERRED EMBODIMENTS

As previously discussed, currently-available security systems are deficient because they only operate on compiled executables on a single machine. The number and type of protection transformations are thereby limited and any attempt for security is easily identifiable to the naked eye. Accordingly, a security-based compilation system that implements security measures during development and applies them during the compilation process can prove desirable and provide a basis for a wide range of software applications. This result can be achieved, according to one embodiment disclosed herein, by an exemplary compilation process1000as illustrated inFIG.2. Turning toFIG.2, the compilation process1000begins by transforming the source code10into a target executable1008. The source code10can be written in a high-level programming language that is easier for humans to write and understand. For example, software engineers can choose from several popular languages like C, C++, Java, Python, C#, Rust, or myriad others depending on their goals and needs. Once software engineers have completed development, the source code10is transformed through several processes.

The compilation process1000can generally be split into three stages: a front end, a middle end, and a back end of a compiler toolchain. The front end of the compiler toolchain takes in source code10written in a high-level programming language. The front end is also responsible for producing an intermediate representation (IR)1004that contains the substance of the source code10but in a different form that is amenable to optimization. The front end of the compiler toolchain is generally designed for a specific programming language or family of programming languages but can produce a modular and independent IR1004.

The middle end of the compiler toolchain takes in the IR1004as input and performs a series of optimizations on the IR1004. As the IR1004is no longer tied to any specific programming language in the source code10, the middle end of the compiler toolchain can be created independently and can exhibit a modular design that allows for easy interchangeability.

The back end of the compiler toolchain takes in the IR1004and is responsible for any optimizations that are specific to a target instruction set architecture, like x86, x64, or ARM, and for code generation. For example, the back end includes the linker, which is responsible for producing the final target executable1008by linking together all the necessary binary files and libraries required for the final program. As with the front end and middle end, the back end of the compiler toolchain can be designed to operate in a modular fashion with respect to the other parts of the compiler toolchain. For example, it is possible for software engineers to write their source code10in a specific programming language, use the front end and middle end of the compiler toolchain to produce an optimized IR1004, then feed the IR1004to several different back ends that will produce executables suitable for different target instruction sets, like for a desktop computer running x86 or a mobile computing device on ARM.

In some embodiments, the front end of the compiler toolchain includes at least a Lexical Analyzer1001and Syntax Analyzer1001. The Lexical Analyzer1001takes the source code10and converts it into a sequence of tokens, or strings of characters. Next, the Syntax Analyzer1001analyzes the source code10to determine the relationships between the tokens in the source code10and stores the relationship in a data structure. Commonly, an abstract syntax tree1002, such as shown inFIG.2, is used. The abstract syntax tree1002is a tree data structure where the vertices are comprised of tokens and the edges represent the syntactical relationships between tokens. The abstract syntax tree1002is then input into an intermediate representation generator1003, which produces an intermediate representation (IR)1004in a form convenient for optimization in a code optimizer1005.

At this stage, the IR1004is passed to the middle end of the compiler toolchain for optimizations. After several iterations of applying optimizations on the IR1004, the IR1004is passed into the back end of the compiler toolchain. In the back end, a code generator1005transforms the IR1004into native code1006. The native code1006can include machine code and/or be composed of object files, and is sent to a linker1007to bundle the object files and any other required libraries and creates a suitable executable for a target instruction set architectures1008, like x86, x64, or ARM.

In some embodiments, one or more injection points200into the compilation process1000can be used to apply security measures where advantageous, such as shown inFIG.3. Turning toFIG.3, an exemplary injection point200B occurs at the code optimizer1005, where the compiler applies optimizations, usually in sequence, on the intermediate representation1004. Here, the protection transformations can be applied directly on the intermediate representation1004. This advantageously results in executable files where the security measures are incorporated with the game code and logic, making it much more difficult for unscrupulous players to identify and attack the security measures.

In another example, an exemplary injection point200C is at the linker1007, which bundles object files and produces executables suitable for target instruction set architectures1008. Here, security measures that are targeted for specific architectures can also be incorporated during the linking and executable creation process. For example, a game that is going to run on a mobile device likely using the ARM instruction set might require different security measures than a game that runs on a desktop computer using the x64 instruction set. Another exemplary injection point200A is at the source code10prior to being transformed through the compilation process1000. Injections at the source code10occur as security software engineers are actively developing and creating the video game. Security measures identify specific problematic design patterns in the source code10through methods like static analysis and suggest improvements to be implemented. Injections at the source code10also take the form of reusable and extensible security modules or toolkits that are available to software engineers to automatically provide flexible security when applied. Additionally and/or alternatively, an injection point200D after the target executable1008can be created. In contrast to conventional systems, this injection point is primarily for, but not limited to, finishing touches or tying up loose ends to supplement the other security measures that have already been incorporated in the target executable1008. Although four injection points200are shown and described for exemplary purposes only, those of ordinary skill in the art can appreciate that the advantages of the system and methods described herein can be applied to similar or like compilation phases, including, for example, the incoming edges of the four injection points200described above (e.g., a part of the edge of the injection points in addition to the injection points200).

Although not shown, another exemplary injection point200occurs as the abstract syntax tree1002is input into an intermediate representation generator1003. Here, the protection transformations advantageously can be full source-to-source transformations or source-to-IR transformations. As an example, developers of games frequently use utility functions provided by compilers for common tasks, such as initializing or copying variables. These utility functions are well known, have distinct patterns, and are frequently targeted by hackers and cheaters. Accordingly, the injection point200as the abstract syntax tree1002is input into an intermediate representation generator1003enables protection transformations by replacing the utility functions provided by compilers for functionally equivalent custom implementations developed by game security engineers. As another example, variables and functions can have metadata added to in this stage to better inform protection transformations later during code generation. Other examples of exemplary injection points200are discussed herein with reference toFIGS.3-9.

Similarly, although described as injection points200, the compilation process1000includes any application, injection, encryption, encoding, transformation, translation, and/or operation of security measures or protection transformations discussed herein.

FIG.4illustrates an exemplary flow diagram depicting the video game development process under some embodiments. Turning toFIG.4, one or more tools are available to developers including, for example, one or more Obfuscators301, Protectors302, Trackers303, and Analyzers304. The source code10is then passed to a distributed compiler305that supports distributed compilation306A . . .306N and the application of protection transformations or security measures307A . . .307N. Each of the distributed compilers305A . . .305N can work independently from the other distributed compilers305A . . .305N allowing compilation to be conducted in parallel and greatly increasing compilation speed. Each of the distributed compilers also has the capability to inject security measures307A . . .307N, distributing the obfuscation process and accomplishing it during compilation to decrease the time until the target obfuscated executable1008is produced for testing and further development. Stated in another way, those of ordinary skill in the art will appreciate that the security measures described herein can be applied at the front-end, middle, back-end, and linking phases of building an application.

In order to allow software engineers to have finer control over their desired security measures and to allow them to create expanded security capabilities, some embodiments include several reusable and extensible tools or modules that software engineers can employ to create highly secure, highly performant video games. These security modules, like the Obfuscators301, Protectors302, Trackers303, and Analyzers304can range in function and generality. Some modules are highly general and can be applied to nearly any video game software. Other modules, however, are developed specifically for certain types of video games, such as racing games, first person shooters, role playing games, etc. Modules are also developed specifically for certain types of target instruction set architectures, like x64 or ARM. These modules are independent, extensible, and could be easily applied to new games, automatically applying security benefits while maintaining performance. The modules are also tuned for a distributed video game development environment. As video games mature into vast productions with budgets in the billions, the creation of video games is a collaborative endeavor requiring vast teams of software engineers working in unison on the same software. Software engineers develop independent modules that are loaded into a toolkit or dashboard that would be available to all software engineers. Software engineers could then extend or build upon these modules to collaboratively and iteratively improve and develop these security modules.

In some embodiments, a class of these reusable security modules are Obfuscators301. Obfuscators301are a class of protection transforms for the marking and obfuscation of variables or code. Obfuscators301, as an illustration, offer new managed data types, e.g., secure integer or secure string, that are protected by the game automatically. Using these new managed data types, a software engineer designates specific variables that are likely to be sensitive (e.g., a player's health, position, score, etc.) as they write source code10. Furthermore, Obfuscators301can also be configured to automatically obfuscate certain variables or code based on how those variables or code are used during compilation or execution. In this way, Obfuscators301allow software engineers to precisely target the variables and code that require obfuscation, while also automatically providing obfuscation for certain patterns of compilation or execution that indicate that obfuscation is required. The Obfuscators301are developed in order to perform the obfuscation for variables at one or more injection points200. Obfuscators accomplish their transformations in various ways, for example, by slicing the data in the variables into small fragments and shuffling the fragments in order to make reconstitution of the variable difficult.

Obfuscators301similarly provide tools for marking logic and for obfuscating code. Software engineers have the capability to target pieces of logic for obfuscation at several levels. An engineer could mark an entire file, a class, an object, an interface, a function, or even a line or a set of lines of code in a video game as sensitive in order to ensure that the code will be apply protection transformations during compilation. Obfuscators301can also automatically target certain sections of logic or code for protection transformations based on operational usage or patterns in compilation. Obfuscators301, like all other security modules, are integrated during the compilation process1000and appear in the same manner as other game code in the target executable1008. In contrast, commercially available security systems in the prior art employ their security measures after the target executable1008has been created and will have specific sections that show obvious signs of obfuscation, attracting the attention of unscrupulous players and providing a clear target for reverse engineering efforts.

In some embodiments, a class of these reusable security modules are Protectors302. Protectors302are a class of security modules that serve as anti-tampering mechanisms. When unscrupulous players attempt to attack data or logic that has been the target of protection transforms, Protectors302are designed to react and respond in various ways during runtime, or while the program is executing. For example, Protectors302can reverse the attack, by restoring the modified value or logic from a specially saved copy, or protectors302can also detect an attack is occurring and respond by admonishing the player or closing the game. Protectors302are lightweight and highly adjustable and adaptable. Protectors302, like all other security measures, are incorporated and injected during compilation, making it more difficult for unscrupulous players to identify. Protectors are also not limited to data or logic that have had protection transforms applied but can also protect unmodified data or logic.

As an example, a Protector302performs cyclic redundancy checks (CRC). The CRC Protector302receives a range of code to check, a place in the code to execute, and what actions to take in case of a positive or negative evaluation at runtime. When the video game is running, at specified times, CRC Protector looks at the specified bytes in memory, perform the CRC, and take the action specified at compile-time in case of positive or negative evaluations. As another example, a Protector302protects the nature of function calls. Generally, function calls are mapped out and pre-determined during the compilation process1000. Unscrupulous players are able to use static analysis tools to analyze these functions calls without ever having to run the game. The Function-Call Protector automatically converts all function calls to become computed at run-time instead of during compilation. The Function-Call Protector can counteract certain reverse engineering tactics like static analysis, forcing unscrupulous players to analyze the code at runtime. Other examples of Protectors include instructions for detecting the presence of other software, like debuggers or virtual machines, and react accordingly. Protectors can also encode, decode, or restore various types of variables at compile or run-time to counteract reverse engineering efforts. In some embodiments, Protectors include a variety of forms and aims to offer flexible protection.

In some embodiments, a class of these reusable security modules are measurement tools called Trackers303. Trackers303play a vital role in measuring the performance costs of these applied security mechanisms. Modern video games must fit within exceedingly high-performance expectations in order to withstand the fast-paced environment that modern games require. One of the largest costs in applying security measures is the performance cost, especially for any processes that must execute during runtime, like the Protectors302. Trackers303, thus, represent another invaluable tool for video game developers who want to improve security measures, while maintaining the high standard of performance. Trackers303, like other security modules, can be generic and applied to normal functions in the game code or more specific, for example, tracking the performance costs of specific Protectors302under different anti-tampering strategies.

A problem with current anti-tampering mechanisms is that they are often one-size-fits-all and often present untenable variations in time in accomplishing their integrity checks. An anti-tampering mechanism that runs quickly on 90% of inputs but inconsistently performs slowly on 10% of inputs does not meet the high-performance expectations required by modern video games and could lead to dropped frames, leading to a poor video game experience for the player. This problem can be diagnosed, tuned, and eliminated with the use of customized Trackers303that can be track the performance costs of the discussed security measures.

Trackers303are not limited to measuring performance during runtime. As Trackers303and the other security modules are closely integrated into the compilation process1000, Trackers303can also measure the performance of the various transformations and processes during compilation. Trackers303have the capability to granularly capture the time it takes to create the IR1004in the IR Generator1003, the time it takes to compile the IR1004into object files, the time it takes the linker1007to link the target executable1008, and the post-processing time it takes after linking to resolve symbols and canonical values. Each individual process or subprocess of the compilation process1000can be meticulously measured in order to identify bottlenecks or to identify how certain changes affect the compilation time. Trackers303can help optimize the video game development process to help more secure video games during a shorter period.

In some embodiments, a class of reusable security modules are analytical tools called Analyzers304. Analyzers304allow developers to flexibly examine the compilation process1000and the target executable1008in order to provide helpful analytics to improve security measures. Analyzers304are similar to Trackers303but not necessarily fine-tuned to collect time and performance-based information. Analyzers range greatly in function and can operate at one or several of the injection points200. For example, an Analyzer304could operate on the IR1004at the Code Optimizer & Generator1005to determine code that is rarely executed or frequently executed. Software engineers can then focus the efforts of Protectors302on parts of the code that are frequently executed. As another example, an Analyzer304could be mobilized during the linking phase1007to collect helpful analytics such as counting the number of strings or Windows API functions used in the executable. Strings can provide valuable information to adversaries and contribute to information leakage. Using analyzers, software engineers can minimize information leakage by minimizing or obfuscating the strings in the linker1007. Similarly, developers can collect information about the Windows API or other operating system functions used in the executable and choose to replace them with more secure variants developed by the developers.

Additionally and/or alternatively, although not shown, in some embodiments, the class of reusable security modules include software virtualizations platforms. The software virtualization platforms allow developers to flexibly adapt the compilation process1000and the Code Optimizer & Generator1005for an architecture that is specific to a virtual instance of the native code. In other words, the software virtualization platforms can apply virtualization, mutation, and combined mutation of application code with subsequent virtualization. By way of example, the application code can include virtualizations of a secured memory, a secured CPU, one or more secured registers, a secured stack, and so on. The software virtualization can be applied to an instruction, a block of code, a function, or any component of the application code. In some embodiments, the software virtualization can further include nested virtualizations.

With the extra information available during the compilation process1000, software engineers can create a wide variety of reusable security modules that were not previously possible. Security modules can be configured at one or several injection points200depending on the needs of the module. For example, a Protector302that performs a CRC can be configured at the Code Optimizer & Generator1005to insert the logic to perform a CRC on a certain section of code. At that stage, however, the compilation process1000does not have the canonical value, the binary value, that is required to perform the CRC. The Protector302can finish its configuration during the linking phase1007when the canonical value can be supplied. Security modules can also interact with each other to provide richer functionality, increasing the complexity of the protection of the game code. In this way, security modules can perform their various functions, such as applying their protection transformations or retrieving information for future use, at one or several of the injection points200during the compilation process1000. Security modules can also work in conjunction with other security modules in programmatic and dynamic ways that were not previously possible. For example, Protectors302could be configured to work in conjunction with Trackers303to dynamically be inserted during the compilation process1000in sections of code that are executed most often. This would allow the evolution of security measures that are more automated and require less and less manual configuration by software engineers.

Another benefit of injecting or applying security measures during compilation is increased pace in the game development process. As software engineers develop the source code10for a video game, they must continually compile the game to ensure that new additions to the source code10are free from errors or bugs. While some errors can be detected by the Syntax Analyzer1001during the compilation process1000or with the application of unit or regression tests, other errors can only be detected by running tests after the target executable1008has been built. This requires software engineers to continually compile and produced target executables1008in order to test the additions to the source code10. As codebases increase in size, the compile time of codebases likewise increases, significantly hampering the video game development process. Software engineers have been able to decrease the compilation and build times by distributing the compilation process1000and compiling the video games on several computers in parallel. Much of software is now engineered in order to be conducive to this type of distributed compilation and build in order to decrease development times. Conventional security systems that apply their security measures exclusively on an executable produced after compilation act as a bottleneck to this process because these systems are not configured to be distributed. They must take in the entire monolithic executable as an input, then usually on a single computer, analyze the machine code to apply inferences and try to inject security measures. As the size and complexity of video games increases, this task is consuming increasingly more time, cannot be distributed, and is responsible for a large increase in video game development time

In contrast, a system that incorporates security measures during the compilation process1000directly can benefit from distributed computing.FIG.4displays such a distributed system with a distributed compiler305that supports distributed compilation306A . . .306N. When source code10needs to be compiled, the compilation task is split among the distributed compilers305A . . .305N, allowing compilation to be conducted in parallel and greatly increasing compilation speed. Each of the distributed compilers305A . . .305N can be executed on specialized hardware that is optimized for parallel processing. Each distributed compiler305A . . .305N can take various forms like a separate computer, a server in a rack, a virtualized computer, or more. Each of the distributed compilers305A . . .305N possess the capability to apply security measures307A . . .307N, distributing the obfuscation process and accomplishing it in parallel during compilation to decrease the time until the target obfuscated executable1008is produced for testing and further development. As the encoding, encrypting, and obfuscation can now be accomplished in parallel over a distributed set of compilers, the present invention removes the bottleneck from the video game development process.

Additionally and/or alternatively, the compilation process1000can cooperate with a set of compiler and toolchain technologies such as, for example, the LLVM compiler toolchain infrastructure. The LLVM compiler toolchain infrastructure is a popular collection of modular compiler and toolchain technologies that offers many of the core components of the exemplary compilation process1000such as the Lexical and Syntax Analyzer1002, the IR generator1003, the Code Optimizer and Generator1005, and Linker1007. The LLVM compiler toolchain infrastructure offers a selection of front-end compilers that supports the compilation of nearly any programing language. Similarly, the LLVM compiler toolchain infrastructure offers a large variety of back-end compilers that can produce optimized target executables1008for nearly any instruction set architecture. The LLVM's modular architecture is supported by a programming-language-agnostic IR that can serve as the intermediary between several of the front end and back-end compilers.

The LLVM compiler toolchain infrastructure is open source and can be modified to inject or apply security measures at several points.FIG.5illustrates a diagram illustrating an exemplary embodiment using the LLVM compiler infrastructure. On the front end, a Clang compiler401can be used to parse the C or C++ source code10, create the abstract syntax tree1002, then produce the IR1004. The Clang compiler401is a popular front end for the C language family (C, C++, Objective C/C++, OpenCL, CUDA, and Renderscript). The IR1004is passed to a LLVM code optimizer and code generator402from the LLVM Core libraries. In some embodiments, the LLVM Core libraries can be modified to include injection point200of the previously discussed security measures during the IR optimization1005. The LLVM Core libraries then translate the IR1004to the native code1006, producing object files. On the back end, a LLD linker403is used to link the object files and create the executable for the target instruction set architecture1008. The LLD linker403is a drop-in replacement for system linkers that supports ELF, PE/COFF, Mach-O, and WebAssembly. In some embodiments, the LLD linker403can be modified to include the injection point200to apply security measures during the object and archive file processing1007and the generation of the target executable file1008. After the target executable is created, there can also be further injections to accomplish post-processing tasks such as resolving and creating any symbols or canonical values when necessary.

FIG.6illustrates another exemplary embodiment using the LLVM compiler toolchain infrastructure in the context of a build system. The system inFIG.6incorporates post-processing security measures after creation of executable code. As discussed previously, software engineers begin by writing the source code10, which in this instance is C/C++, a popular set of general-purpose, procedural programming languages. The source code10is passed to the LLVM/Clang Compiler401where it is transformed into the IR1004. The IR1004presents a favorable structure for applying code optimizations and for generating the native code1006for some applications. This LLVM Code Optimizer and Generator402accomplishes this task and creates the native code1006in OMF/COFF format, in this instance. OMF, or Relocatable Object Module Format, is a popular object file format that is used primarily for Intel x64 microprocessors, while COFF, or Common Object File Format, is another popular executable format used in Unix and Microsoft Windows-based systems. The native code1006is then passed to the LLVM LLD Linker403which links the files to create the target executable code1008. The target executable code needs to be created for all popular formats and in this instance PE, the Portable Executable format, and ELF, the Executable and Linkable Format are created. PE is generally popular on Windows systems, while ELF is popular on Unix-based systems. The source code10, the IR1004, the native code1006, and target executable code1008also all represent possible injection points where security measures can be applied.

FIG.6includes additional injections points200E-F, which show connections between the build system and the LLVM/Clang Compiler401and LLVM LLD Linker403. The injection point200E, similar to injection point200B, is applied on the IR1004. The injection point200E, however, applies security measures on the IR1004after the IR has been created but before it has undergone any optimizations, while injection point200B applies security measures after the IR has undergone optimizations. The injection point200F applies security measures after the LLVM LLD Linker403has completed and when the target executable has already been created.

FIG.6also includes a build system which, generally, is the system responsible for collecting all the necessary components required to create the target executable code. The requirements and duties of a build system can vary greatly depending on the type and complexity of the target executable code. For example, a build system for a modern and highly complex video game that contains several packages of source code10and libraries in binary form might also need to accommodate a distributed compilation system as described inFIG.4. The build system inFIG.6uses, as an example, CMake, a popular cross-platform and open-source tool for managing build processes. By using CMake or similar software like the Microsoft Build Engine (MSBuild), software engineers can easily create project files for different platforms, such as Solution files for Microsoft Windows or Makefiles for GNU.

The build system allows for plugins501that can be used to apply security measures. After the IR1004is generated at the LLVM/Clang Compiler401, the build system plugin501accomplishes various pre-processing tasks503on the IR1004. For example, transformations, encodings, and obfuscations that rely on the game logic can be applied on the IR1004as well as the extraction of all strings and canonical values. Similarly, after the target executable code1008is created at the LLVM LLD Linker403, another build system plugin502accomplishes various post-processing tasks504on the ELF/PE executable. For example, during post-processing504, the build system plugin502can resolve and create any symbols or canonical values as necessary. Other security measures, such as transformations, obfuscations, or encodings can further take place in this post-processing504. AlthoughFIG.5andFIG.6feature the LLVM compiler toolchain infrastructure, other compiler infrastructures like Microsoft Visual C++ (MSVC) could be used when desired.

FIG.7illustrates a diagram illustrating an alternative embodiment ofFIG.5using the LLVM compiler infrastructure. As before, on the front end, a Clang compiler401can be used to parse the C or C++ source code10, create the abstract syntax tree1002, then produce the IR1004. As shown inFIG.7, and as previously described, an injection point200can be included between the generation of the abstract syntax tree1002prior to the generation of the IR1004.

As discussed with reference toFIG.5, in some embodiments, the IR1004is passed to a LLVM code optimizer and code generator402from the LLVM Core libraries. In some embodiments, the LLVM Core libraries can be modified to include injection point200of the previously discussed security measures during the IR optimization1005. The LLVM Core libraries then translate the IR1004to the native code1006, producing object files.

Additionally and/or alternatively, as shown inFIG.7, a custom code generator701can receive the IR1004. Advantageously, instead of directly producing the native code1006, the custom code generator701can use the IR1004to generate a virtualization of the native code1006. In other words, the custom code generator701can generate code for an architecture that is specific to that software's virtual machine instance, such as for use with the software virtualization platforms disused above.

In some embodiments, the compilation process1000advantageously can be adapted to obfuscate and protect third-party libraries that are shipped as object code. For example, as shown inFIG.7, a convertor702can receive the object code and translate the object code back to the IR1004. Any of the protection mechanisms discussed herein can be applied to the IR1004, which is then compiled back to machine code prior to being linked by the linker404.

On the back end, the LLD linker404is used to link the object files and create the executable for the target instruction set architecture1008. The LLD linker404is a drop-in replacement for system linkers that supports ELF, PE/COFF, Mach-O, and WebAssembly. In some embodiments, the LLD linker404can be modified to include the injection point200to apply security measures during the object and archive file processing1007and the generation of the target executable file1008. After the target executable is created, there can also be further injections to accomplish post-processing tasks such as resolving and creating any symbols or canonical values when necessary. Although shown for exemplary purposes, each of the injection points200shown inFIG.7enable developers to insert/modify anti-tampering logic and the present system can include additional injection points200as desired.

FIG.8illustrates another exemplary embodiment ofFIG.6using the LLVM compiler toolchain infrastructure in the context of a build system. As discussed previously, software engineers begin by writing the source code10, which in this instance is C/C++, a popular set of general-purpose, procedural programming languages. Compared to the embodiment shown inFIG.6,FIG.8illustrates an exemplary injection point200G to access the source code10being passed to the LLVM/Clang Compiler401prior to the transformation into the IR1004. Advantageously, protections can be applied prior to the generation of the IR1004. For example, the reusable security modules shown can pre-process the abstract syntax tree1002(shown inFIG.3), modify the abstract syntax tree1002, and post-process the abstract syntax tree1002, for example, to replace the utility functions provided by compilers for functionally equivalent custom implementations developed by game security engineers.

The native code1006(or a virtualization of the native code1006, such as described with reference toFIG.5, or a transformed object file702in native code) is then passed to the LLVM LLD Linker403which links the files to create the target executable code1008. The target executable code needs to be created for all popular formats and in this instance PE, the Portable Executable format, and ELF, the Executable and Linkable Format are created. PE is generally popular on Windows systems, while ELF is popular on Unix-based systems. The source code10, the IR1004, the native code1006, and target executable code1008are also all components where security measures and/or protections transforms can be applied by inserting injection points or generating custom code, such as for an architecture that is specific to that software's virtual machine instance discussed herein.

The build system allows for plugins501that can be used to apply security measures. After the IR1004is generated at the LLVM/Clang Compiler401, the build system plugin501can perform various pre-processing tasks503on the IR1004. For example, transformations, encodings, and obfuscations that rely on the game logic can be applied on the IR1004as well as the extraction of all strings and canonical values. Similarly, after the target executable code1008is created at the LLVM LLD Linker403, another build system plugin502can perform various post-processing tasks504on the ELF/PE executable. For example, during post-processing504, the build system plugin502can resolve and create any symbols or canonical values as necessary. And in some embodiments, finalization, post-processing, resolving, and creating additional symbols or canonical values can be applied, leveraging an injection point200built into the linker403. Other security measures, such as transformations, obfuscations, or encodings can further take place in this post-processing504.

The described embodiments are susceptible to various modifications and alternative forms, and specific examples thereof have been shown by way of example in the drawings and are herein described in detail. It should be understood, however, that the described embodiments are not to be limited to the particular forms or methods disclosed, but to the contrary, the present disclosure is to cover all modifications, equivalents, and alternatives.

Claims

  1. A security-based method for compiling an executable from a source file, comprising: converting the source file into a sequence of tokens via a lexical analyzer;generating an abstract syntax tree from the sequence of tokens;producing an intermediate representation of the generated abstract syntax tree;performing optimizations on the intermediate representation;transforming the produced intermediate representation into machine code;creating an executable by linking the machine code with one or more libraries;and incorporating at least one security measure during the security-based method for compiling the executable, wherein said incorporating comprises injecting a class of reusable security modules, the class including at least two protectors, each protector in operable communication with each other to perform at least one cyclic redundancy check during runtime of the compiled executable.
  1. The method of claim 1, wherein said incorporating the at least one security measure comprises applying protection transforms between said generating the abstract syntax tree and said producing an intermediate representation of the generated abstract syntax tree.
  2. The method of claim 2, wherein said applying protection transforms comprises replacing one or more utility functions provided by a compiler with functionally equivalent custom implementations.
  3. The method of claim 1, wherein said incorporating the at least one security measure comprises applying protection transforms prior to said converting the source file into a sequence of tokens.
  4. The method of claim 1, wherein said incorporating the at least one security measure comprises applying protection transforms between said performing optimizations on the intermediate representation and said transforming the produced intermediate representation into machine code.
  5. The method of claim 1, wherein said incorporating the at least one security measure comprises applying protection transforms during said creating the executable by linking the machine code with one or more libraries.
  6. The method of claim 1, wherein said incorporating the at least one security measure comprises applying protection transforms to the created executable.
  7. The method of claim 1, wherein said transforming the produced intermediate representation into machine code comprises generating, via a custom code generator, a virtualization of the machine code.
  8. The method of claim 1, further comprising: translating the machine code back into a second intermediate representation;applying protection transforms to the second intermediate representation;and compiling the second intermediate representation with the applied protection transforms back into the machine code for said creating the executable.
  9. A non-transitory nonvolatile computer program product comprising a processor-readable medium having a sequence of instructions stored thereon, which, when executed by the processor, causes the processor to execute a security-based method for compiling an executable from a source file, the sequence of instructions comprising: instructions for converting the source file into a sequence of tokens via a lexical analyzer;instructions for generating an abstract syntax tree from the sequence of tokens;instructions for producing an intermediate representation of the generated abstract syntax tree;instructions for performing optimizations on the intermediate representation;instructions for transforming the produced intermediate representation into machine code;instructions for creating an executable by linking the machine code with one or more libraries;and instructions for incorporating at least one security measure during the security-based method for compiling the executable, wherein said instructions for incorporating comprises instructions for injecting a class of reusable security modules, the class including at least two protectors, each protector in operable communication with each other to perform at least one cyclic redundancy check during runtime of the compiled executable.
  10. The computer program product of claim 10, wherein said instructions for incorporating the at least one security measure comprises instructions for applying protection transforms between said instructions for generating the abstract syntax tree and said instructions for producing an intermediate representation of the generated abstract syntax tree.
  11. The computer program product of claim 11, wherein said instructions for applying protection transforms comprises instructions for replacing one or more utility functions provided by a compiler with functionally equivalent custom implementations.
  12. The computer program product of claim 10, wherein said instructions for incorporating the at least one security measure comprises instructions for applying protection transforms prior to said instructions for converting the source file into a sequence of tokens.
  13. The computer program product of claim 10, wherein said instructions for incorporating the at least one security measure comprises instructions for applying protection transforms between said instructions for performing optimizations on the intermediate representation and said instructions for transforming the produced intermediate representation into machine code.
  14. The computer program product of claim 10, wherein said instructions for incorporating the at least one security measure comprises instructions for applying protection transforms during said instructions for creating the executable by linking the machine code with one or more libraries.
  15. The computer program product of claim 10, wherein said instructions for incorporating the at least one security measure comprises instructions for applying protection transforms to the created executable.
  16. The computer program product of claim 10, wherein said instructions for transforming the produced intermediate representation into machine code comprises instructions for generating, via a custom code generator, a virtualization of the machine code.
  17. The computer program product of claim 10, said sequence of instructions further comprising: instructions for translating the machine code back into a second intermediate representation;instructions for applying protection transforms to the second intermediate representation;and instructions for compiling the second intermediate representation with the applied protection transforms back into the machine code for said creating the executable.
  18. A distributed system for security-based compiling of an executable from a source file, comprising: a data network;and one or more distributed compilers, each distributed compiler in operative communication with the one or more distributed compilers over the data network and comprising a non-transitory nonvolatile computer program product comprising a processor-readable medium having a sequence of instructions stored thereon, which, when executed by the processor, causes the processor to execute the sequence of instructions comprising for receiving an allocated portion of the source file, converting the allocated portion of source file into a sequence of tokens via a lexical analyzer, generating an abstract syntax tree from the sequence of tokens, producing an intermediate representation of the generated abstract syntax tree, performing optimizations on the intermediate representation, transforming the produced intermediate representation into machine code, creating an executable by linking the machine code with one or more libraries, and incorporating at least one security measure during the security-based method for compiling the executable, wherein said incorporating comprises injecting a class of reusable security modules, the class including at least two protectors, each protector in operable communication with each other to perform at least one cyclic redundancy check during runtime of the compiled executable.
  19. The distributed system for security-based compiling of claim 1, wherein at least one of the one or more distributed compilers includes an LLVM compiler toolchain infrastructure.

Disclaimer: Data collected from the USPTO and may be malformed, incomplete, and/or otherwise inaccurate.