User:Softlock/Portable Executable Automatic Protection

Portable Executable Automatic Protection

This article describes an automated technique for protecting portable executable files used in Windows NT Platform. The proposed technique mainly works on Portable Executable format for 32-bit applications. The article describes the PE format illustrating its main structures followed by an overview on existing protection techniques, and then it illustrates a new technique used in packing the PE file in order to protect it against disassembling and reverse engineering. The protection technique involves a static operation on the file reversed by a dynamic one during the run-time. The static and the dynamic operations provide a combined solution for software protection against static (Automatic) and dynamic reverse engineering. The article studies the effect of protection on the performance and provides a solution to enhance the results.

INTRODUCTION

edit

Portable Executable format [1] is used to represent executable files in all Windows NT platforms. The PE file format describes, file headers, sections and structures. File format is important to understand the loading process by the operating system and the linking mechanism to the other exiting libraries. A PE file is composed of a group of headers followed by a set of sections holding code, data and other useful information. The headers include DOS Header, NT Headers and Sections Headers [1] [2]. Each section header holds information like the size, the starting position, and the characteristics of the section. For example the “.text” section (code section) header provides the RVA (Relative Virtual Address) value which is used to determine the starting position of the section in memory, this value is important if the executable file is loaded in a location other than the preferred location (Re-Location) [1] [2]. Another example is the NT Headers which provide general information like PE signature, target machine type, the file characteristic, the Image Base, the Image Size and the Entry Point. The Image Base value determines the preferred starting address of the image when loading into memory. The Entry Point determines the address of the first instruction.

OVERVIEW

edit

Normal PE protection uses packing procedure, which alters the file structures, encrypt and compress the file sections and inject an executable section to perform the unpacking. During run-time, the injected section unpacks the file into the memory, correct the structure and finally jump to the original entry point in order to start the normal execution. There are many publicly available packers , which are useful to protect the code and data in the file, though their security on disk and memory can be compromised [3] [4][5]. There have been number of researches regarding the Software Protection and DRM systems which discuss the problem of securing the software and the intellectual property of a software vendor against reverse engineering and piracy. The researches propose different techniques, which represent possible methods for securing the software. Code Obfuscation [6] is considered a common method for software protection. In [7]Diego et al present a model for software protection using code Obfuscation and Fingerprinting combined with license enforcement. The presented model provides a semi-automated process for protection that involves the direct interaction of the software developer to modify his written code in order to make use of the protection process, unlike the fully automated model proposed by this paper. Code obfuscation was presented in [8] by modifying a simple compiler (tcc) to modify certain unconditional branching instructions to conditional branching aiming at misleading automated reverse engineering tools [5] to detect the original code. Another powerful technique for protecting software is self-modifying code, which means that the code is modifying itself during run-time, meanwhile keeping it hard to reverse it statically [9]. Another useful property for self-modifying code presented in [10] to add additional strength to software self-check summing maintaining the software integrity. Whit-Box cryptography is another method for adding security to software; however, it suffers from static or dynamic key recovery attacks [6].

STATIC PROTECTION OPERATIONS

edit

This section describes the required steps to apply the static protection on the executable files. The steps are performed in the Post-Build phase; it modifies the PE file structures, changes its characteristic, alters contents, and injects new sections. Following section describes the static modifications applied to the PE file in order to apply the protection.

Modifying PE Structure

edit

This step modifies the values in the PE File headers that describe the properties and characteristics of the file. The changed values are the Number of Sections, Address of Entry Point, Size of Image and Data Directories RVAs and Sizes (Import, Relocation, COM…) The protection process mainly involves adding a new section (Security Section) to the PE file. This section is supplied with the necessary information used to perform the unpacking (reversing the modifications). The supplied information includes the original PE File headers and structures, which are removed or altered while applying the protection. Fig1 illustrates the overall structure of the PE file after the modifications, with the added Security Section.

PE Headers
Dos, NT, Section Headers
Code
Data
Other Sections
Security Section

New Code Stub, Useful Information in Unpacking

Fig1. Illustrates the structure of the PE file after applying the Modifications

Modifying Import Table Structure

edit

The protection operation mainly depends on changing the Imported Address Table; it provides the imported DLLs and their Functions, upon which the PE file depends on during run time. The protection works by modifying the Imported Address Table, where the new table will depend on the Unpacking DLL. The Unpacking DLL works with the Security Section to perform the unpacking operation.

Static Code Redirection

edit

The Static Code Redirection process is very important for providing extra security and protection to the PE file. This operation is similar to the method used in [8], aiming to redirect certain JMP/CALL instructions in the PE Original Code towards Interception Jump Table (IJT) that depends on the Unpacking DLL. Figure2 illustrates the IJT structure, while Fig3 illustrates the instructions used for the redirection operation in each IJT entry. The static code redirection process works by disassembling the PE code, then selecting certain Far JMP or CALL instructions and modifies their target locations to corresponding IJT Entry. The Unpacking DLL is responsible for correcting the IJT Entry code stub (during run-time – Dynamic Code Redirection) in order to redirect the execution flow towards the correct location.

PE File Encryption

edit

The protection process should encrypt certain parts of the PE file in order to protect it against disassembling and code reverse engineering, whether the file on disk or in the memory during the execution. The protection process will encrypt the code, data sections, original import table and IJT. The protection process should hide the key somewhere in the PE file, or it can use the key as a Derived Key from some parts of the PE file using any key derivation algorithms [11][12] . White-Box Cryptography [6] is considered a solution to this problem, which proposes a software only solution for protection against key recovery. We propose using a double encryption process, by combining the derived key with hardware based key (stored or derived from a hardware device, like Hardware Tokens or even a Machine Identifier). Combining several process of protection on the PE file makes it harder for automated reverse engineering and disassemblers tools to succeed in reversing the protected code. The code section encryption provides false program flow in case of direct disassembling. The encryption of the IJT moves the battle of reverse engineering from the easy static reverse engineering to the harder dynamic one. Moreover, linking the protection process to the Unpacking DLL increases the effort of the dynamic reverse engineering.


Fig3. Illustrates the Code Stub in each IJT entry, where the last JMP Instruction redirects the code towards the Original Instruction


DYNAMIC UNPACKING OPERATION

edit

The Dynamic Unpacking operation is responsible for unpacking the protected PE file in memory. The Unpacking DLL is the object that provides the dynamic protection. When the protected application is executed in memory, the Windows Loader automatically loads the Unpacking DLL, because it resides in the modified Import Address Table. The purpose of loading the Unpacking DLL while loading the protected application is to reverse the static protection modifications before the application starts the execution. The following steps explain the reversing (unpacking) operations:

  1. Go through the debugger detection procedure [13], and stop the unpacking operation if debugging behaviors are detected.
  2. Extract the PE special information from the Injected Security Section.
  3. Decrypt Code Section, Data Section, Original Import table and the IJT Stub located in the Security Section using a Derived (Combined) Encryption Key
  4. Perform Base Relocation Process [1]; if the Load Address of the PE file in memory was in a different location than the preferred address (Image Base)
  5. Load all Imported DLLs found in the original Import Address Table located in the inject Security Section, then retrieve the real memory addresses of all their Imported Functions, then update the Imported Address Table (IAT) [1] [2]. This step is associated with an operation called Dynamic PE Infection, mentioned later.
  6. Extract all IJT header information and descriptors, and retrieve the correct jump address for every IJT entry.
  7. Correct – if necessary – or corrupt the PE file Headers in memory [13].

The Unpacking DLL performs the above operations while loading, though in some cases (like protected DLLs) the Unpacking DLL performs these operations by receiving a call from the Unpacking Code Stub that exists in the Security Section in the PE file. The static operation changes the original Entry Point to reference the Unpacking Code Stub instead of the original Entry Point. The Unpacking Code Stub calls an Exported API from the Unpacking DLL, which performs the mentioned unpacking operations, and then the Code Stub ends by a JMP instruction to the OEP [1]. Transforming the Code Stub to Self-Modifying Code [9] can add extra strength to this code stub. One drawback for Self-Modifying Code is that it is used by many computer viruses, which might raise the threat of detecting the Protected Application as a virus by commercial Anti-Virus programs.

DYNAMIC PE INFECTION

edit

The purpose of the Dynamic PE Infection is to handle the control to the Unpacking DLL over all loaded modules in the protected Application memory space, and mainly keeps the Protected Application attached to the Unpacking DLL throughout the whole execution time. The operation works by API Interception, which main concept is to intercept some –selected- system APIs and perform some operations additional to the regular operation of that API.

The Dynamic Infection operation mainly works by changing the value of the target API Address in the infected module’s IAT (Imported Address Table) in memory. By changing this address, any CALL instruction –depending on the IAT values- will instead call another Function (with the same interface and parameters of the Original API) exported by the Unpacking DLL. These exported Interception APIs will perform extra functionalities over the main functionality of the Original Intercepted API. Fig4 illustrates the Interception process resulting from infecting a certain module in memory.

In Fig4, The Unpacking DLL modifies the IAT of the protected PE file in memory by replacing the IAT entry corresponding to a specific API (ex: API_1 Address) by the Address in the Unpacking DLL. When the Original PE code starts execution, it will make a call to API_1, as illustrated by the CALL instruction. The CALL instruction makes the API call by referencing the API address in the IAT. The Win Loader is responsible for updating the IAT with the real Addresses of all the APIs imported by the PE file. By replacing this address, the CALL instruction will execute the Interception API_1 in Unpacking DLL instead of the real API. The Interception API is responsible for calling the Real API in its System DLL in order to make the calling process transparent to the protected PE. This Dynamic Infection operation is recursive over all loaded modules in the application’s memory space.

DYNAMIC CODE REDIRECTION

edit

As mentioned earlier in the Static Code Redirection, the redirection operation is responsible for redirecting the code execution to its correct sequence. Figure5 illustrates the Redirection Operation. The Code Redirection increases the security and protection of the PE file against Reverse Engineering, Cracking and Memory Dumping [13]. The process mainly keeps the PE file always attached to the Unpacking DLL in order to perform the execution correctly, as any attempt to unload the Unpacking DLL or trying to remove it from the Import Table of the PE file will lead to false execution of the original code. Although this operation adds more security to the PE file, it still adds overhead on the execution process, especially in the case of huge loops as in Graphics Applications. The overhead is high, as the operation adds extra instructions IJT Code Stub and redirection operation for every modified JMP/CALL instruction. In order to solve this overhead problem, the Dynamic Code Redirection should provide an algorithm that somehow decreases the overhead on the execution and in the same time does not affect the security of the PE file. The main target of the redirection algorithm is to decrease the overhead of redirection execution during the original code execution while maintaining security. The algorithm treats each IJT Entry as a stand-alone entity, and monitors the number of executions of each entity. At the same time, it monitors the Global number of executions (Global Number of Hits) of all the entities in the execution time. Those two counters will be the keys to balance the speed, the performance and the Security of the protected application.


Each entity holds some information that describes it. It holds the Entity State, whether it is Encrypted, Decrypted or Corrected, besides it holds the Number of Hits, providing how much this entity has been executed. The following is the explanation of each state:

  • Encrypted: The destination RVA in the last JMP instruction in the IJT Entry -in Fig3- is encrypted and requires decryption by Redirect function in order to perform execution correctly.
  • Decrypted: The Destination RVA in the last JMP instruction in the IJT Entry is decrypted and requires no decryption, though it may affect the Redirection Algorithm depending on the number of hits
  • Corrected: The Original Instruction in the Original Code is corrected and will not jump to the IJT Entry, as its destination RVA is corrected.

The algorithm modifies each IJT Entry according to its Entity State, Entity Number of Hits, Global Number of Hits for all entities, Number of Corrected/Decrypted Entities per module and four predefined thresholds. The four thresholds are:

  • Entity Hit Threshold (EHT): A threshold, which implies that the state of the entity should change to corrected if its Number of Hits exceeds that threshold. The algorithm should compare this threshold to the Number of Hits of the executed entity.
  • Global Hit Threshold (GHT): A threshold, which implies that the state of a decrypted IJT Entry with the minimum Number of Hits should change to encrypted. The algorithm should compare this threshold to the Global Number of Hits.
  • Correction Threshold (CT): A threshold, which implies that the total number of corrected instructions in memory is high and the algorithm should encrypt the entry with the Minimum Number of Hits. This threshold can be a percentage of the total number of entries (ex: 25%)
  • Decryption Threshold (DT): A threshold, which implies that the total number of decrypted entries is high and the algorithm should encrypt the entry with the Minimum Number of Hits. This threshold can be a percentage of the total number of entries (ex: 50%)

The Entity Hit Threshold mainly aims to speed up the execution of the original code by correcting its destination address, so that this instruction will not jump to the IJT Entry anymore, assuming that exceeding this threshold indicates the continuous execution of that specific instruction. Meanwhile, the Global Hit Threshold, Correction Threshold and Decryption Threshold aim to maintain the security by encrypting a decrypted/corrected Entry.Figure6 illustrates the state diagram of an IJT Entry.


PROTECTED APPLICATIONS PERFORMANCE

edit

This section will present some test results applied to protected applications to assess the protected applications performance compared to their performance before applying the protection. The section also introduces test results to assess the Redirection algorithm and its effect on the performance and security of the protected application. The first performance test was to assess the executable loading duration overhead. Since the protected application is statically linked to the Unpacking DLL, the Unpacking DLL loading will add certain overhead over the loading time of the executable. This overhead will add time delay to the original loading time of all DLLs in the Import Table, due to performing the Unpacking, PE Infection and Redirection operations by the Unpacking DLL. This delay is defined as Unpack Delay Duration. The performance test is conducted to test this Unpack Delay Duration. The test works by protecting an Executable file and measuring the duration of the Load Operations done by the Unpacking DLL. These measures will be applied to different number of modules in one application. For example, if Executable A depends on DLLs B & C, then the measures will be applied on protected A only, then A&B, then A B&C and so forth. Figure7 shows a graph for the Average Unpack Delay Duration per Protected Modules. The test is applied to different applications and number of their dependencies. It must be stated that there cannot be a fixed Unpack Delay Duration for all applications and modules, as the complexity and number of dependencies of the modules differ from one to another. Therefore, the graph result can differ depending on the target-protected applications. The test results show that the maximum Average Unpack Delay Duration may reach 300 milliseconds for a set of four protected modules.


The second performance test is to assess the Redirection algorithm. A custom application written in x86 Assembly was used in order to provide a more specific test bench for testing the effect of the algorithm. The custom application contains massive loops with 24 function calls (CALL instructions) which shall be modified by the Static Code Redirection process. The custom application takes 9500 milliseconds for the whole execution time before applying protection. The applied protection mainly tested the performance and security of the application after finishing the execution, by adjusting the thresholds with different values. The performance test is to check the total execution time of the application, while the security test is to check the state of all IJT entries after finishing execution. A software cracker using Dynamic Reverse Engineering can simply wait until the application finishes execution and right then he dumps the application from memory to disk. The Code redirection security should make this operation useless, as the dumped Code section would give false execution. Table1 presents the final test results for the protected application with different threshold values. The results show that changing the Thresholds values affects the performance and security of the protected application. The first entry in Table1 shows a result of adjusting threshold to maximize the Security, which by the end of the execution kept 30 IJT Entries encrypted, but the performance was weak as execution duration increased by 177% over the original time. The second table entry shows a result of adjusting the thresholds to decrease the security slightly for the sake of performance, which led to a result of 31 Decrypted IJT Entries with enhanced performance of about one extra second over the original time. Though the performance result is considered acceptable, the application security is at stake, as all the IJT Entries are decrypted without any encrypted entries. The third entry shows a result for adjusting thresholds values in order to increase the security without affecting the performance severely, which in turn increased the number of encrypted IJT Entries to four. The 5th table entry is the actual test for the Redirection Algorithm. The entry shows a result of adjusting all the thresholds to maintain security and enhance the performance. The performance was enhanced by adjusting the Number of Hits Threshold to 50, which in turn affected the Entries states to be corrected. Meanwhile, adjusting the Decryption and Correction thresholds to 0.9&0.8 respectively maintained the security by keeping 8 IJT Entries Encrypted and 3 IJT Entries Decrypted. This adjustment enhanced the performance by adding 600 milliseconds - 6.5% increase - over the original time, which gave the fastest performance. This performance is better than the 2nd entry thresholds and maintains more security.

The Redirection Algorithm proposes two problems that can be a target of a future work. The first problem is how to enhance the selection of the JMP/CALL instructions to be redirected throughout the Static Code Redirection aiming at providing the highest Security with the optimal performance. The second problem is to find a Mathematical model for the Dynamic Code Redirection operation that can predicts the behavior of the protected application regarding both Application’s Security and Performance.


References

edit
  1. ^ a b c d e f Microsoft Portable Executable and Common Object File Format Specification, Microsoft
  2. ^ a b c Matt Pietrek, “An In-Depth Look into the Win32 Portable Executable File Format”, MSDN Magazine, February 2002 http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
  3. ^ Li Sun, Tim Ebringer, Serdar Boztas “Hump-and-dump: efficient generic unpacking using an ordered address execution histogram”, Witham Laboratories, Australia http://www.datasecurity-event.com/uploads/hump_dump.pdf
  4. ^ Matias Madou, Bertrand Anckaert, Bjorn De Sutter, Koen De Bosschere, “Hybrid Static Dynamic Attacks against Software Protection Mechanisms”, Proceedings of the 5th ACM workshop on Digital Rights Management, November 07-07, 2005, Alexandria, VA, USA
  5. ^ a b Christopher Kruegel, William Robertson, Fredrik Valeur, Giovanni Vigna, “Static disassembly of obfuscated binaries”, Proceedings of the 13th conference on USENIX Security Symposium, p.18-18, August 09-13, 2004, San Diego, CA
  6. ^ a b c P.C. van Oorschot, “Revisiting Software Protection”, Proc. 6th Int'l Conf. Information Security (ISC 03), LNCS 2851, Springer-Verlag, 2003, pages. 1–13
  7. ^ Diego Bendersky, Ariel Futoransky, Luciano Notarfrancesco, Carlos Sarraute, and Ariel Waissbein, “Advanced Software Protection Now”, CoreLabs Technical Report , 2003
  8. ^ a b Chris Coakley, Jay Freeman, Robert Dick, “Next-Generation Protection against Reverse Engineering”, Anacapa Sciences Inc, http://www.anacapasciences.com/publications/protecting_software2005.02.09.pdf, 2005
  9. ^ a b Bertrand Anckaert, Matias Madou, and Koen De Bosschere, “A Model for Self-Modifying Code”, Lecture Notes in Computer Science, Springer Berlin / Heidelberg, Volume 4437/2007, pages 232-248 , 2007
  10. ^ Jonathon T. Giffin, Mihai Christodorescu, Louis Kruger, “Strengthening Software Self-Checksumming via Self-Modifying Code”, Proceedings of the 21st Annual Computer Security Applications Conference, p.23-32, December 05-09, 2005
  11. ^ B. Kaliski, RFC2898 - PKCS #5: “Password-Based Cryptography Specification Version 2.0”, RSA Laboratories
  12. ^ Shakir M. Hussain and Hussein Al-Bahadili “A Password-Based Key Derivation Algorithm Using the KBRP Method”, American Journal of Applied Sciences, 777-782, 2008
  13. ^ a b c Peter Ferrie “Anti-unpacker tricks”, Microsoft, USA, http://www.datasecurity-event.com/uploads/unpackers.pdf
edit