An Android application hardening method, system and device
By generating virtual code through a custom interpreter and dynamic instruction reorganization algorithm, the problem of reverse engineers being able to obtain the source code of Android applications in existing technologies is solved, achieving higher instruction-level protection strength and enhancing the security of Android applications.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- INSTITUTE OF INFORMATION ENGINEERING CHINESE ACADEMY OF SCIENCES
- Filing Date
- 2022-11-07
- Publication Date
- 2026-05-19
AI Technical Summary
In existing technologies, even after Android applications are protected by code virtualization, reverse engineers can still obtain the source code by reverse analyzing the .so file, exposing the security vulnerabilities of Android applications and failing to effectively increase the time and effort required for reverse analysis.
By receiving a custom interpreter file, selecting protected functions, constructing native methods and Java native interface functions, extracting instructions for metadata collection, code reordering and offset correction, generating virtual code, saving it in a resource file, compiling it into the application package, and then interpreting and executing it using a dynamic instruction reorganization algorithm and a custom interpreter.
It enhances the instruction-level protection of Android applications, making it impossible for reverse engineers to obtain effective semantics, thus improving application security.
Smart Images

Figure CN115756480B_ABST
Abstract
Description
Technical Field
[0001] This invention relates to the field of Android data processing technology, and in particular to an Android application hardening method, system, and device. Background Technology
[0002] Currently, many Android application hardening techniques rely on mature technologies such as dynamic loading, encryption, and anti-debugging. This means that reverse engineers are also familiar with these mature technologies and can develop countermeasures through reverse engineering to crack them. Code obfuscation makes reverse engineering more difficult. Common types of code obfuscation include data obfuscation, control flow obfuscation, and code virtualization. Data obfuscation focuses on string encryption and identifier renaming. Since strings and identifiers in a program often imply specific and easily understood meanings, scanning engines can exploit this principle to understand the code. To avoid this, application package obfuscation tools replace meaningful strings and identifiers with meaningless ones. Control flow obfuscation hides the original application's control flow graph, preventing static analysis by making the application's control flow graph appear more complex. A representative method called control flow flattening uses switch structures instead of easily identifiable loops and conditional jumps to transfer control flow, thus avoiding static and dynamic analysis. Code virtualization is a typical code obfuscation method that converts the executable file (DEX) bytecode into an intermediate representation, forcing reverse engineers to switch from a familiar instruction set to an unfamiliar custom virtual code set, hoping to increase the time and effort required for reverse engineering.
[0003] In existing technologies, such as the Android VMP protection implementation method and system disclosed in CN113127004A, VMP protection for an app can be implemented at the beginning of the app's lifecycle. This technical solution copies the codeItem of the Java function A to be protected to a cpp file. Function A and an interpreter function are defined in the cpp file. The interpreter function is called within function A. Within the interpreter function, the byte array of codeItem is converted into the codeItem defined in the cpp file. Then, a virtual register is defined, and the instructions in the codeItem are retrieved line by line. The application package is then compiled using a compiler, thus achieving VMP protection for the Android application.
[0004] However, while the existing technologies described above achieve code virtualization protection, although the function instructions cannot be found in the executable file, the dexcode is still loaded into memory when the Android application runs the protected function. Furthermore, by copying the definitions from codeItem to the cpp file and defining a .so file for loading, the source code is essentially stored in the .so file in a different form, allowing the source code to be obtained through reverse engineering of the .so file. Reverse engineers can obtain valid semantics, exposing security vulnerabilities in Android applications without significantly increasing their time and effort in reverse engineering. Summary of the Invention
[0005] This invention provides an Android application hardening method, system, and device to address the problem that reverse engineers can quickly obtain the effective semantics of hardened Android applications, thus exposing the security vulnerabilities of Android applications.
[0006] This invention provides an Android application hardening method, comprising:
[0007] Receives custom interpreter files generated by users from interpreter files in the Dalvik virtual machine source code;
[0008] Select several protected functions from the executable file;
[0009] The protected functions are sequentially constructed into native methods, and corresponding Java native interface functions are sequentially generated.
[0010] Extract all instructions of the protected function from each native method;
[0011] The metadata of all instructions of the protected function are collected, the code is reordered, and the offset is corrected in sequence to obtain virtual code that can be interpreted and executed in a custom interpreter through Java native interface functions;
[0012] Save the virtual code in a resource file;
[0013] The custom interpreter file and resource files containing virtual code are encrypted and then compiled into the application package file to obtain the hardened application package file.
[0014] Furthermore, the specific selection criteria for selecting several protected functions from the executable file include:
[0015] Select functions that are sensitive application interfaces when called in the executable file, randomly select 10% of the functions in the executable file, or specify functions as protected functions.
[0016] Furthermore, the metadata collection steps include:
[0017] All instructions of the protected function are used as original instructions, and a random opcode of a random sequence of instructions from 0 to 255 is generated. The opcode of each original instruction is extracted and the instruction offset value pc is obtained.
[0018] The opcode of each original instruction is replaced with a random opcode to obtain intermediate instructions;
[0019] If the intermediate instruction is an unconditional jump instruction goto or goto / 16, then the intermediate instruction is expanded to an unconditional jump instruction goto / 32.
[0020] Record the order of this intermediate instruction among all the replaced intermediate instructions and the total number of words of the extension brought about by the unconditional jump instruction goto;
[0021] The instruction offset value pc, the total number of words, the order of this intermediate instruction among all the replaced intermediate instructions, and this intermediate instruction are combined sequentially to construct a new structure. The new structure is stored in the dictionary with the instruction offset value pc as the key. After all the original instructions have formed a new structure and been stored in the dictionary, the metadata collection is realized.
[0022] Furthermore, the code reordering step includes:
[0023] The intermediate instruction is divided into a byte starting with the opcode and the remaining bytes. After replacing and deconstructing the opcode, the two bytes led by the opcode are moved to the end of the intermediate instruction. Two bytes are added to the beginning of the intermediate instruction. The low-order byte indicates the position of the opcode, and the high-order byte is filled with a random number to achieve code disorder.
[0024] Furthermore, the step of performing the offset correction process includes:
[0025] If the address calculated from the original offset of the extended intermediate instruction is not the address of the target instruction, the operand part of the intermediate instruction will be offset corrected.
[0026] Furthermore, the instructions for correcting offsets include unconditional jump instructions: including goto and goto / 16, conditional jump instructions: including if-test, exception instructions: including try-catch, and pseudo-instructions: including packed-switch, sparsed-switch, and fill-array-data.
[0027] Furthermore, the step of receiving a custom interpreter file generated by the user from the interpreter file in the Dalvik virtual machine source code includes:
[0028] Receive user initialization processing of the interpreter file in the Dalvik virtual machine source code;
[0029] The dynamic instruction reorganization algorithm used to execute the virtual code is added to the initialized interpreter to generate a custom interpreter file.
[0030] Furthermore, the steps of the dynamic instruction reassembly algorithm for executing virtual code include:
[0031] The program counter pointer points to the starting address of the virtual code;
[0032] Based on the starting address, read the first two bytes of the virtual code to obtain the position of the virtual opcode;
[0033] Based on the position of the virtual opcode, obtain the operands and determine the handler that interprets and executes the virtual code.
[0034] This invention also provides an Android application hardening system, comprising:
[0035] Preprocessing module: Used to receive the original application package file, preprocess it, construct each protected function selected in the application package file into a native method, and generate a Java native interface function corresponding to the native method;
[0036] Instruction virtualization module: used to collect metadata, shuffle code and correct offsets for instructions extracted by the local method constructed by the preprocessing module, form virtual code, and encrypt and save the virtual code as a resource file;
[0037] Custom interpreter module: interprets virtual code using a dynamic instruction reassembly algorithm in a custom interpreter file and distributes the virtual code to the handler for execution; and
[0038] The repackaging module is used to repackage resource files and custom interpreter files into a single application package file and sign the newly generated application package.
[0039] The present invention also provides an electronic device, including a memory, a processor, and a computer program stored in the memory and executable on the processor, wherein the processor executes the program to implement any of the above-described Android application hardening methods.
[0040] This invention provides an Android application hardening method that collects metadata, reorders code, and corrects offsets from instructions extracted by protected functions in the executable file to obtain virtual code that can be interpreted and executed by a custom interpreter through Java native interface functions. When the virtual instructions are loaded into memory, reverse engineers cannot obtain effective semantics, thereby improving the protection strength of Android application instructions.
[0041] Meanwhile, the custom interpreter file containing the dynamic instruction reassembly algorithm alters the original Dalvik instruction structure. By re-encrypting the key of the custom interpreter and storing the key in the resource file, it is difficult for reverse engineers to obtain the entry point of the custom interpreter, thereby further improving the protection strength of Android application instructions. Attached Figure Description
[0042] To more clearly illustrate the technical solutions in this invention or the prior art, the drawings used in the description of the embodiments or the prior art will be briefly introduced below. Obviously, the drawings described below are some embodiments of this invention. For those skilled in the art, other drawings can be obtained from these drawings without creative effort.
[0043] Figure 1 This is a flowchart of an Android application hardening method provided by the present invention;
[0044] Figure 2 This is a flowchart illustrating an Android application hardening method provided by the present invention;
[0045] Figure 3 This is a schematic diagram of the process for collecting metadata in an Android application hardening method provided by the present invention;
[0046] Figure 4 This is a flowchart illustrating the execution of virtual code via a dynamic instruction reorganization algorithm in an Android application hardening method provided by this invention.
[0047] Figure 5 This is a structural block diagram of an Android application hardening system provided by the invention.
[0048] Figure label:
[0049] 110: Preprocessing module; 120: Instruction virtualization module; 130: Custom interpreter module; 140: Repackaging module. Detailed Implementation
[0050] To make the objectives, technical solutions, and advantages of this invention clearer, the technical solutions of this invention will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some, not all, of the embodiments of this invention. All other embodiments obtained by those skilled in the art based on the embodiments of this invention without creative effort are within the scope of protection of this invention.
[0051] The following is combined with Figures 1-4 The present invention describes an Android application hardening method, comprising the following steps:
[0052] Step S1: Before hardening, receive the user's custom interpreter file generated from the interpreter file in the Dalvik virtual machine source code. Specific steps include:
[0053] The interpreter file in the Dalvik virtual machine source code is initialized, and the dynamic instruction reorganization algorithm is added to the initialized interpreter to generate a custom interpreter file.
[0054] Step S2: During hardening, select several protected functions from the executable files (Dalvik VM executes, DEX) in the Android application package (APK) file.
[0055] Specifically, the selection scheme for choosing several protected functions from the executable file is as follows:
[0056] (1) Select functions in the executable file that call sensitive application program interfaces (APIs). For example, if function A calls sendTextMessage, and sendTextMessage is a sensitive API, then function A is the function to be protected.
[0057] (2) Randomly select 10% of the functions from the executable file.
[0058] (3) Designate a function as the protected function. For example, add the annotation @Dynvmp to the definition of function A to indicate that this function is to be protected.
[0059] By selecting a subset of protected functions from all functions in the executable file, the enhanced app's operational efficiency is ensured. Simultaneously, it makes it difficult for reverse engineers to access the entry point of a custom interpreter, thereby increasing the instruction-level protection strength of the Android application.
[0060] Step S3: Construct several protected functions sequentially into native methods and generate Java Native Interface (JNI) functions. These native Java methods can then be routed to a custom interpreter for execution via the JNI function. This is because subsequent instruction virtualization operations convert the instructions of these methods into virtual instructions, which cannot be interpreted and executed by the Dalvik interpreter. Instead, they need to be routed to a custom interpreter via the JNI function to be correctly interpreted and executed.
[0061] Step S4: Extract all instructions of the protected function from each native method.
[0062] Step S5: Collect metadata, reorder code, and correct offsets for all instructions of the protected function in sequence to obtain virtual code that can be interpreted and executed in a custom interpreter through Java native interface functions.
[0063] Specifically, the steps involved in metadata collection include:
[0064] All instructions of the protected function are treated as raw instructions, and a random opcode vm_opcode of a random sequence of instructions between 0 and 255 is generated. The opcode rawOpcode of each raw instruction is extracted and the instruction offset value pc is obtained. The instruction offset value pc refers to the offset of the current instruction in the instruction stream.
[0065] The opcode of each original instruction is replaced with a random opcode to obtain the intermediate instruction tmpIns. This replaces rawOpcode with a value from vm_opcode, which cannot be used in subsequent opcode random permutations. The order of this intermediate instruction among all replaced intermediate instructions is recorded as its index, and the total number of words extended due to the goto instruction (each word equals 2 bytes) is used as the extend value; all other values are set to 0 by default.
[0066] If the intermediate instruction is a goto instruction or a goto / 16 instruction, then the intermediate instruction is expanded to a goto / 32 instruction;
[0067] The instruction offset value pc, the total number of words, the order of this intermediate instruction among all the replaced intermediate instructions, and this intermediate instruction are combined in sequence to construct a new structure codeInfo(pc+extend,index,tmpIns). The new structure is stored in the dictionary with the instruction offset value pc as the key. After all the original instructions have formed the new structure and been stored in the dictionary, the metadata collection is realized.
[0068] Virtual code is constructed by collecting metadata, reordering code, and correcting offsets for all instructions in the protected functions. When the virtual instructions are loaded into memory, reverse engineers cannot obtain valid semantics, thus increasing the protection strength at the instruction level for Android applications.
[0069] Step S6: After processing all instructions extracted from all functions to be protected, the resulting virtual code is sequentially saved in the resource file. For example, after processing all instructions in all native methods constructed from randomly selected 10% of the functions in the executable file, the resulting virtual code is saved in the resource file.
[0070] Step S7: Encrypt the custom interpreter file and the resource file containing virtual code, then compile them into the application package file to obtain the hardened application package file.
[0071] This invention modifies the original Dalvik instruction structure by using a custom interpreter file containing a dynamic instruction reconfiguration algorithm. Furthermore, the key to the custom interpreter is re-encrypted and stored in a resource file, making it difficult for reverse engineers to access the custom interpreter's entry point, thereby enhancing the instruction-level protection strength of Android applications.
[0072] Meanwhile, by collecting metadata, reordering code, and correcting offsets of the instructions extracted by the protected functions in the executable file, virtual code that can be interpreted and executed by a custom interpreter via JNI functions is obtained. When the virtual instructions are loaded into memory, reverse engineers cannot obtain effective semantics, thereby further improving the protection strength at the instruction level of Android applications.
[0073] To further enhance the protection at the instruction level for Android applications, the code reordering process includes:
[0074] The intermediate instruction tmpIns is divided into a byte 0801 starting with the opcode and the remaining bytes 0x1500. After replacing and deconstructing the opcode, the two bytes leading to the opcode are moved to the end of the intermediate instruction. Two bytes are added to the beginning of the intermediate instruction, with the low byte indicating the position of the opcode and the high byte filled with a random number, thus achieving code reordering.
[0075] Specifically, taking the instruction `move-object / from16 v1,v21` as an example, its corresponding bytecode is 0x08011500. After opcode 08 is replaced and destructured, it is broken down into 0xc301 and 0x1500. The two bytes leading from the opcode are moved to the end of the instruction at 1500c301. Finally, two bytes are added to the beginning of the instruction; the low-order byte indicates the opcode position, and the high-order byte is filled with a random number. The final form of 0x08011500 is 0xb7021500c301.
[0076] Meanwhile, the steps for correcting the offset include:
[0077] If the address calculated from the original offset of the expanded instruction is not the address of the target instruction, the operand part of the instruction will be offset-corrected.
[0078] In this embodiment, the instructions for correcting offsets include unconditional jump instructions: including goto and goto / 16; conditional jump instructions: including if-test; exception instructions: including try-catch; and pseudo-instructions: including packed-switch, sparsed-switch, and fill-array-data.
[0079] The execution steps of the dynamic instruction reconfiguration algorithm for executing virtual code include:
[0080] Step 1: Point the program counter pointer to the starting address of the virtual code.
[0081] Step 2: Based on the starting address, read the first byte of the virtual code to obtain the position of the virtual opcode.
[0082] Step 3: Based on the position of the virtual opcode, obtain the operands and determine the handler that interprets and executes the virtual code. For example, if the virtual opcode 0x1a corresponds to the real opcode 0x90, representing an add-int instruction, then the instruction will be executed by the handler that processes this type of instruction.
[0083] This invention achieves high-strength protection at the instruction level based on the disorder and dynamic recovery of virtual code, preventing reverse engineers from using existing knowledge to reverse engineer Android applications.
[0084] The Android application reinforcement system provided by this invention is described below. The Android application reinforcement system described below can be referred to in correspondence with the Android application reinforcement method described above.
[0085] On the other hand, please refer to the following: Figure 4 The present invention also provides an Android application hardening system, comprising:
[0086] Preprocessing module 110: This module receives the original application package file, preprocesses it, constructs each protected function selected from the application package file into a native method, and generates a Java native interface function corresponding to the native method.
[0087] Instruction virtualization module 120: Used to collect metadata, shuffle code and correct offsets for instructions extracted by the native method constructed by preprocessing module 110, form virtual code, and encrypt and save the virtual code as a resource file.
[0088] Custom interpreter module 130: interprets virtual code using a dynamic instruction reorganization algorithm in a custom interpreter file and distributes the virtual code to a handler for execution.
[0089] Repackaging module 140: Used to repackage resource files and custom interpreter files into an application package file and sign the newly generated application package.
[0090] The preprocessing module preprocesses the original application package file to construct native methods and generate corresponding Java native interface functions. The instruction virtualization module collects metadata, reorders code, and corrects offsets to construct virtual code. A custom interpreter module interprets and executes the virtual code. The repackaging module repackages the application package file, altering the original Dalvik instruction format. When virtual instructions are loaded into memory, reverse engineers cannot obtain valid semantics, thus enhancing the protection strength at the instruction level of Android applications.
[0091] The device embodiments described above are merely illustrative. The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the modules can be selected to achieve the purpose of this embodiment according to actual needs. Those skilled in the art can understand and implement this without any creative effort.
[0092] Through the above description of the embodiments, those skilled in the art can clearly understand that each embodiment can be implemented by means of software plus necessary general-purpose hardware platforms, and of course, it can also be implemented by hardware. Based on this understanding, the above technical solutions, in essence or the part that contributes to the prior art, can be embodied in the form of a software product. This computer software product can be stored in a computer-readable storage medium, such as ROM / RAM, magnetic disk, optical disk, etc., and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute the methods described in the various embodiments or some parts of the embodiments.
[0093] Finally, it should be noted that the above embodiments are only used to illustrate the technical solutions of the present invention, and not to limit them; although the present invention has been described in detail with reference to the foregoing embodiments, those skilled in the art should understand that modifications can still be made to the technical solutions described in the foregoing embodiments, or equivalent substitutions can be made to some of the technical features; and these modifications or substitutions do not cause the essence of the corresponding technical solutions to deviate from the spirit and scope of the technical solutions of the embodiments of the present invention.
Claims
1. A method for hardening Android applications, characterized in that, include: Receives custom interpreter files generated by users based on interpreter files in the Dalvik virtual machine source code; Select several protected functions from the executable file; The protected functions are sequentially constructed into native methods, and corresponding Java native interface functions are sequentially generated for each native method. Extract all instructions of the protected function from each native method; The metadata of all instructions of the protected function are collected, the code is reordered, and the offset is corrected in sequence to obtain virtual code that can be interpreted and executed in a custom interpreter through Java native interface functions; Save the virtual code in a resource file; The custom interpreter file and resource files containing virtual code are encrypted and then compiled into the application package file to obtain the hardened application package file; The steps for collecting the metadata include: All instructions of the protected function are used as original instructions, and a random opcode of a random sequence of instructions from 0 to 255 is generated. The opcode of each original instruction is extracted and the instruction offset value pc is obtained. The opcode of each original instruction is replaced with a random opcode to obtain intermediate instructions; If the intermediate instruction is an unconditional jump instruction goto or goto / 16, then the intermediate instruction is expanded to an unconditional jump instruction goto / 32. Record the order of this intermediate instruction among all the replaced intermediate instructions and the total number of words of the extension brought about by the unconditional jump instruction goto; The instruction offset value pc, the total number of words, the order of this intermediate instruction among all the replaced intermediate instructions, and this intermediate instruction are combined in sequence to construct a new structure. The new structure is stored in the dictionary with the instruction offset value pc as the key. After all the original instructions have formed a new structure and been stored in the dictionary, the collection of metadata is realized. The steps of code reordering include: The intermediate instruction is divided into bytes starting with the opcode and the remaining bytes. After replacing and deconstructing the opcode, the two bytes led by the opcode are moved to the end of the intermediate instruction. Two bytes are added to the beginning of the intermediate instruction. The low-order byte indicates the position of the opcode, and the high-order byte is filled with a random number to achieve code disorder. The steps for performing offset correction include: If the address calculated from the original offset of the extended intermediate instruction is not the address of the target instruction, the operand part of the intermediate instruction is offset-corrected.
2. The Android application hardening method according to claim 1, characterized in that, The specific selection criteria for selecting several protected functions from the executable file include: Select functions in the executable file that call sensitive application interfaces, randomly select 10% of the functions in the executable file, or specify functions as protected functions.
3. The Android application hardening method according to claim 1, characterized in that, The instructions for correcting offsets include unconditional jump instructions (goto and goto / 16), conditional jump instructions (if-test), exception instructions (try-catch), and pseudo-instructions (packed-switch, sparse-switch, and fill-array-data).
4. The Android application hardening method according to any one of claims 1 to 3, characterized in that, The receiving user's custom interpreter file generated from the interpreter file in the Dalvik virtual machine source code includes: Receive user initialization processing of the interpreter file in the Dalvik virtual machine source code; The dynamic instruction reorganization algorithm used to execute the virtual code is added to the initialized interpreter to generate a custom interpreter file.
5. The Android application hardening method according to claim 4, characterized in that, The steps of the dynamic instruction reassembly algorithm for executing virtual code include: The program counter pointer points to the starting address of the virtual code; Based on the starting address, read the first two bytes of the virtual code to obtain the position of the virtual opcode; Based on the position of the virtual opcode, obtain the operands and determine the handler that interprets and executes the virtual code.
6. An Android application hardening system, characterized in that, The Android application hardening method as described in claim 1 includes: Preprocessing module: Used to receive the original application package file, preprocess it, construct each protected function selected in the application package file into a native method, and generate a Java native interface function corresponding to the native method; Instruction virtualization module: used to collect metadata, shuffle code and correct offsets for instructions extracted by the local method constructed by the preprocessing module, form virtual code, and encrypt and save the virtual code as a resource file; Custom interpreter module: interprets virtual code using a dynamic instruction reassembly algorithm in a custom interpreter file and distributes the virtual code to the handler for execution; and The repackaging module is used to repackage resource files and custom interpreter files into a single application package file and sign the newly generated application package.
7. An electronic device comprising a memory, a processor, and a computer program stored in the memory and executable on the processor, characterized in that, When the processor executes the program, it implements the Android application hardening method as described in any one of claims 1 to 5.