An ordered, enhanced, cacheable symbolic execution static analysis method and system
By performing function call graph topological sorting on the code and caching intermediate results, the problem of low efficiency in static code analysis in existing technologies is solved, enabling efficient cross-function analysis and incremental analysis.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- RUAN AN TECH CO LTD
- Filing Date
- 2022-11-28
- Publication Date
- 2026-06-02
AI Technical Summary
Existing static code analysis methods are inefficient when dealing with large-scale code, failing to meet the agile and automated process requirements of software development companies, and face difficulties in cross-function and cross-file analysis.
By abstracting the program code into a function call graph, performing topological sorting, decomposing it into function units and checker units, using depth-first traversal and caching intermediate results, utilizing a stack to store simulated execution information, and combining constraint solving to determine defect conditions.
It improves the efficiency of static code analysis, reduces redundant development, solves cross-function dependency issues, and supports incremental analysis and cross-binary library analysis.
Smart Images

Figure CN115827444B_ABST
Abstract
Description
Technical Field
[0001] This invention relates to the field of information security technology, and in particular to an ordered, enhanced, and cacheable symbolic execution static analysis method and system. Background Technology
[0002] Symbolic execution in static code analysis is a search algorithm that uses techniques such as constraint solving to accurately find code defects by simulating code execution logic. The search time is proportional to the size of the code; for code with tens of millions of lines, a complete search can take several hours. This cannot meet the needs of agile and automated processes widely adopted by software development companies. Furthermore, cross-function and cross-file analysis is a common problem in static analysis. Therefore, how to solve the problems of existing static code analysis methods is something that needs to be considered.
[0003] It should be noted that the information disclosed in the background section above is only used to enhance the understanding of the background of this disclosure, and therefore may include information that does not constitute prior art known to those skilled in the art. Summary of the Invention
[0004] The purpose of this invention is to overcome the shortcomings of the prior art and provide an ordered, enhanced, and cacheable symbolic execution static analysis method and system, which solves the deficiencies of current code static analysis methods.
[0005] The objective of this invention is achieved through the following technical solution: an ordered, enhanced, and cacheable symbolic execution static analysis method, wherein the static analysis method includes:
[0006] S1. Abstract each function call point in the program code into a node caller, a node callee, and a directed edge from the caller to the callee. Set the call nodes and call edges of the entire program into the function call graph of this program.
[0007] S2. Perform a topological sort on the function call graph to obtain a list in reverse order of function dependencies;
[0008] S3. Divide the function call graph into separate function units and checker units according to the reverse order, and traverse and calculate the function units and checker units in turn. Complete the analysis after the complete traversal is completed.
[0009] S4. Store the intermediate results of this calculation in the stack for use in subsequent dependent calculations, and at the same time look up the intermediate cached results that this calculation depends on.
[0010] S5. Based on the relevant statement numbers and statement execution information of the cached query, determine whether the defect conditions are met based on the execution information of each statement. If they are met, a defect result is generated.
[0011] The S3 step specifically includes:
[0012] The functions in the function call graph are divided into multiple separate function units. Each function unit's branch is a separate execution path. The branch path that has been traversed is the complete analysis of the function unit.
[0013] All checkers in the function call graph are broken down according to their functions and implemented as units organized by function. Steps S1 and S2 are repeated for the functions implemented by each checker unit to obtain the function call graph of all checker units and the list of checker functions with dependency order. The program functions are then analyzed and calculated by the checkers in the order of dependency.
[0014] The inspector includes a base layer and a logic layer. The base layer is used for basic information extraction and can be reused in other inspectors. The logic layer is used to complete the business logic for specific defects based on the business logic of using freed memory.
[0015] The stack storage includes: when the simulated execution reaches a conditional branch, a new stack frame is created for each branch condition, and the intermediate information contained in the subsequent branch condition is stored in this stack frame. When the current branch condition is completed, the stack frame of this branch condition is popped, and the stack frame of other branch conditions is switched. This process is repeated, and the set of stack frames in the stack is the complete information when this branch condition is reachable.
[0016] The defect conditions are abstractions of the program semantics based on the content of the checker, represented as a set of constraint condition symbols in mathematical logic. Finally, constraint solving is used to judge this set of constraint conditions. Constraint solving mainly solves the defect conditions and branch conditions in the chassis. Constraints are set in advance in the branching stage to reduce the calculation of unreachable branches, or the branch conditions are calculated in the final defect generation stage to reduce the amount of calculation of branch conditions.
[0017] An ordered, enhanced, cacheable symbolic execution static analysis system includes a sorting preparation module, an ordered traversal module, a cache management module, and an inspection and calculation module.
[0018] The sorting preparation module is used to abstract each function call point in the program code into a node caller, a node callee, and a directed edge from the caller to the callee. The call nodes and call edges of the whole program are set into the function call graph of this program. The function call graph is topologically sorted to obtain a list in reverse order of function dependencies.
[0019] The ordered traversal module is used to divide the function call graph into separate function units and checker units according to the reverse order, and to traverse and calculate the function units and checker units in sequence. The analysis is completed after the complete traversal is finished.
[0020] The cache management module is used to store the intermediate results of this calculation through a stack for use by subsequent dependent calculations, and to look up the intermediate cache results that this calculation depends on.
[0021] The inspection calculation module is used to determine whether the defect conditions are met based on the execution information of each statement and the number of all relevant statements in the cache query. If the conditions are met, a defect result is generated.
[0022] The ordered traversal module includes a function analysis unit and a checker analysis unit;
[0023] The function analysis unit is used to divide the functions in the function call graph into multiple separate function units. Each function unit's branch is a separate execution path, which is traversed in a depth-first order. The analysis of the function unit is completed when the traversed branch path is completed.
[0024] The inspector analysis unit is used to split all inspectors in the function call graph according to their functions, and implement them as units organized by function. The sorting preparation module is repeatedly executed for the functions implemented by each inspector unit to obtain the function call graph of all inspector units and the list of inspector functions with dependency order in sequence. Then, the inspectors are used to analyze and calculate the program functions in the order of dependency.
[0025] A computer-readable storage medium having a computer program stored thereon, which, when executed by a processor, implements the steps of the static analysis method.
[0026] A terminal device includes a memory and a processor, wherein the memory stores a computer program, and the processor executes the computer program to implement the steps of the static analysis method.
[0027] This invention has the following advantages: an ordered, enhanced, and cacheable symbolic execution static analysis method and system, which implements mutually dependent checkers by combining them according to the dependency order, increasing the reusability of checkers and reducing redundant development; the dependency order between functions can solve the analysis dependency problem of cross-function calls; at the same time, by caching the analysis results, the analysis efficiency can be effectively improved, and incremental analysis and cross-binary library analysis can be realized on this basis. Attached Figure Description
[0028] Figure 1 This is a schematic flowchart of the method of the present invention;
[0029] Figure 2 Example diagram of topological sorting for function call graphs;
[0030] Figure 3 Example diagram of saving the stack for branch path states. Detailed Implementation
[0031] To make the objectives, technical solutions, and advantages of the embodiments of this application clearer, 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 a part of the embodiments of this application, and not all of the embodiments. The components of the embodiments of this application described and shown in the accompanying drawings can generally be arranged and designed in various different configurations. Therefore, the detailed description of the embodiments of this application provided below with reference to the accompanying drawings is not intended to limit the scope of protection of the claimed application, but merely represents selected embodiments of this application. All other embodiments obtained by those skilled in the art based on the embodiments of this application without inventive effort are within the scope of protection of this application. The present invention will be further described below with reference to the accompanying drawings.
[0032] One embodiment of the present invention relates to an ordered, enhanced, and cacheable symbolic execution static analysis method, which calculates the dependency order of program functions and checkers through graph topological sorting; performs each check step sequentially; caches and retrieves the check information of each dependency step; calculates the check information of the current checker by combining the information of the checked checkers; and calculates the check information of the current function by combining the information of the checked functions.
[0033] like Figure 1 As shown, it specifically includes the following:
[0034] S1. Abstract each function call point in the program code into a node (Caller), a node (Callee), and a directed edge from the caller to the callee. Collect all the call nodes and call edges in the entire program to form the function call graph of this program.
[0035] The function call graph represents the call relationship between functions in the program. The nodes in the graph are functions, and the directed edges represent the call relationship between functions.
[0036] S2. Perform a topological sort on the function call graph to obtain a list in reverse order of function dependencies;
[0037] like Figure 2As shown, the topological sorting order is not unique; it is sufficient to represent the dependency order. The set of checkers to be checked is also a topologically sortable directed graph relationship. For example, USE_AFTER_FREE and FORWARD_NULL both depend on DEREF_POINTER. The checker set is also sorted to obtain the checker list.
[0038] S3. Divide the function call graph into separate function units and checker units according to the reverse order, and traverse and calculate the function units and checker units in turn. Complete the analysis after the complete traversal is completed.
[0039] Furthermore, specifically including:
[0040] 1) A function unit can be divided into two parts: a calculation part and a control part. The calculation part is for calculating data, and the control part is for controlling the calculation branch flow. Different control conditions for the execution of a function result in different calculation execution flows. This invention exhausts all possible control conditions and performs simulation calculations on the data to obtain the complete possible execution path and execution result of the function.
[0041] 2) The branch selection follows a tree structure, meaning that only the last branch is switched each time, and the calculation results of the previous branches are unaffected and can be reused. Therefore, the results of the previous calculations can be cached in a stack manner for reuse by branches on subsequent reachable paths. (See reference...) Figure 3 .
[0042] 3) Each function yields the following results through simulation:
[0043] Execute branch 1 + the set of constraints on branch 1 + the set of calculation results of branch 1;
[0044] Execute branch 2 + the set of constraints on branch 2 + the set of calculation results of branch 2;
[0045] Execute branch 3 + the set of constraints on branch 3 + the set of calculation results of branch 3;
[0046] 4) For the calculation result of each complete branch path, this invention calculates the constraint conditions of the constraint condition set on this branch, thereby determining whether this path is reachable and under what constraint conditions it is reachable. This step can be solved using general constraint solving tools.
[0047] 5) Calculate whether the constraints of the result set of this branch are reachable. The result is the result of the checker.
[0048] The specific analysis and calculation of the checker are implemented according to the specific business logic of each check item. For example, consider the memory release (USE_AFTER_FREE) checker:
[0049] In C / C++ programs, re-referencing freed memory can cause a memory exception, leading to program crashes. The checker's business logic involves searching for possible execution branches where this problem might occur. Based on this scenario, memory states can be abstracted into three finite states: undefined, allocated, and freed, and the transitions between these states can be represented by a finite state machine. The computation part involves understanding the transition methods for these abstract states and identifying illegal transition operations that could cause exceptions. For example, in C++ code checking, as shown in the table below:
[0050]
[0051] Other inspection tasks can refer to this example to perform similar modeling and calculations on the content to be inspected and the semantics of the code.
[0052] S4. The above steps have ensured the dependency order of the function unit to be checked and the checker unit. Subsequent calculation units can directly utilize the results of the analyzed portion and put these results into the cache file. The checking business calculation process of each unit will have caching operations: intermediate results of this calculation are stored in the stack for use by subsequent dependent calculations, and intermediate cached results dependent on this calculation are retrieved at the same time;
[0053] The inspector design employs a method of extracting common basic components into upper-layer dependencies, similar to inheritance in object-oriented programming. For example, the USE_AFTER_FREE memory release inspector is designed with two layers: pointer dereferencing (base layer) and the use of released memory (logic layer). The base layer extracts basic information, while the logic layer implements the specific defect logic based on the business logic of the USE_AFTER_FREE memory release. Furthermore, the base layer can be reused in other inspectors; for instance, the pointer dereferencing (base layer) can also be used by the FORWARD_NULL null pointer dereferencing inspector.
[0054] The intermediate results simulate the execution results along a specific executable path. Different branches produce different results, and the execution information of one branch depends on the execution of the previous reachable branch. This invention implements this relationship using a stack. When the simulated execution reaches a conditional branch, a new stack frame is created for each branch condition (e.g., branch condition one), storing the intermediate information contained in this branch condition within this stack frame. After branch condition one is executed, its stack frame is popped and pushed onto the stack frame of branch condition two, and so on. This allows for the search of information only from executable branches, which is also known as path-sensitive information in static analysis.
[0055] like Figure 3As shown, the intermediate information for each individual type of check is the result information generated after the simulated execution of a certain statement in the program, which can be represented as a mapping structure: <check type, <statement number, statement execution information>>; and there are contextual dependencies between statements, such as (statement number 1, statement number 5, ..., statement number n), so that all related statements can be associated and extracted based on the dependencies.
[0056] The intermediate cache result data format is a dictionary (key, value set pairs). The dictionary key stores the code tree position corresponding to the information, and the value stores the entire information event stream list associated with this code tree. The calculation process of each inspection item unit applied to each function unit is a gradual extraction process of code content from syntactic information to semantic information. For example, in the null pointer dereference checker (FORWARD_NULL), the basic unit first extracts syntactic information to find which variables involve pointer operations. Based on this, subsequent checkers directly use this part of the syntactic information to perform semantic logic calculations (the calculation process is generally the symbolic execution and constraint solving methods commonly used in static analysis; see the final comments for details), generating new information. At the same time, the generated new information is inserted into the dictionary set. The information flow in the dictionary set is ordered, representing the complete event stream generated by the defect.
[0057] Intermediate results of each check item unit applied to the calculation of each function unit are stored persistently on the local disk.
[0058] Intermediate results from each check item unit applied to the calculations of each function unit can be reused by dependent check item units and dependent function units. This is because the content of the function remains unchanged, and the content of the functions called by the function dependencies also remains unchanged, thus the analyzer's analysis result for this function remains unchanged. This feature can be used to implement incremental analysis, cross-library analysis, and improve analysis efficiency. There are no explicit requirements for the storage format or medium; it is sufficient that the dependent intermediate results can be retrieved in subsequent unit analyses. However, to meet the needs of incremental analysis, offline analysis, and multiple reuse, persistent storage media is recommended, such as files or databases for persistent storage.
[0059] S5. Based on the relevant statement numbers and statement execution information of the cached query, determine whether the defect conditions are met based on the execution information of each statement. If they are met, a defect result is generated.
[0060] Furthermore, defect conditions are abstractions of program semantics based on the checker content, represented as a set of constraint symbols in mathematical logic. Finally, constraint solvers evaluate these constraints. Constraint solvers primarily solve defect conditions and branch conditions within the framework, either by imposing constraints early in the branching phase to reduce computation of unreachable branches, or by calculating branch conditions at the final defect generation stage to reduce computational load. Constraint solvers could consider using open-source solutions, such as Microsoft Z3.
[0061] Another embodiment of the present invention relates to an ordered, enhanced, cacheable symbolic execution static analysis system, which includes a sorting preparation module, an ordered traversal module, a cache management module, and an inspection calculation module;
[0062] Furthermore, the sorting preparation module is used to abstract each function call point in the program code into a node caller, a node callee, and a directed edge from the caller to the callee. The call nodes and call edges of the entire program are set into the function call graph of this program. The function call graph is topologically sorted to obtain a list in reverse order of function dependencies.
[0063] Furthermore, the ordered traversal module is used to divide the function call graph into separate function units and checker units according to the reverse order, and to traverse and calculate the function units and checker units in turn, completing the analysis after the complete traversal is completed.
[0064] Furthermore, the cache management module is used to store the intermediate results of this calculation through a stack for use by subsequent dependent calculations, and to look up the intermediate cache results that this calculation depends on.
[0065] Furthermore, the inspection calculation module is used to determine whether the defect conditions are met based on the execution information of all relevant statements in the cached query. If they are met, a defect result is generated.
[0066] Furthermore, the ordered traversal module includes a function analysis unit and a checker analysis unit;
[0067] Among them, the function analysis unit is used to divide the functions in the function call graph into multiple separate function units. Each function unit's branch is a separate execution path, which is traversed in depth-first order. The analysis of the function unit is completed when the traversed branch path is completed.
[0068] Checker Analysis Unit: This unit is used to break down all checkers in the function call graph according to their functions, and implement them as units organized by function. The sorting preparation module is repeatedly executed for the functions implemented by each checker unit to obtain the function call graph of all checker units and the checker function list with dependency order in sequence. Then, the checkers are used to analyze and calculate the program functions in the order of dependency.
[0069] Another embodiment of the present invention relates to a computer-readable storage medium having a computer program stored thereon, which, when executed by a processor, implements the steps of the static analysis method.
[0070] The computer program includes computer program code, which can be in the form of source code, object code, executable file, or some intermediate form. The computer-readable medium can include: any entity or device capable of carrying the computer program code, recording media, USB flash drive, portable hard drive, magnetic disk, optical disk, computer memory, read-only memory (ROM), random access memory (RAM), electrical carrier signals, telecommunication signals, and software distribution media, etc. It should be noted that the content included in the computer-readable medium can be appropriately added or removed according to the requirements of legislation and patent practice in the jurisdiction. For example, in some jurisdictions, according to legislation and patent practice, computer-readable media do not include electrical carrier signals and telecommunication signals.
[0071] Another embodiment of the present invention relates to a terminal device, including a memory and a processor, wherein the memory stores a computer program, and the processor executes the computer program to implement the steps of the static analysis method.
[0072] The above description is merely a preferred embodiment of the present invention. It should be understood that the present invention is not limited to the forms disclosed herein and should not be construed as excluding other embodiments. It can be used in various other combinations, modifications, and environments, and can be altered within the scope of the concept described herein through the above teachings or related technologies or knowledge. Modifications and variations made by those skilled in the art that do not depart from the spirit and scope of the present invention should be within the protection scope of the appended claims.
Claims
1. An ordered, enhanced, cacheable symbolic execution static analysis method, characterized in that: The static analysis method includes: S1. Abstract each function call point in the program code into a node caller, a node callee, and a directed edge from the caller to the callee. Set the call nodes and call edges of the entire program into the function call graph of this program. S2. Perform a topological sort on the function call graph to obtain a list in reverse order of function dependencies; S3. Divide the function call graph into separate function units and checker units according to the reverse order, and traverse and calculate the function units and checker units in turn. Complete the analysis after the complete traversal is completed. S4. Store the intermediate results of this calculation in the stack for use in subsequent dependent calculations, and at the same time look up the intermediate cached results that this calculation depends on. S5. Based on the relevant statement numbers and statement execution information of the cached query, determine whether the defect conditions are met based on the execution information of each statement. If they are met, a defect result is generated. The S3 step specifically includes: The functions in the function call graph are divided into multiple separate function units. Each function unit's branch is a separate execution path. The branch path that has been traversed is the complete analysis of the function unit. All checkers in the function call graph are broken down according to their functions and implemented as units organized by function. Steps S1 and S2 are repeated for the functions implemented by each checker unit to obtain the function call graph of all checker units and the list of checker functions with dependency order. The program functions are then analyzed and calculated by the checkers in the order of dependency. A function unit can be divided into two parts: the calculation part and the control part. The calculation part is for data calculation, and the control part is for the control conditions of the calculation branch process. Different control conditions for the execution of a function result in different calculation execution processes. The data is simulated and calculated to obtain the complete possible execution path and execution result of the function. The branch selection is a tree structure, meaning that each time a branch is switched, only the last branch is switched, and the calculation results of the previous branches are not affected and can be reused. The calculation results of the previous branches are cached in a stack manner for reuse by branches on the subsequent reachable path. Each function yields the following results through simulation: Execute branch 1 + the set of constraints on branch 1 + the set of calculation results for branch 1; Execute branch 2 + the set of constraints on branch 2 + the set of calculation results for branch 2; Execute branch 3 + the set of constraints on branch 3 + the set of calculation results for branch 3; For each complete branch path, calculate the constraint conditions of the constraint condition set on this branch to determine whether the path is reachable and under what constraint conditions it is reachable.
2. The ordered, enhanced, cacheable symbolic execution static analysis method according to claim 1, characterized in that: The inspector includes a base layer and a logic layer. The base layer is used for basic information extraction and can be reused in other inspectors. The logic layer is used to complete the business logic for specific defects based on the business logic of using freed memory.
3. The ordered, enhanced, cacheable symbolic execution static analysis method according to claim 1, characterized in that: The stack storage includes: when the simulated execution reaches a conditional branch, a new stack frame is created for each branch condition, and the intermediate information contained in the subsequent branch condition is stored in the stack frame. When the current branch condition is completed, the stack frame of the branch condition is popped, and the stack frame of other branch conditions is switched. This process is repeated, and the set of stack frames in the stack is the complete information when the branch condition is reachable.
4. The ordered, enhanced, cacheable symbolic execution static analysis method according to claim 1, characterized in that: The defect conditions are abstractions of the program semantics based on the content of the checker, represented as a set of constraint condition symbols in mathematical logic. Finally, constraint solving is used to judge this set of constraint conditions. Constraint solving mainly solves the defect conditions and branch conditions in the chassis. Constraints are set in advance in the branching stage to reduce the calculation of unreachable branches, or the branch conditions are calculated in the final defect generation stage to reduce the amount of calculation of branch conditions.
5. An ordered, enhanced, cacheable symbolic execution static analysis system, characterized in that: It includes a sorting preparation module, an ordered traversal module, a cache management module, and an inspection and calculation module; The sorting preparation module is used to abstract each function call point in the program code into a node caller, a node callee, and a directed edge from the caller to the callee. The call nodes and call edges of the whole program are set into the function call graph of this program. The function call graph is topologically sorted to obtain a list in reverse order of function dependencies. The ordered traversal module is used to divide the function call graph into separate function units and checker units according to the reverse order, and to traverse and calculate the function units and checker units in sequence. The analysis is completed after the complete traversal is finished. The cache management module is used to store the intermediate results of this calculation through a stack for use by subsequent dependent calculations, and to look up the intermediate cache results that this calculation depends on. The inspection calculation module is used to determine whether the defect conditions are met based on the cached query's all relevant statement numbers and statement execution information, and if they are met, a defect result is generated. The ordered traversal module includes a function analysis unit and a checker analysis unit; The function analysis unit is used to divide the functions in the function call graph into multiple separate function units. Each function unit's branch is a separate execution path, which is traversed in a depth-first order. The analysis of the function unit is completed when the traversed branch path is completed. A function unit can be divided into two parts: the calculation part and the control part. The calculation part is for data calculation, and the control part is for the control conditions of the calculation branch process. Different control conditions for the execution of a function result in different calculation execution processes. The data is simulated and calculated to obtain the complete possible execution path and execution result of the function. All checkers in the function call graph are broken down according to their functions and implemented as units organized by function. The contents of the sorting preparation module are repeatedly executed for the functions implemented by each checker unit to obtain the function call graph of all checker units and the list of checker functions with dependency order. The program functions are then analyzed and calculated by the checkers in the order of dependency. The branch selection is a tree structure, meaning that each time a branch is switched, only the last branch is switched, and the calculation results of the previous branches are not affected and can be reused. The calculation results of the previous branches are cached in a stack manner for reuse by branches on the subsequent reachable path. Each function yields the following results through simulation: Execute branch 1 + the set of constraints on branch 1 + the set of calculation results for branch 1; Execute branch 2 + the set of constraints on branch 2 + the set of calculation results for branch 2; Execute branch 3 + the set of constraints on branch 3 + the set of calculation results for branch 3; For each complete branch path, calculate the constraint conditions of the constraint condition set on this branch to determine whether the path is reachable and under what constraint conditions it is reachable. The inspector analysis unit is used to split all inspectors in the function call graph according to their functions, and implement them as units organized by function. The sorting preparation module is repeatedly executed for the functions implemented by each inspector unit to obtain the function call graph of all inspector units and the list of inspector functions with dependency order in sequence. Then, the inspectors are used to analyze and calculate the program functions in the order of dependency.
6. A computer-readable storage medium having a computer program stored thereon, characterized in that: When the computer program is executed by the processor, it implements the steps of the static analysis method according to any one of claims 1-4.
7. A terminal device, comprising a memory and a processor, wherein the memory stores a computer program, characterized in that: When the processor executes the computer program, it implements the steps of the static analysis method according to any one of claims 1-4.
Citation Information
Patent Citations
A detection method, system and device using the released memory and a storage medium
CN109426723A