Analysis methods and systems for obfuscated PASS based on LLVM
By constructing control flow graphs and state transition graphs, useless basic blocks are identified, solving the problem of poor accuracy of existing deobfuscation methods when facing complex LLVM obfuscation techniques. This enables in-depth analysis of binary programs and improves deobfuscation tools.
Patent Information
- Application Number
- CN202510265124.0
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-03-07
- Publication Date
- 2025-10-31
- Estimated Expiration
- 2045-03-07
AI Technical Summary
Existing deobfuscation methods are inaccurate when faced with complex LLVM obfuscation techniques, resulting in poor binary program analysis, especially in dealing with new or custom obfuscation strategies.
By extracting the target function from the obfuscated binary program, locating the encrypted string, constructing the control flow graph and generating the state transition graph, identifying useless basic blocks, and using pattern matching and dynamic probe techniques to determine the obfuscated logic, including the assignment sequence of decryption algorithm parameters and control variables, the control flow graph and state transition graph are optimized to identify useless basic blocks.
It enhances the ability to analyze complex obfuscation techniques, enabling a deeper understanding of how obfuscation passes work, improving the adaptability and effectiveness of deobfuscation tools, providing a clear view of binary program structure and behavior, and supporting the development of more efficient and flexible deobfuscation tools.
Smart Images

Figure CN119783065B_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of software protection technology, and in particular to an analysis method and system for obfuscated PASS based on LLVM. Background Technology
[0002] In the field of software protection, obfuscation techniques are widely used to protect binary programs from reverse engineering and unauthorized access. This protection has been particularly enhanced with the application of obfuscation passes in compilers such as Low Level Virtual Machines (LLVM). These obfuscation passes can perform various transformations on the original binary program, including string encryption, control flow flattening, and fake control flow insertion, making decompilation and understanding extremely difficult. However, this protection also presents challenges for legitimate security research and software maintenance, as even legitimate users may need to understand and analyze these highly obfuscated binary programs.
[0003] In existing technologies, deobfuscation methods are commonly used to understand highly obfuscated binary programs. Deobfuscation methods mainly rely on directly analyzing the obfuscated binary code and attempting to restore its original logic. There are three main approaches: (1) Static analysis: Identifying and decrypting strings and restoring control flow by analyzing the structure and content of the binary file. (2) Dynamic analysis: Executing the binary program and monitoring its runtime behavior to collect information to help restore the original binary program. (3) Pattern-based deobfuscation: Using known obfuscation patterns, designing specialized algorithms to automatically remove the obfuscation effect. Although these methods can mitigate the impact of obfuscation to some extent, they each have their limitations: For complex obfuscation techniques, especially those involving high-level control flow transformations or the insertion of a large amount of useless code, static analysis alone is insufficient to fully understand the obfuscated code structure. Although dynamic analysis can provide more accurate information, it usually only covers a limited number of execution paths and may be affected by environmental factors. Pattern-based deobfuscation relies heavily on predefined obfuscation pattern libraries and is ineffective when faced with new or custom obfuscation strategies.
[0004] Therefore, most existing deobfuscation methods focus on eliminating the obfuscation result, making them often ineffective against new obfuscation techniques. Obfuscation techniques are constantly evolving, and existing deobfuscation methods may immediately become ineffective once a new or updated version emerges. Thus, while current deobfuscation techniques can help recover parts of the original logic of obfuscated code in some cases, they still face significant challenges in combating modern obfuscation techniques due to the aforementioned limitations. Summary of the Invention
[0005] This application provides an analysis method and system based on obfuscation PASS in LLVM to solve the problem of poor binary program analysis results caused by poor deobfuscation accuracy in the prior art.
[0006] In a first aspect, embodiments of this application provide an analysis method based on obfuscated PASS in LLVM, comprising: extracting a target function from an obfuscated binary program, locating the position of an encrypted string in the target function, and determining decryption logic based on the position of the encrypted string, wherein the decryption logic includes decryption algorithm parameters;
[0007] The target expression in the target function is found, and the expression logic is identified by pattern matching. Based on the decryption logic and the expression logic, the string encryption algorithm parameters are determined. The target expression includes a combination of arithmetic operations, logical operations, and bitwise operations.
[0008] A control flow graph is constructed based on the expression logic, and the control variables in the control flow graph are identified. Based on the assignment sequence of the control variables, a state transition graph of the control variables is generated.
[0009] Identify the identifiers of useless basic blocks in the target function based on the state transition diagram. Based on the string encryption algorithm parameters and the identifiers of the useless basic blocks, determine the obfuscation implementation logic of the obfuscated binary program. The useless basic blocks are unreachable or invalid code blocks inserted by the obfuscation PASS in the underlying virtual machine LLVM during the obfuscation process of the binary program.
[0010] Optionally, the expression logic includes jump relationships between instructions within a basic block, jump relationships between basic blocks, strongly connected components, and branch structures. The step of constructing a control flow graph based on the expression logic, identifying control variables in the control flow graph, and generating a state transition graph for the control variables based on the assignment sequence of the control variables includes:
[0011] Based on the first instruction sequence in the target expression, the first instruction sequence is divided into multiple basic blocks according to a preset partitioning rule. The number of basic blocks is counted, and the number of instructions contained in each basic block is taken as the size of the basic block.
[0012] Within each basic block, jump instructions between instructions are searched to determine the jump relationship between the instructions. All basic blocks are traversed to find jump instructions from one basic block to another to determine the jump relationship between the basic blocks.
[0013] Based on the number of basic blocks, the size of the basic blocks, the jump relationships between instructions, and the jump relationships between basic blocks, an initial structure diagram is constructed;
[0014] Identify the strongly connected components in the initial structural graph, optimize the strongly connected components to obtain an intermediate structural graph, assign a corresponding weight to each edge in the intermediate structural graph to obtain a weighted intermediate structural graph, wherein the strongly connected components are a loop structure composed of mutually reachable basic blocks.
[0015] Identify the branch structure in the weighted intermediate structure graph, and adjust the weight of the corresponding edge according to the execution frequency and path complexity of different branches in the branch structure to obtain the control flow graph;
[0016] By counting cross-references and sorting addresses, the main distribution block with the most cross-references in the control flow graph and whose address is below a preset threshold is determined. The indirect jump instructions or indirect call instructions in the main distribution block are parsed, and the operands of the registers in the indirect jump instructions or indirect call instructions in the main distribution block are extracted to identify the control variables.
[0017] By tracing the assignment operation of the control variable in reverse, the initial dispatch block that first assigns a value to the control variable is located;
[0018] Based on the initial distribution block and the assignment sequence of the control variables, dynamically track all instruction chains that modify the control variables, and record the calculation logic and modification path of the control variable values;
[0019] Based on the computational logic and the modification path, a state transition graph is generated with basic blocks as nodes and control variable states as edges. The state transition graph contains the mapping relationship between changes in the values of control variables and branch jumps.
[0020] Optionally, the step of identifying strongly connected components in the initial structural graph, optimizing the strongly connected components to obtain an intermediate structural graph, and assigning a corresponding weight to each edge in the intermediate structural graph to obtain a weighted intermediate structural graph includes:
[0021] The initial structure graph is divided into multiple subgraphs to decompose the depth-first search process of the Tarjan algorithm into multiple subtasks, and multi-threading is used to identify strongly connected components in all subgraphs.
[0022] Perform a cyclic reduction operation on each of the strongly connected components, and generate the intermediate structure graph after performing the cyclic reduction operation on all the strongly connected components.
[0023] For each edge in the intermediate structure graph, the values of three dimensions—the probability of a jump, the length of the jump path, and the degree of impact on jump performance—are fused to obtain the edge weight, thus producing a weighted intermediate structure graph.
[0024] Optionally, the cyclic reduction operation includes:
[0025] If there is a strongly connected component with a single cyclic entry block, then the strongly connected component with a single cyclic entry block is compressed into a single virtual node, and the virtual node is associated with the single cyclic entry block.
[0026] Alternatively, if there are strongly connected components with multiple cyclic entry blocks, then one of the cyclic entry blocks is selected as the main loop head node based on the dominator tree algorithm, and the remaining cyclic entry blocks are deleted.
[0027] Optionally, adjusting the weights of corresponding edges based on the execution frequency and path complexity of different branches within the branch structure to obtain the control flow graph includes:
[0028] Based on the static analysis results of the branch structure in the initial structure diagram, the actual number of executions of each branch in the branch structure is obtained by dynamic instrumentation, and the execution frequency of each branch is calculated.
[0029] For each branch's path, the path complexity is determined based on the number of basic blocks and the total number of instructions in the branch, the maximum depth of the data dependency chain in the branch, and the nesting level of the strongly connected components in the branch.
[0030] The execution frequency and the path complexity are input into a preset weight calculation model to generate a fused weight value;
[0031] The weights of the corresponding edges in the weighted intermediate structure graph are adjusted using the fusion weight values to obtain the control flow graph.
[0032] Optionally, the identifiers of useless basic blocks in the objective function are identified based on the state transition diagram, including:
[0033] From the second instruction sequence consisting of all valid basic blocks in the objective function, remove the valid instructions related to the calculation of the string encryption algorithm parameters and control variables to obtain the remaining instruction sequence;
[0034] A reachability analysis is performed on the control flow graph to obtain the basic blocks containing the remaining instruction sequence, and basic blocks that meet the following conditions are selected: there is no complete path from the function entry to the basic block in the control flow graph, and the jump conditions of all predecessor basic blocks are false in the state transition graph;
[0035] Dynamic probes are injected into the selected basic blocks to monitor the actual execution coverage of the selected basic blocks. If the actual execution coverage is lower than a preset coverage threshold, the basic blocks whose actual execution coverage is lower than the preset coverage threshold are identified as useless basic blocks. The preset coverage threshold is dynamically adjusted based on the obfuscation strength defined in the string encryption algorithm parameters.
[0036] Optionally, dynamic probes are injected into the selected basic blocks to monitor the actual execution coverage of the selected basic blocks, including:
[0037] A first probe is inserted before the entry instruction of the selected basic block to record the number of entries; a second probe is inserted before the exit jump instruction of the selected basic block to record the number of exits.
[0038] Associate the number of entries and the number of exits with the corresponding control variable states in the state transition diagram, and record the following information: the control variable value when the basic block is executed, and jump to the address of the predecessor dispatch block of the basic block;
[0039] The actual execution coverage is calculated based on the ratio of the number of entries to the total number of function calls, whereby the total number of function calls is obtained by statistically analyzing the number of entries and the number of exits.
[0040] Secondly, embodiments of this application provide an analysis system based on obfuscated PASS in LLVM, including:
[0041] An extraction and positioning module is used to extract a target function from an obfuscated binary program, locate the position of an encrypted string in the target function, and determine decryption logic based on the position of the encrypted string. The decryption logic includes decryption algorithm parameters.
[0042] The search and identification module is used to search for the target expression in the target function, identify the expression logic through pattern matching, and determine the string encryption algorithm parameters based on the decryption logic and the expression logic. The target expression includes a combination of arithmetic operations, logical operations and bitwise operations.
[0043] A recognition module is constructed to build a control flow graph based on the expression logic, identify the control variables in the control flow graph, and generate a state transition graph of the control variables based on the assignment sequence of the control variables.
[0044] The identification and determination module is used to identify the identifiers of useless basic blocks in the target function according to the state transition diagram, and to determine the obfuscation implementation logic of the obfuscated binary program based on the string encryption algorithm parameters and the identifiers of the useless basic blocks. The useless basic blocks are unreachable or invalid code blocks inserted by the obfuscation PASS in the underlying virtual machine LLVM during the obfuscation process of the binary program.
[0045] Thirdly, embodiments of this application provide a computing device, including a processing component and a storage component; the storage component stores one or more computer instructions; the one or more computer instructions are to be invoked and executed by the processing component to implement an analysis method based on obfuscated PASS in LLVM as described in any of the first aspects.
[0046] Fourthly, embodiments of this application provide a computer storage medium storing a computer program, which, when executed by a computer, implements an analysis method for obfuscated PASS based on LLVM as described in any of the first aspects.
[0047] This application provides an analysis method based on the obfuscation PASS in LLVM, comprising: extracting the target function from the obfuscated binary program, locating the position of the encrypted string in the target function, determining the decryption logic based on the position of the encrypted string, the decryption logic including decryption algorithm parameters; searching for the target expression in the target function, identifying the expression logic through pattern matching, determining the string encryption algorithm parameters based on the decryption logic and the expression logic, the target expression including a combination of arithmetic operations, logical operations, and bitwise operations; constructing a control flow graph based on the expression logic, identifying the control variables in the control flow graph, generating a state transition graph of the control variables based on the assignment sequence of the control variables; identifying the identifiers of useless basic blocks in the target function based on the state transition graph, determining the obfuscation implementation logic of the obfuscated binary program based on the string encryption algorithm parameters and the identifiers of useless basic blocks, the useless basic blocks being unreachable or invalid code blocks inserted during the obfuscation process of the binary program by the obfuscation PASS in the underlying virtual machine LLVM.
[0048] This application's embodiments determine the decryption logic by extracting the target function from the obfuscated binary program and locating the position of the encrypted string. This method further analyzes the encryption algorithm parameters, enabling analysts to gain a deeper understanding of the specific working principle of the obfuscation pass, including the specific encryption algorithms and parameters used. Pattern matching is used to identify the target expression logic, including combinations of arithmetic, logical, and bitwise operations within the target function, ensuring effective operation even under complex obfuscation conditions. A control flow graph is constructed based on the expression logic, and the control variables and their assignment sequences are identified to generate a state transition diagram. This helps reveal the execution flow of the binary program, especially paths that become difficult to trace after obfuscation, thus providing a clear view of the binary program's structure and behavior. The state transition diagram identifies useless basic block identifiers in the target function. Based on this information, a more comprehensive understanding of the specific obfuscation strategies and techniques employed by the obfuscation pass can be obtained, including how the code execution flow is disrupted and how interfering code is inserted. This method focuses on understanding and analyzing the obfuscation mechanism itself rather than merely removing the obfuscation result, thus better addressing new or custom obfuscation passes. This analytical method, "inferring the essence from the phenomenon," improves the effectiveness and adaptability of deobfuscation tools in the face of constantly evolving obfuscation techniques. In summary, this technical solution not only helps analysts gain a deeper understanding of the working principles of obfuscation passes, but also supports the development of more efficient and flexible deobfuscation tools, ultimately enhancing the analytical and security assessment capabilities of software protection measures. Furthermore, the embodiments of this application enhance the analytical capabilities of obfuscated binary programs. By analyzing and optimizing control flow graphs and state transition graphs in detail, it can accurately identify and handle complex loop structures, branching logic, and changes in control variables. It can also dynamically track and record the assignment sequences of control variables and their modification paths, thereby gaining a deeper understanding of the specific implementation details of obfuscation techniques and providing strong support for deobfuscation. Specifically, this method accelerates the identification and optimization process of strongly connected components through multi-threading and adjusts weights based on factors such as jump probability, path length, and performance impact, effectively improving the accuracy and efficiency of constructing control flow graphs and state transition graphs.
[0049] These or other aspects of this application will become more apparent in the following description of the embodiments. Attached Figure Description
[0050] To more clearly illustrate the technical solutions in the embodiments of this application 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 application. For those skilled in the art, other drawings can be obtained based on these drawings without creative effort.
[0051] Figure 1A flowchart illustrating an analysis method for obfuscated PASS based on LLVM, provided for embodiments of this application;
[0052] Figure 2 A schematic diagram of the structure of an analysis system based on obfuscated PASS in LLVM provided in an embodiment of this application;
[0053] Figure 3 This is a schematic diagram of the structure of a computing device provided in an embodiment of this application. Detailed Implementation
[0054] To enable those skilled in the art to better understand the present application, the technical solutions in the embodiments of the present application will be clearly and completely described below with reference to the accompanying drawings.
[0055] In some of the processes described in the specification, claims, and accompanying drawings of this application, multiple operations appearing in a specific order are included. However, it should be clearly understood that these operations may not be executed in the order they appear herein, or may be executed in parallel. The operation numbers, such as 11, 12, etc., are merely used to distinguish different operations and do not themselves represent any execution order. Furthermore, these processes may include more or fewer operations, and these operations may be executed sequentially or in parallel. It should be noted that the descriptions such as "first," "second," etc., in this document are used to distinguish different messages, devices, modules, etc., and do not represent a sequential order, nor do they limit "first" and "second" to different types.
[0056] The technical solutions of the embodiments of this application will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of this application, and not all embodiments. Based on the embodiments of this application, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of this application.
[0057] Figure 1 A flowchart of an analysis method for obfuscated PASS based on LLVM provided in this application embodiment is shown below. Figure 1 As shown, the method includes:
[0058] S11. Extract the target function from the obfuscated binary program, locate the position of the encrypted string in the target function, and determine the decryption logic based on the position of the encrypted string. The decryption logic includes the decryption algorithm parameters.
[0059] The objective function determines which parts of the binary program require focused parsing and processing. The location of the encrypted string refers to the specific position of the encrypted string within the objective function after obfuscation, helping to locate the data to be decrypted. Embodiments of this application can locate the encrypted string within the objective function using static analysis or other methods. The decryption logic, including the encryption algorithm parameters and the location of the decryption function, refers to a series of rules and steps required to restore the encrypted string to a readable form, facilitating understanding and analysis.
[0060] S12. Locate the target expression in the target function, identify the expression logic through pattern matching, and determine the string encryption algorithm parameters based on the decryption logic and the expression logic. The target expression includes a combination of arithmetic operations, logical operations, and bitwise operations.
[0061] The target expression can refer to an expression that includes combinations of arithmetic, logical, and bitwise operations. It can be related to control flow or data transformation and is used to identify specific logical patterns, thereby inferring the behavior of the original binary program. The string encryption algorithm parameters are the algorithm parameters used when generating the encrypted string.
[0062] S13. Construct a control flow graph based on the expression logic, identify the control variables in the control flow graph, and generate a state transition graph of the control variables based on the assignment sequence of the control variables.
[0063] In this context, key variables are those that play a crucial role in the control flow diagram. Changes in key variables lead to changes in the execution path of the binary program. In obfuscated implementation logic analysis, they are used to track decision points and their impact during the execution of the binary program. State transition diagrams are graphical representations built upon the state changes of control variables. They demonstrate how changes in the values of control variables affect the execution flow of the binary program, providing a more intuitive display and understanding of the binary program's execution logic.
[0064] Optionally, embodiments of this application may utilize variable calculation methods to generate state transition diagrams for control variables.
[0065] S14. Identify the identifiers of useless basic blocks in the objective function based on the state transition diagram, and determine the obfuscation implementation logic of the obfuscated binary program based on the string encryption algorithm parameters and the identifiers of useless basic blocks.
[0066] Among them, useless basic blocks are unreachable or invalid code blocks inserted during the obfuscation process of the binary program by the obfuscation PASS in the underlying virtual machine LLVM. Useless basic blocks do not participate in the execution of actual program logic. By identifying useless basic blocks, unnecessary interference code can be identified and eliminated, improving analysis efficiency.
[0067] In step S14, this embodiment of the application achieves reverse derivation of the obfuscation implementation logic through joint analysis of the state transition diagram and string encryption algorithm parameters.
[0068] By executing steps S11-S14, this embodiment extracts the target function from the obfuscated binary program and locates the position of the encrypted string to determine the decryption logic. This allows analysts to gain a deeper understanding of the specific working principle of the obfuscation pass, including the specific encryption algorithm and parameters used. Pattern matching is used to identify the target expression logic in the target function, ensuring effective operation even under complex obfuscation conditions. This process helps to accurately identify the specific details of the obfuscation technique application, such as the selection of encryption algorithms and parameter settings. A control flow graph is constructed based on the expression logic, and the control variables and their assignment sequences are identified to generate a state transition diagram. This helps to reveal the execution flow of the binary program, especially paths that become difficult to trace after obfuscation. This step provides a clear view of the binary program's structure and behavior. By identifying useless basic block identifiers in the target function through the state transition diagram, a more comprehensive understanding of the specific obfuscation strategies and techniques used in the obfuscation pass can be obtained, including how the code execution flow is disrupted and how interference code is inserted. This analytical method, "inferring the essence from the phenomenon," improves the effectiveness and adaptability of deobfuscation tools in the face of constantly evolving obfuscation techniques. In summary, this technical solution not only helps analysts gain a deeper understanding of how obfuscation passes work, but also supports the development of more efficient and flexible deobfuscation tools, ultimately enhancing the analytical and security assessment capabilities of software protection measures.
[0069] In some possible embodiments, the expression logic includes jump relationships between instructions within a basic block, jump relationships between basic blocks, strongly connected components, and branch structures. S13: Construct a control flow graph based on the expression logic, identify control variables in the control flow graph, and generate a state transition graph of the control variables based on the assignment sequence of the control variables, including:
[0070] Step 131: Based on the first instruction sequence in the target expression, divide the first instruction sequence into multiple basic blocks according to the preset partitioning rules, count the number of basic blocks, and use the number of instructions contained in each basic block as the size of the basic block.
[0071] The first instruction sequence refers to the initial set of consecutive instructions extracted from the objective function, without any segmentation. In binary program analysis, it serves as the foundational material for constructing basic blocks. Preset partitioning rules refer to a set of established criteria or conditions for dividing the instruction sequence into basic blocks, such as partitioning based on the position of jump instructions. In deobfuscation analysis, these rules help clarify the boundaries of each basic block, thereby providing a better understanding of the program structure.
[0072] Accordingly, step 131 decomposes the first instruction sequence into multiple basic blocks according to a preset partitioning rule and counts their number and size, which can provide structured data support for subsequent detailed analysis and help to quickly locate and understand the function and role of each basic block.
[0073] Step 132: Within each basic block, find the jump instructions between instructions to determine the jump relationship between instructions. Traverse all basic blocks and find the jump instructions from one basic block to another to determine the jump relationship between basic blocks.
[0074] Accordingly, step 132, which finds and determines the jump relationships between instructions and basic blocks, helps to clearly show the internal control flow of the program, enabling researchers to intuitively see the execution path of the program, especially in the case of complex jump logic.
[0075] Step 133: Based on the number of basic blocks, the size of basic blocks, the jump relationships between instructions, and the jump relationships between basic blocks, construct the initial structure diagram.
[0076] It should be understood that the initial structure diagram is a preliminary graphical representation built based on the number and size of basic blocks, the jump relationships between instructions, and the jump relationships between basic blocks. In obfuscated implementation logic analysis, it is used to provide a basic framework for program control flow, laying the foundation for subsequent optimization and adjustments.
[0077] Accordingly, step 133 constructs an initial structure diagram based on the collected information, providing a preliminary but comprehensive view of the control flow of the binary program, allowing analysts to examine the entire program structure from a macro perspective and prepare for further detailed analysis.
[0078] Step 134: Identify the strongly connected components in the initial structure graph, optimize the strongly connected components to obtain the intermediate structure graph, assign corresponding weights to each edge in the intermediate structure graph to obtain the weighted intermediate structure graph. The strongly connected components are a loop structure composed of mutually reachable basic blocks.
[0079] It should be understood that strongly connected components are loop structures composed of mutually reachable basic blocks, representing a path from any of these basic blocks back to the starting point via a series of edges. In binary program analysis, identifying strongly connected components helps uncover complex loop structures that may exist in binary programs, which is crucial for understanding and simplifying code. Weighted intermediate structure graphs are based on intermediate structure graphs, assigning numerical values to each edge reflecting its importance or frequency of use. In this scenario, they are used to more accurately simulate the actual path selection preferences during program execution, facilitating the identification of critical paths and potential obfuscation strategies.
[0080] Accordingly, step 134 identifies and optimizes strongly connected components, which not only removes repetitive or unnecessary loop structures, but also simplifies the control flow graph, making it easier to understand and analyze, while also improving algorithm efficiency.
[0081] One possible implementation is step 134, which involves identifying strongly connected components in the initial structure graph, optimizing these components to obtain an intermediate structure graph, and assigning a weight to each edge in the intermediate structure graph to obtain a weighted intermediate structure graph.
[0082] Step a1: Divide the initial structure graph into multiple subgraphs to decompose the depth-first search process of the Tarjan algorithm into multiple subtasks, and use multi-threading to identify strongly connected components in all subgraphs.
[0083] It should be understood that Tarjan's algorithm is an algorithm used to find all strongly connected components in a directed graph in linear time. In binary program analysis, it is used to efficiently identify loop structures in the control flow graph, which may be part of obfuscation techniques, helping analysts understand the actual execution flow of the binary program. Depth-first search is an algorithm that traverses or searches a tree or graph. In this process, the branches of the tree are searched as deeply as possible. In this scenario, it is used to explore every corner of the program's control flow graph, ensuring that no potentially strongly connected components are missed, contributing to a comprehensive understanding of the binary program's logical structure. A subgraph is a graph composed of a subset of vertices and edges selected from the original graph. When dealing with complex control flow graphs, dividing the graph into multiple subgraphs facilitates parallel processing and improves computational efficiency, especially in multi-threaded environments.
[0084] Accordingly, step a1 significantly improves processing speed and efficiency, especially when dealing with large and complex control flow graphs, by dividing the initial structure graph into multiple subgraphs and applying the Tarjan algorithm in a multi-threaded manner to identify strongly connected components. This method not only accelerates the analysis process but also makes resource utilization more rational.
[0085] Step a2: Perform a cyclic reduction operation on each strongly connected component. After performing the cyclic reduction operation on all strongly connected components, an intermediate structure graph is generated.
[0086] It should be understood that loop reduction is a process of simplifying identified strongly connected components. This operation transforms complex loop structures into a more easily understood and analyzed form, helping to reveal the true logic of the program rather than its obfuscated surface structure.
[0087] Accordingly, step a2: Performing loop reduction can effectively simplify the control flow graph, especially for graphs containing complex loop structures. By compressing single-entry loops or selecting the head node of the main loop based on the dominance tree algorithm, unnecessary details can be reduced, making the graph more concise and clear, and thus making it easier to discover the core logic and control flow pattern of the program.
[0088] Specifically, the cyclic reduction operation includes:
[0089] If there is a strongly connected component with a single cyclic entry block, then the strongly connected component with a single cyclic entry block is compressed into a single virtual node, and the virtual node is associated with the single cyclic entry block.
[0090] Alternatively, if there are strongly connected components with multiple cyclic entry blocks, then one of the cyclic entry blocks is selected as the main loop head node based on the dominator tree algorithm, and the remaining cyclic entry blocks are deleted.
[0091] It should be understood that a virtual node is an abstract node introduced into the graph to represent a set of one or more actual nodes. Using virtual nodes in this embodiment helps simplify the control flow graph, making it more intuitive, especially when dealing with complex loop structures with a single entry point. The dominance tree algorithm is an algorithm used to construct a dominance tree, which displays the dominance relationships between basic blocks in a program's control flow graph. In the presence of multiple loop entries, the dominance tree algorithm can select the most suitable loop head node to optimize the clarity and accuracy of the intermediate structure graph.
[0092] Step a3: For each edge in the intermediate structure graph, the values of the three dimensions of jump probability, jump path length, and jump performance impact are fused to obtain the edge weight, so as to obtain a weighted intermediate structure graph.
[0093] It should be understood that the three dimensions of jump probability, jump path length, and jump performance impact are standards used to evaluate the importance or weight of an edge. Jump probability refers to the frequency with which the edge is actually used; jump path length reflects the distance from the starting point to the ending point; and jump performance impact considers the edge's influence on overall performance. In the analysis of obfuscation implementation logic, combining these three dimensions can help to better understand which paths are more critical and which may be designed for obfuscation.
[0094] Correspondingly, step a3, which assigns weights to each edge in the intermediate structure graph, is essentially a further refinement of the control flow graph. By combining factors such as jump probability, path length, and performance impact to determine the weights, the generated weighted intermediate structure graph can more accurately reflect the actual execution situation, helping to identify truly important execution paths. It can also more accurately locate the application position of obfuscation strategies, providing strong support for deobfuscation work.
[0095] By executing steps a1 to a3, the embodiments of this application provide a more detailed analytical perspective and enhance the depth of understanding of program behavior.
[0096] Step 135: Identify the branch structure in the weighted intermediate structure graph, and adjust the weight of the corresponding edge according to the execution frequency and path complexity of different branches in the branch structure to obtain the control flow graph.
[0097] It should be understood that a branch structure refers to the portion of the control flow graph representing different execution path choices, typically caused by conditional judgments. During analysis, evaluating the execution frequency and path complexity within the branch structure can help determine which paths are more important and which paths may be redundant paths designed for obfuscation.
[0098] Accordingly, step 135 adjusts the edge weights according to the execution frequency and path complexity of different branches within the branch structure, so that the control flow graph can more accurately reflect the actual execution situation and help identify the main execution path and secondary or obfuscated paths.
[0099] As one possible implementation, the weights of the corresponding edges are adjusted based on the execution frequency and path complexity of different branches within the branch structure to obtain the control flow graph, including:
[0100] Step b1: Based on the static analysis results of the branch structure in the initial structure diagram, obtain the actual execution count of each branch within the branch structure through dynamic instrumentation, and calculate the execution frequency of each branch. Dynamic instrumentation refers to the technique of inserting code during program execution to collect runtime information. In binary program analysis scenarios, it is used to obtain the actual execution count of each branch within the branch structure, thereby calculating the execution frequency of each branch and helping to understand which paths are more frequently used. Execution frequency refers to the number of times a specific branch or path is executed during program execution. By understanding the execution frequency, the most frequently used and least frequently used execution paths in the program can be identified, which is crucial for understanding the behavior of binary programs.
[0101] Accordingly, step b1, through a combination of static analysis and dynamic instrumentation, not only obtains the theoretical branching structure but also real-world runtime data, including the actual number of times each branch is executed and its execution frequency. This method provides more accurate information than pure static analysis, helping to identify truly important execution paths rather than relying solely on the code structure itself.
[0102] Step b2: For each branch's path, determine the path complexity based on the number of basic blocks and the total number of instructions in the branch, the maximum depth of the data dependency chain in the branch, and the nesting level of the strongly connected components in the branch.
[0103] It should be understood that path complexity is a metric that measures the complexity of a path. It is calculated based on multiple factors, such as the number of basic blocks, the total number of instructions, the maximum depth of data dependency chains, and the nesting level of strongly connected components. High path complexity means that the path may be more difficult to understand and trace, and may also be more likely to become a target of obfuscation. The maximum depth of a data dependency chain refers to the number of operation steps required in a path from one operation to its final dependent data source. A higher depth of data dependency chains may indicate a more complex path, increasing the difficulty of understanding and reverse engineering.
[0104] Accordingly, step b2, which determines path complexity, considers multiple factors (number of basic blocks, total number of instructions, depth of data dependency chains, and nesting level of strongly connected components), making path complexity assessment more comprehensive and accurate. Compared to focusing solely on execution frequency, path complexity can reveal paths that, while not frequently executed, are structurally complex; these paths are often key application areas for obfuscation techniques.
[0105] Step b3: Input the execution frequency and path complexity into the preset weight calculation model to generate the fused weight value. The weight calculation model is a preset mathematical model used to combine execution frequency and path complexity to generate the fused weight value. This model helps quantify the importance of each edge, making the control flow graph more reflective of actual execution and facilitating analysts' identification of critical paths and potential obfuscation strategies.
[0106] Accordingly, step b3 uses a pre-defined weight calculation model to combine execution frequency and path complexity to generate a fused weight value. This method comprehensively considers multiple factors and provides a more scientific and reasonable way to evaluate the importance of each edge in the control flow graph. Compared to simple execution frequency or path complexity, the fused weight value can better reflect the actual impact of edges in actual operation.
[0107] Step b4: Adjust the weights of the corresponding edges in the weighted intermediate structure graph using the fusion weight values to obtain the control flow graph.
[0108] Accordingly, step b4 adjusts the weights of the corresponding edges in the weighted intermediate structure graph and optimizes the control flow graph based on the fused weight values. This process not only improves the accuracy of the control flow graph but also makes it better reflect the actual operation of the program.
[0109] By executing steps b1 to b4, this embodiment of the application optimizes the control flow graph by comprehensively considering various factors, thereby more effectively supporting subsequent deobfuscation work, such as identifying critical paths and discovering the application location of obfuscation strategies. The optimized control flow graph facilitates a deeper understanding of program logic and improves deobfuscation efficiency.
[0110] Step 136: By counting the number of cross-references and sorting addresses, determine the main dispatch block with the most cross-references in the control flow graph and whose address is located before a preset threshold. Analyze the indirect jump instructions or indirect call instructions in the main dispatch block and extract the operands of the registers in the indirect jump instructions or indirect call instructions in the main dispatch block to identify the control variables.
[0111] It should be understood that the main dispatch block is one or more basic blocks in the control flow graph with the most cross-references and addresses located before a preset threshold. It often contains indirect jump or call instructions. In deobfuscation analysis, identifying the main dispatch block helps in understanding the core logic and control flow management mechanism of the program. Register operands refer to the data stored in the register, used as operation parameters in indirect jump or call instructions. In the analysis scenario, they are used to trace the source and change process of control variables.
[0112] Accordingly, step 136 identifies the main dispatch block and identifies control variables by parsing the indirect jump or call instructions within it. This step focuses on the core control logic of the binary program and helps to gain a deeper understanding of the program's main functions and control mechanisms.
[0113] Step 137: Reverse trace the assignment operation of the control variable to locate the initial dispatch block where the control variable is first assigned a value.
[0114] Accordingly, step 137 reverse-tracks the assignment operation of the control variable to find the first assignment point. This is crucial for understanding the origin and initial state of the control variable and provides a starting point for subsequent dynamic tracking.
[0115] Step 138: Based on the initial dispatch block and the assignment sequence of control variables, dynamically track all instruction chains that modify control variables, and record the calculation logic and modification path of the control variable values.
[0116] It should be understood that a modification path refers to a record of all instruction chains that can cause changes to the values of control variables. In binary program analysis, understanding modification paths helps reveal how control variables are manipulated to affect program behavior, thus aiding in deobfuscation.
[0117] Accordingly, step 138 dynamically tracks all instruction chains that modify control variables based on the initial dispatch block and the assignment sequence of control variables. This process can record the change trajectory of control variables in detail, helping analysts to fully understand the impact of control variables on program behavior.
[0118] Step 139: Based on the calculation logic and the modified path, generate a state transition graph with basic blocks as nodes and control variable states as edges. The state transition graph contains the mapping relationship between changes in the values of control variables and branch jumps.
[0119] Accordingly, the state transition diagram finally generated in step 139 not only shows the mapping relationship between the changes in the values of control variables and branch jumps, but also provides a new perspective to understand the execution logic of the program. It is particularly suitable for analyzing highly confusing programs because it can highlight those control flow transfer patterns that are not easily noticed.
[0120] By executing steps 131-139, the embodiments of this application ensure the systematic nature and accuracy of the analysis process, thereby improving the overall analysis results. These steps work together to achieve a deep understanding and precise parsing of obfuscated binary programs.
[0121] In some possible embodiments, S14, identifying the identifiers of useless basic blocks in the objective function based on the state transition diagram, includes:
[0122] Step 141: Remove the valid instructions related to the calculation of string encryption algorithm parameters and control variables from the second instruction sequence consisting of all valid basic blocks in the objective function to obtain the remaining instruction sequence.
[0123] It should be understood that the second instruction sequence refers to the sequence of instructions composed of all valid basic blocks extracted from the objective function. In binary program analysis scenarios, it serves as the foundational dataset used to further filter and identify useless basic blocks. The remaining instruction sequence is the sequence of instructions remaining after removing valid instructions related to string encryption algorithm parameters and control variable calculations from the second instruction sequence. It helps focus on code segments that do not directly participate in core logic processing and aids in identifying potentially useless or obfuscated basic blocks.
[0124] Accordingly, step 141 removes instructions related to the calculation of string encryption algorithm parameters and control variables from the second instruction sequence to obtain the remaining instruction sequence. This process effectively narrows the scope of interest, allowing subsequent analysis to focus more on parts that may not participate in actual logical processing. This method improves the efficiency and accuracy of identifying useless basic blocks.
[0125] Step 142: Perform reachability analysis on the control flow graph to obtain the basic blocks containing the remaining instruction sequences, and filter the basic blocks that meet the following conditions: there is no complete path from the function entry to the basic block in the control flow graph, and the jump conditions of all predecessor basic blocks are false in the state transition graph.
[0126] It should be understood that reachability analysis is a technique used to determine whether paths exist between nodes in a control flow graph. In this scenario, it is used to identify which basic blocks in the control flow graph are reachable from function entry points, thereby identifying unreachable basic blocks and treating them as potentially useless basic blocks.
[0127] Accordingly, step 142 performs reachability analysis on the control flow graph and filters basic blocks that meet specific conditions, accurately identifying basic blocks that will not be accessed during normal execution. Compared to methods that rely solely on static analysis, this method incorporates information from the actual execution path, ensuring the reliability of the identification results.
[0128] Step 143: Inject dynamic probes into the selected basic blocks to monitor the actual execution coverage of the selected basic blocks. If the actual execution coverage is lower than the preset coverage threshold, the basic blocks whose actual execution coverage is lower than the preset coverage threshold are identified as useless basic blocks. The preset coverage threshold is dynamically adjusted based on the obfuscation strength defined in the string encryption algorithm parameters.
[0129] It should be understood that dynamic probes are code snippets inserted during program runtime to collect execution information at specific locations. By injecting dynamic probes, the actual execution coverage of specific basic blocks can be monitored, which is crucial for verifying whether these basic blocks are actually being used. The preset coverage threshold is a threshold dynamically adjusted based on the obfuscation strength defined in the string encryption algorithm parameters, used to determine whether a basic block is a useless basic block. If the actual execution coverage of a basic block is lower than this threshold, it is considered useless.
[0130] Accordingly, step 143 verifies whether these basic blocks are truly unused by injecting dynamic probes into the selected basic blocks and monitoring their actual execution coverage. This method not only provides a theoretical probability analysis but also confirms the status of the basic blocks through actual runtime data, increasing the credibility of identifying useless basic blocks.
[0131] As one possible implementation, step 143, injecting dynamic probes into the selected basic blocks to monitor the actual execution coverage of the selected basic blocks, includes:
[0132] Step c1: Insert a first probe before the entry instruction of the selected basic block to record the number of entries; insert a second probe before the exit jump instruction of the selected basic block to record the number of exits.
[0133] It should be understood that the first probe is a code snippet inserted before the entry instruction of the selected basic block, used to record the number of times the basic block is entered. In binary program analysis scenarios, this helps track the actual usage frequency of a specific basic block, thereby determining whether it is a useless basic block. The second probe is a code snippet inserted before the exit jump instruction of the selected basic block, used to record the number of times the basic block exits, used to further confirm the actual execution status of the basic block, and combined with the entry count to calculate the actual execution coverage.
[0134] Step c2: Associate the number of entries and exits with the corresponding control variable states in the state transition diagram, and record the following information: the control variable value when the basic block is executed, and jump to the address of the predecessor dispatch block of that basic block.
[0135] It should be understood that the state of control variables refers to their values at a given moment, which determine the branching and jumping behavior of the binary program. By associating with the state of control variables, we can better understand the specific conditions that trigger the execution of basic blocks and their contextual information. The address of the preceding dispatch block refers to the address of the basic block executed before jumping to the current basic block. Recording this information helps in constructing a more detailed execution path graph, facilitating the analysis of dependencies and execution flow between basic blocks.
[0136] Step c3: Calculate the actual execution coverage based on the ratio of the number of entries to the total number of function calls. The total number of function calls is obtained by counting the number of entries and exits.
[0137] It should be understood that actual execution coverage is a metric calculated based on the ratio of entry counts to the total number of function calls, reflecting the proportion of selected basic blocks that are actually executed during the entire function's execution. This metric is of great significance for assessing the importance of basic blocks.
[0138] By executing steps c1 to c3, this embodiment of the application inserts probes at the entry and exit points of the selected basic blocks, accurately recording the number of entries and exits for each basic block. This provides direct runtime data support, making the judgment of the actual usage of basic blocks more accurate and reliable. Compared to methods relying solely on static analysis or theoretical speculation, dynamic probes provide verification methods in a real-world operating environment, ensuring the credibility of the identification results. Correlating the data recorded by the probes with the state of the control variables in the state transition diagram not only tracks the number of times a basic block is executed but also obtains the specific conditions that trigger the execution of that basic block (such as the value of the control variables) and information about the predecessor dispatch block. This correlation analysis helps to comprehensively understand the role and impact of basic blocks in the program execution process. Compared to simply recording the number of executions, this method increases the understanding of the execution context, allowing analysts to not only know whether a basic block is executed but also why it is executed, improving the depth and accuracy of the analysis. Calculating actual execution coverage based on the ratio of entry counts to total function calls provides a quantitative metric for measuring the importance and frequency of use of basic blocks. This is crucial for determining whether a basic block is useless, as low coverage often indicates that the basic block may contain invalid code intentionally inserted for obfuscation purposes. Compared to relying solely on static analysis or simple probe logging, this method provides a more scientific and reasonable standard for evaluating the value of basic blocks by calculating coverage, making the process of identifying useless basic blocks more systematic and accurate. In summary, steps C1 to C3 not only provide direct runtime data support but also enhance the understanding of the actual usage of basic blocks through correlation analysis and coverage calculation. These specific steps focus on in-depth analysis using real-time data provided by dynamic probe technology, thereby improving the accuracy and reliability of identifying useless basic blocks.
[0139] Step 144: Associate the remaining instruction sequence with the marking results to generate an instruction-identifier mapping table. Traverse all other functions in the obfuscated binary program. Based on the isomorphism analysis of the control flow graph and state transition graph, identify useless basic blocks in other functions that are similar to the useless modules in the target function. Combine the identifiers of similar useless basic blocks with the identifiers of the useless basic blocks to form an identifier set.
[0140] It should be understood that an instruction-identifier mapping table is a data structure that records each instruction and its corresponding identifier (such as whether it is a useless basic block). This helps in the systematic management and analysis of the various basic blocks in a binary program, and facilitates subsequent processing and optimization. Isomorphism analysis refers to the process of comparing two graph structures to determine whether they have the same topological properties. In this scenario, it is used to identify patterns in other functions that are similar to the labeled useless basic blocks, thereby expanding the scope of useless basic block identification.
[0141] Accordingly, step 144 generates an instruction-identifier mapping table and applies the method to other functions throughout the program. By identifying similar useless basic blocks through isomorphism analysis, it achieves extended application from local to global. This method is not limited to the analysis of a single function but can be generalized to the entire program, greatly improving the comprehensiveness and depth of deobfuscation work.
[0142] By executing steps 141 to 144, this embodiment of the application utilizes actual operating data and graph structure similarity to improve the accuracy and coverage of identifying useless basic blocks, thereby providing technical support for a deeper understanding and simplification of the obfuscated program.
[0143] This application provides an exemplary flow of an analysis method for obfuscated passes based on LLVM. It should be understood that LLVM has modular functionality; therefore, this application can be divided into four modules: String Localization and Decryption Analysis Module (SLDAM), Complex Expression Analysis Module (CEAM), Control Flow Analysis and Basic Block Dispatching Mechanism Analysis Module (CFABBDMAM), and Useless Basic Block Identification Module (UBBIM). These modules perform in-depth analysis of the minimum functionally complete function (i.e., the aforementioned objective function) to gradually derive the obfuscation implementation logic of the obfuscated pass in LLVM. The complex expression is an exemplary objective expression. The input, output, and processing procedures of the above four modules, as well as the interaction procedures between modules, are as follows:
[0144] The input to the string location and decryption analysis module is: an LLVM-obfuscated binary program (i.e., the obfuscated binary program mentioned above), and the output is the location of the encrypted string, the location of the decryption function, and the decryption algorithm. The processing of this module includes: (1) String location: Static analysis of the data segment to find suspicious byte sequences. Identify string operation functions (such as `strcpy`, `strcmp`), trace the data flow through cross-referencing, and find possible encrypted strings. Analyze the initialization logic to locate the string decryption function called before the normal process. (2) Decryption process analysis: Through the call relationship of string operation functions, trace back upwards to find the decryption function. Reverse the assembly code of the decryption function, identify key operations, and derive the decryption algorithm. Write a decryption script to automatically decrypt the string.
[0145] The input to the complex expression analysis module is a code snippet containing a complex expression, and the output is the logic and implementation principle of the complex expression. The processing of this module includes: (1) Expression recognition: focusing on computationally intensive code, identifying instruction sequences containing a large number of arithmetic, logical, and bitwise operations. Using pattern matching, common complex expression patterns are identified. Using data flow analysis, the source and destination of variables are tracked to help understand the expression logic. (2) Expression implementation method derivation: analyzing each instruction one by one to understand the function of each instruction. Converting the instruction sequence into a mathematical expression and simplifying it. Trying to replace it with simpler equivalent code and testing whether the program behavior changes.
[0146] The input to the control flow analysis and basic block distribution method parsing module is the control flow graph of the binary program, and the output is the initial distribution block, key distribution variables (i.e., the control variables mentioned above), and basic block execution sequence. The processing steps of this module are as follows: (1) Control flow graph construction and analysis: Use a disassembler to generate a control flow graph. Analyze the structure of the control flow graph to determine the number, size, jump relationship, loops, and branches of basic blocks. (2) Initial distribution block and key distribution variable identification: In a function, the module with the most cross-references and the relatively earlier address is the main distribution block. Analyze the instructions such as "jmp reg" or "call reg" in the main distribution block to find the key distribution control variables. The basic block in which the key distribution control variables are initially assigned is the initial distribution block. (3) Distribution control variable calculation method analysis: Track all instructions that modify the key distribution control variables. Construct a state transition graph based on the variable calculation method. Derive the basic block execution sequence based on the value of the initial distribution block and the state transition graph.
[0147] The input to the useless basic block identification module is: a minimal functional complete function and a binary program. The output is: the identifier of the useless basic block. The processing of this module includes: (1) Collection of fixed feature instructions: In the basic blocks that have been identified in the minimal function, the set of instruction sequences after removing useful instructions is the feature, such as the calculation process of the simplest control distribution. Manual review to eliminate false alarms. (2) Identification of useless basic blocks: Search for basic blocks containing fixed feature instructions in the binary program. Combine with control flow analysis to verify whether they are unreachable blocks or false branches. (3) Optionally, removal of useless basic blocks: Modify the jump instruction to point to the next valid basic block. Delete the useless code. It should be noted that sufficient testing should be performed when removing.
[0148] The interactions between modules are as follows: The minimum functionally complete function serves as the starting point for analysis. Specifically, all four modules analyze the minimum functionally complete function in depth to extract obfuscation features. The string location and decryption analysis module provides information to the other three modules: it locates the decryption function, providing crucial clues for understanding complex expressions and control flow obfuscation, as decryption functions typically involve complex calculations and control flow operations. The control flow analysis and basic block distribution parsing module and the useless basic block identification module mutually verify each other: the basic block distribution patterns identified by the control flow analysis and basic block distribution parsing module can be used to verify whether the useless blocks identified by the useless basic block module are truly unreachable.
[0149] This embodiment has the following advantages: (1) Instead of directly removing obfuscation, it reverse-engineers the implementation logic of the obfuscated Pass in LLVM by analyzing the characteristics of the obfuscated code. (2) It takes the minimum functionally complete function as the starting point: it is highly targeted and can effectively reduce the complexity of the analysis and improve the efficiency of the analysis.
[0150] (3) In-depth understanding of the internal obfuscation mechanism: It focuses not only on the result of obfuscation but also on the obfuscation process, enabling a deeper understanding of LLVM obfuscation technology. (4) Extraction of obfuscation features: This embodiment can extract the behavioral features of various obfuscation passes, providing a data foundation for subsequent research and development of automated deobfuscation tools. (5) Guidance on obfuscation pass development: By understanding the implementation logic of obfuscation passes, this embodiment can guide developers to improve obfuscation passes and enhance code security.
[0151] Figure 2 A schematic diagram of the structure of an analysis system based on obfuscated PASS in LLVM provided in this application embodiment is shown below. Figure 2 As shown, the system includes:
[0152] The extraction and positioning module 21 is used to extract the target function from the obfuscated binary program, locate the position of the encrypted string in the target function, and determine the decryption logic based on the position of the encrypted string. The decryption logic includes decryption algorithm parameters.
[0153] The lookup and identification module 22 is used to find the target expression in the target function, identify the expression logic through pattern matching, and determine the string encryption algorithm parameters based on the decryption logic and the expression logic. The target expression includes a combination of arithmetic operations, logical operations and bitwise operations.
[0154] The recognition module 23 is constructed to construct a control flow graph based on the expression logic, identify the control variables in the control flow graph, and generate a state transition graph of the control variables based on the assignment sequence of the control variables.
[0155] The identification and determination module 24 is used to identify the identifiers of useless basic blocks in the target function according to the state transition diagram. Based on the string encryption algorithm parameters and the identifiers of useless basic blocks, it determines the obfuscation implementation logic of the obfuscated binary program. The useless basic blocks are unreachable or invalid code blocks inserted by the obfuscation PASS in the underlying virtual machine LLVM during the obfuscation process of the binary program.
[0156] Figure 2 The aforementioned analysis system based on LLVM-based obfuscated PASS can perform... Figure 1 The implementation principle and technical effects of the LLVM-based obfuscated PASS analysis method described in the illustrated embodiments will not be repeated here. The specific methods by which each module and unit performs its operations in the LLVM-based obfuscated PASS analysis system described in the above embodiments have been detailed in the embodiments related to this method, and will not be elaborated upon here.
[0157] In one possible design, Figure 2 The analysis system based on obfuscated PASS in LLVM, as shown in the embodiment, can be implemented as a computing device, such as... Figure 3 As shown, the computing device may include a storage component 31 and a processing component 32.
[0158] The storage component 31 stores one or more computer instructions, wherein the one or more computer instructions are invoked and executed by the processing component 32.
[0159] The processing component 32 is used to: extract the target function from the obfuscated binary program, locate the position of the encrypted string in the target function, determine the decryption logic based on the position of the encrypted string, the decryption logic including decryption algorithm parameters; find the target expression in the target function, identify the expression logic through pattern matching, determine the string encryption algorithm parameters based on the decryption logic and the expression logic, the target expression includes a combination of arithmetic operations, logical operations and bitwise operations; construct a control flow graph based on the expression logic, identify the control variables in the control flow graph, generate a state transition graph of the control variables based on the assignment sequence of the control variables; identify the identifiers of useless basic blocks in the target function based on the state transition graph, and determine the obfuscation implementation logic of the obfuscated binary program based on the string encryption algorithm parameters and the identifiers of useless basic blocks, the useless basic blocks being unreachable or invalid code blocks inserted by the obfuscation PASS in the underlying virtual machine LLVM during the obfuscation process of the binary program.
[0160] The processing component 32 may include one or more processors to execute computer instructions to complete all or part of the steps in the above-described method. Alternatively, the processing component may be implemented as one or more application-specific integrated circuits (ASICs), digital signal processors (DSPs), digital signal processing devices (DSPDs), programmable logic devices (PLDs), field-programmable gate arrays (FPGAs), controllers, microcontrollers, microprocessors, or other electronic components to perform the above-described method.
[0161] Storage component 31 is configured to store various types of data to support operations at the terminal. The storage component can be implemented from any type of volatile or non-volatile storage device or a combination thereof, such as Random Access Memory (RAM), Static Random-Access Memory (SRAM), Electrically Erasable Programmable Read Only Memory (EEPROM), Erasable Programmable Read Only Memory (EPROM), Programmable Read Only Memory (PROM), Read Only Memory (ROM), magnetic storage, flash memory, magnetic disk, or optical disk.
[0162] Of course, computing devices may also include other components, such as input / output interfaces, display components, communication components, etc.
[0163] Input / output interfaces provide interfaces between processing components and peripheral interface modules, which can be output devices, input devices, etc.
[0164] The communication components are configured to facilitate wired or wireless communication between computing devices and other devices.
[0165] The computing device can be a physical device or an elastic computing host provided by a cloud computing platform. In this case, the computing device can refer to a cloud server, and the aforementioned processing components, storage components, etc., can be basic server resources rented or purchased from the cloud computing platform.
[0166] This application also provides a computer storage medium storing a computer program, which, when executed by a computer, can perform the above-described functions. Figure 1 The illustrated embodiment is based on the analysis method of obfuscated PASS in LLVM.
[0167] Those skilled in the art will clearly understand that, for the sake of convenience and brevity, the specific working process of the system and unit described above can be referred to the corresponding process in the foregoing method embodiments, and will not be repeated here.
[0168] The system 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.
[0169] 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.
[0170] Finally, it should be noted that the above embodiments are only used to illustrate the technical solutions of this application, and are not intended to limit them. Although this application 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. Such 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 this application.
Claims
1. A method for analyzing obfuscated passes based on LLVM, characterized in that, include: Extract the target function from the obfuscated binary program, locate the position of the encrypted string in the target function, and determine the decryption logic based on the position of the encrypted string. The decryption logic includes decryption algorithm parameters. The target expression in the target function is found, and the expression logic is identified by pattern matching. Based on the decryption logic and the expression logic, the string encryption algorithm parameters are determined. The target expression includes a combination of arithmetic operations, logical operations, and bitwise operations. A control flow graph is constructed based on the expression logic, and the control variables in the control flow graph are identified. Based on the assignment sequence of the control variables, a state transition graph of the control variables is generated. Identify the identifiers of useless basic blocks in the target function based on the state transition diagram. Based on the string encryption algorithm parameters and the identifiers of the useless basic blocks, determine the obfuscation implementation logic of the obfuscated binary program. The useless basic blocks are unreachable or invalid code blocks inserted by the obfuscation PASS in the underlying virtual machine LLVM during the obfuscation process of the binary program. The expression logic includes jump relationships between instructions within a basic block, jump relationships between basic blocks, strongly connected components, and branch structures. The step of constructing a control flow graph based on the expression logic, identifying control variables in the control flow graph, and generating a state transition graph for the control variables based on the assignment sequence of the control variables includes: Based on the first instruction sequence in the target expression, the first instruction sequence is divided into multiple basic blocks according to a preset partitioning rule. The number of basic blocks is counted, and the number of instructions contained in each basic block is taken as the size of the basic block. Within each basic block, jump instructions between instructions are searched to determine the jump relationship between the instructions. All basic blocks are traversed to find jump instructions from one basic block to another to determine the jump relationship between the basic blocks. Based on the number of basic blocks, the size of the basic blocks, the jump relationships between instructions, and the jump relationships between basic blocks, an initial structure diagram is constructed; Identify the strongly connected components in the initial structural graph, optimize the strongly connected components to obtain an intermediate structural graph, assign a corresponding weight to each edge in the intermediate structural graph to obtain a weighted intermediate structural graph, wherein the strongly connected components are a loop structure composed of mutually reachable basic blocks. Identify the branch structure in the weighted intermediate structure graph, and adjust the weight of the corresponding edge according to the execution frequency and path complexity of different branches in the branch structure to obtain the control flow graph; By counting cross-references and sorting addresses, the main distribution block with the most cross-references in the control flow graph and whose address is below a preset threshold is determined. The indirect jump instructions or indirect call instructions in the main distribution block are parsed, and the operands of the registers in the indirect jump instructions or indirect call instructions in the main distribution block are extracted to identify the control variables. By tracing the assignment operation of the control variable in reverse, the initial dispatch block that first assigns a value to the control variable is located; Based on the initial distribution block and the assignment sequence of the control variables, dynamically track all instruction chains that modify the control variables, and record the calculation logic and modification path of the control variable values; Based on the computational logic and the modified path, a state transition graph is generated with basic blocks as nodes and control variable states as edges. The state transition graph contains the mapping relationship between changes in the values of control variables and branch jumps.
2. The method according to claim 1, characterized in that, The process of identifying strongly connected components in the initial structural graph, optimizing these components to obtain an intermediate structural graph, and assigning a corresponding weight to each edge in the intermediate structural graph to obtain a weighted intermediate structural graph includes: The initial structure graph is divided into multiple subgraphs to decompose the depth-first search process of the Tarjan algorithm into multiple subtasks, and multi-threading is used to identify strongly connected components in all subgraphs. Perform a cyclic reduction operation on each of the strongly connected components, and generate the intermediate structure graph after performing the cyclic reduction operation on all the strongly connected components. For each edge in the intermediate structure graph, the values of three dimensions—the probability of a jump, the length of the jump path, and the degree of impact on jump performance—are fused to obtain the edge weight, thus producing a weighted intermediate structure graph.
3. The method according to claim 2, characterized in that, The cyclic reduction operation includes: If there is a strongly connected component with a single cyclic entry block, then the strongly connected component with a single cyclic entry block is compressed into a single virtual node, and the virtual node is associated with the single cyclic entry block. Alternatively, if there are strongly connected components with multiple cyclic entry blocks, then one of the cyclic entry blocks is selected as the main loop head node based on the dominator tree algorithm, and the remaining cyclic entry blocks are deleted.
4. The method according to claim 1, characterized in that, The step of adjusting the weights of corresponding edges based on the execution frequency and path complexity of different branches within the branch structure to obtain the control flow graph includes: Based on the static analysis results of the branch structure in the initial structure diagram, the actual number of executions of each branch in the branch structure is obtained by dynamic instrumentation, and the execution frequency of each branch is calculated. For each branch's path, the path complexity is determined based on the number of basic blocks and the total number of instructions in the branch, the maximum depth of the data dependency chain in the branch, and the nesting level of the strongly connected components in the branch. The execution frequency and the path complexity are input into a preset weight calculation model to generate a fused weight value; The weights of the corresponding edges in the weighted intermediate structure graph are adjusted using the fusion weight values to obtain the control flow graph.
5. The method according to claim 1, characterized in that, Identify the identifiers of useless basic blocks in the objective function based on the state transition diagram, including: From the second instruction sequence consisting of all valid basic blocks in the objective function, remove the valid instructions related to the calculation of the string encryption algorithm parameters and control variables to obtain the remaining instruction sequence; A reachability analysis is performed on the control flow graph to obtain the basic blocks containing the remaining instruction sequence, and basic blocks that meet the following conditions are selected: there is no complete path from the function entry to the basic block in the control flow graph, and the jump conditions of all predecessor basic blocks are false in the state transition graph; Dynamic probes are injected into the selected basic blocks to monitor the actual execution coverage of the selected basic blocks. If the actual execution coverage is lower than a preset coverage threshold, the basic blocks whose actual execution coverage is lower than the preset coverage threshold are identified as useless basic blocks. The preset coverage threshold is dynamically adjusted based on the obfuscation strength defined in the string encryption algorithm parameters.
6. The method according to claim 5, characterized in that, Injecting dynamic probes into the selected basic blocks to monitor the actual execution coverage of the selected basic blocks, including: A first probe is inserted before the entry instruction of the selected basic block to record the number of entries; a second probe is inserted before the exit jump instruction of the selected basic block to record the number of exits. Associate the number of entries and the number of exits with the corresponding control variable states in the state transition diagram, and record the following information: the control variable value when the basic block is executed, and jump to the address of the predecessor dispatch block of the basic block; The actual execution coverage is calculated based on the ratio of the number of entries to the total number of function calls, whereby the total number of function calls is obtained by statistically analyzing the number of entries and the number of exits.
7. An analysis system based on obfuscated PASS in LLVM, characterized in that, include: An extraction and positioning module is used to extract a target function from an obfuscated binary program, locate the position of an encrypted string in the target function, and determine decryption logic based on the position of the encrypted string. The decryption logic includes decryption algorithm parameters. The search and identification module is used to search for the target expression in the target function, identify the expression logic through pattern matching, and determine the string encryption algorithm parameters based on the decryption logic and the expression logic. The target expression includes a combination of arithmetic operations, logical operations and bitwise operations. A recognition module is constructed to build a control flow graph based on the expression logic, identify the control variables in the control flow graph, and generate a state transition graph of the control variables based on the assignment sequence of the control variables. The identification and determination module is used to identify the identifiers of useless basic blocks in the target function according to the state transition diagram, and to determine the obfuscation implementation logic of the obfuscated binary program based on the string encryption algorithm parameters and the identifiers of the useless basic blocks. The useless basic blocks are unreachable or invalid code blocks inserted by the obfuscation PASS in the underlying virtual machine LLVM during the obfuscation process of the binary program. The expression logic includes jump relationships between instructions within a basic block, jump relationships between basic blocks, strongly connected components, and branch structures. The step of constructing a control flow graph based on the expression logic, identifying control variables in the control flow graph, and generating a state transition graph for the control variables based on the assignment sequence of the control variables includes: Based on the first instruction sequence in the target expression, the first instruction sequence is divided into multiple basic blocks according to a preset partitioning rule. The number of basic blocks is counted, and the number of instructions contained in each basic block is taken as the size of the basic block. Within each basic block, jump instructions between instructions are searched to determine the jump relationship between the instructions. All basic blocks are traversed to find jump instructions from one basic block to another to determine the jump relationship between the basic blocks. Based on the number of basic blocks, the size of the basic blocks, the jump relationships between instructions, and the jump relationships between basic blocks, an initial structure diagram is constructed; Identify the strongly connected components in the initial structural graph, optimize the strongly connected components to obtain an intermediate structural graph, assign a corresponding weight to each edge in the intermediate structural graph to obtain a weighted intermediate structural graph, wherein the strongly connected components are a loop structure composed of mutually reachable basic blocks. Identify the branch structure in the weighted intermediate structure graph, and adjust the weight of the corresponding edge according to the execution frequency and path complexity of different branches in the branch structure to obtain the control flow graph; By counting cross-references and sorting addresses, the main distribution block with the most cross-references in the control flow graph and whose address is below a preset threshold is determined. The indirect jump instructions or indirect call instructions in the main distribution block are parsed, and the operands of the registers in the indirect jump instructions or indirect call instructions in the main distribution block are extracted to identify the control variables. By tracing the assignment operation of the control variable in reverse, the initial dispatch block that first assigns a value to the control variable is located; Based on the initial distribution block and the assignment sequence of the control variables, dynamically track all instruction chains that modify the control variables, and record the calculation logic and modification path of the control variable values; Based on the computational logic and the modified path, a state transition graph is generated with basic blocks as nodes and control variable states as edges. The state transition graph contains the mapping relationship between changes in the values of control variables and branch jumps.
8. A computing device, characterized in that, It includes a processing component and a storage component; the storage component stores one or more computer instructions; the one or more computer instructions are invoked and executed by the processing component to implement the analysis method based on obfuscated PASS in LLVM as described in any one of claims 1 to 6.
9. A computer storage medium, characterized in that, The system contains a computer program that, when executed by a computer, implements an analysis method based on obfuscated PASS in LLVM as described in any one of claims 1 to 6.
Citation Information
Patent Citations
Control flow obfuscation method and system based on a callback function
CN111723345A
Task control method and device based on state machine
CN118377604A