A method for verifying complex software source code based on model detection
By using modularization and stub function replacement, the verification challenge of complex software modules was solved, improving the efficiency and accuracy of model detection and ensuring the security and functional correctness of complex software.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- ZHEJIANG UNIV
- Filing Date
- 2024-01-04
- Publication Date
- 2026-06-12
AI Technical Summary
Existing model detection technologies struggle to effectively handle complex software modules, especially macros, files, function pointers, system calls, and cross-module communication, resulting in low efficiency and insufficient accuracy in security detection of complex software.
The software source code is divided into a module partitioning method, namely, a module to be verified, an input module, a called module, and an output module. Complex interfaces and functions are replaced with stub functions, and verification is performed using a model checking tool. Assertions are written to ensure the correctness and security of the output.
It improves the efficiency and accuracy of complex software source code verification, can cover more input scenarios, reduces the impact of insecure code, and enhances the automation of model detection.
Smart Images

Figure CN117785716B_ABST
Abstract
Description
Technical Field
[0001] This invention belongs to the field of computer software source code verification, especially for model detection of complex software written in C language, and particularly relates to a method for verifying complex software source code based on model detection. Background Technology
[0002] For a long time, software security and functional correctness have been guaranteed by software testing. The typical software testing process is: construct test cases, then call the function or method under test, and finally verify the results. The target under test can be called a module, which can give specific outputs for specific inputs. However, constructing test cases can only cover a portion of the inputs, especially when the number of input parameters increases, the number of possible inputs expands rapidly, and the number of inputs that software testing can cover becomes even more negligible.
[0003] Model checking transforms program source code into formulas, then uses a formula parser to prove the correctness of the formulas. Model checking's unique feature of non-deterministic variables can cover all inputs. Furthermore, compared to other formal verification techniques, model checking offers a higher degree of automation. However, model checking cannot handle infinite loops. Bounded model checking verifies the correctness of the module under test within a finite number of loop iterations by setting an upper bound. As long as the actual number of loop iterations does not exceed the set upper bound, the module under test can be considered completely correct. Sometimes, extreme inputs can cause the number of loop iterations to exceed the set upper bound, in which case the completeness of the verification cannot be guaranteed, although the number of inputs covered is still far greater than in software testing.
[0004] Most model checking tools only provide simple precondition and postcondition primitives. For modules with relatively simple structures, the preconditions and postconditions can be written relatively intuitively to complete the verification. However, for modules with more complex structures, the number of inputs and outputs is large and the forms are more diverse. Verifying these modules requires writing a lot of verification code and fine-grained configuration of the verification tools. Therefore, it is necessary to design a standard model checking process for complex software modules to increase the efficiency and accuracy of the verification work. Summary of the Invention
[0005] Current model checking and verification engineering largely focuses on writing simple preconditions and postconditions to verify simple modules. However, there are no standardized methods for handling macros, files, function pointers, system calls, cross-module calls, and cross-module communication within software modules. Furthermore, the security of complex software can currently only be guaranteed through software testing, but even after testing, the software may still have numerous defects. To address these issues, this invention proposes a model checking-based method for verifying the source code of complex software. This method introduces model checking technology into the security testing of large-scale software, providing a new and safer option for testing complex software.
[0006] This application provides a method for verifying complex software source code based on model detection. It is implemented using a complex software source code verification system, which includes a module to be verified, an input module, a called module, and an output module.
[0007] (1) Preprocess the software source code in the module to be verified;
[0008] (2) Formalize the input module and the called module, and construct the stub functions in the output module and the called module;
[0009] (3) Filter the input module, including invalid input and input that will cause excessive loop count;
[0010] (4) Input the processed content from the input module into the module to be verified;
[0011] (5) Write assertions for the output module;
[0012] (6) Use a model checking tool to verify the preprocessed software source code and the code written in steps (2)-(5);
[0013] (7) Analyze the verification results in step (6).
[0014] Furthermore, the inputs in the input module include:
[0015] Data-type parameters are passed as parameters to the module to be verified when calling the interface.
[0016] The data file is transmitted by passing the file path to the module to be verified when calling the interface. The module to be verified needs to read the contents of the file according to the path.
[0017] The configuration file is used to modify the behavior of the module to be verified. It is passed to the module to be verified by passing the file path when calling the interface. The module to be verified needs to read the contents of the file according to the path.
[0018] Macro files are used to modify the behavior of the module to be verified, and are passed by including them through the include preprocessor directive.
[0019] The function pointer is passed as a parameter to the module to be verified when calling the interface.
[0020] Control parameters are used to control the behavior of the module to be verified. They are passed as parameters to the module to be verified when calling the interface.
[0021] Data parameters and data files are data inputs, while configuration files, macro files, function pointers, and control parameters are control inputs.
[0022] Furthermore, the called module includes interfaces to other modules and stub functions:
[0023] The other module interfaces are services that directly call other software modules without using stub functions;
[0024] The stub function is used to abstract the service interfaces of other software modules in the software source code and describe their functions using the language of model checking.
[0025] Furthermore, the output module is used to reflect the processing result of the module to be verified for a certain input, including the directly returned result, the modification of the state, and the call to other modules:
[0026] Return values mainly include directly obtained interface return values, or modifications made to the pointer content by the module to be verified after passing the pointer as a parameter;
[0027] Modifications to static and global variables are obtained indirectly by using an interface to verify the output of this section, while modifications to global variables are obtained by reading the global variables.
[0028] The stub function is used to record call information and functional simulation.
[0029] Further, step (1) specifically involves combining the macro files and configuration files in the software source code to obtain several configurations.
[0030] Further, in step (2), the formal input module includes:
[0031] Determine whether all configurations need to be verified;
[0032] If all configurations need to be verified, a script is used to generate configuration files / macros; otherwise, specific configuration files / macros are written according to requirements.
[0033] Set control parameters and data parameters to undefined;
[0034] Set the data file, configuration file, and function pointer as deterministic parameters.
[0035] Furthermore, in step (3), control parameters and data parameters with restricted values are filtered. Control parameters need to be ensured to have valid configuration values, while data parameters are filtered according to restrictions.
[0036] Furthermore, in step (7), the failed assertions are analyzed, wherein:
[0037] For the failure of functional assertion, it is necessary to check the correctness of the software source code and the code written in steps (2)-(5). If there is no error, it proves that there is a defect in the software source code.
[0038] The failure of a security assertion proves that there is a security flaw in the software source code.
[0039] The technical solutions provided by the embodiments of this application may include the following beneficial effects:
[0040] A modular approach was adopted, dividing the various elements in the software source code into modules, which made the structure of the entire verification project clearer and facilitated the formulation and implementation of the verification plan.
[0041] For file processing, stub functions were written to replace the write and read system calls, which solved the problem that the model checking tool could not directly read files and allowed verifiers to freely control the content of the files and return different results for different file names.
[0042] For cases where the module to be verified ultimately outputs its output through an interface or a passed function pointer, a stub function is written to retrieve the parameter content, replacing the corresponding interface and function pointer to obtain the output of the module to be verified. After obtaining the output, corresponding postconditions are written for the output. This solves the problem of difficulty in obtaining such outputs during model detection.
[0043] For calls made by the module to be verified to other modules, the "descriptive stub function" method is adopted, which only simulates the external behavior of the called interface and removes the specific functions, thereby improving the verification efficiency and eliminating the impact of unsafe code in the called interface on the module to be verified.
[0044] It should be understood that the above general description and the following detailed description are exemplary and explanatory only, and do not limit this application. Attached Figure Description
[0045] The accompanying drawings, which are incorporated in and form part of this specification, illustrate embodiments consistent with this application and, together with the description, serve to explain the principles of this application.
[0046] Figure 1 This is a schematic diagram of a complex software source code verification system according to an exemplary embodiment.
[0047] Figure 2 This is a flowchart illustrating a complex software source code verification method based on model detection, according to an exemplary embodiment.
[0048] Figure 3 This is a flowchart illustrating a formal input module according to an exemplary embodiment. Detailed Implementation
[0049] Exemplary embodiments will now be described in detail, examples of which are illustrated in the accompanying drawings. When the following description relates to the drawings, unless otherwise indicated, the same numbers in different drawings represent the same or similar elements. The embodiments described in the following exemplary embodiments do not represent all embodiments consistent with this application.
[0050] The terminology used in this application is for the purpose of describing particular embodiments only and is not intended to be limiting of the application. The singular forms “a,” “the,” and “the” used in this application and the appended claims are also intended to include the plural forms unless the context clearly indicates otherwise. It should also be understood that the term “and / or” as used herein refers to and includes any or all possible combinations of one or more of the associated listed items.
[0051] It should be understood that although the terms first, second, third, etc., may be used in this application to describe various information, such information should not be limited to these terms. These terms are only used to distinguish information of the same type from one another. For example, without departing from the scope of this application, first information may also be referred to as second information, and similarly, second information may also be referred to as first information. Depending on the context, the word "if" as used herein may be interpreted as "when," "when," or "in response to determination."
[0052] This application provides a method for verifying complex software source code based on model detection. This method is based on... Figure 1 The diagram illustrates an implementation of a complex software source code verification system. The system includes a module to be verified, an input module, a called module, and an output module. Except for the module to be verified, all other modules can be empty. The absence of any part of any other module, except for the module to be verified, will not affect the operation of the verification method. For example, if the module does not use a configuration file, the 'configuration file' part in the input module can be omitted.
[0053] It should be noted that, in this application, "complex software" refers to software with a complex implementation method. The complexity of the implementation method includes the use of many high-level language features, the use of complex configuration files, and frequent interaction with the operating system.
[0054] The set of all possible inputs in the input module is the input space. This application needs to verify (1) functional correctness: for any input in the input space, after inputting it into the module to be verified, the output generated is as expected; (2) security: for any input in the input space, after inputting it into the module to be verified, no security exception will be generated during the execution process. Security exceptions include, but are not limited to, pointer exceptions, memory exceptions, division by zero errors and computational overflow.
[0055] For modules to be verified, they should expose some interfaces that users can call to access the services provided by the module. This method should cover all interfaces and verify the functionality and security of each interface.
[0056] The inputs in the input module can be divided into two main categories: (1) Data input: The module to be verified treats this type of input as data. From the result, this input will not affect the behavior of the module to be verified, but it will affect the output of the module to be verified; (2) Control input: This type of input can affect the behavior of the module to be verified, and it can also affect the output of the module to be verified. In fact, the input type is not a precise definition, but a classification of the various parts in the input module, so as to process the two types of input separately in the future. Control input is a definite value, and data input is an indeterminate value. The specific value is a definite literal value or a set of literal values. Indeterminate value is a value type unique to model detection. When a variable in the code is not assigned a value, the model detection tool will consider it to be indeterminate, and will verify all possible values of indeterminate value during the verification process. The inputs in the input module specifically include:
[0057] 1. Data-type parameters are passed as parameters to the module to be verified when calling the interface. Most parameters belong to this category, which is considered data-type input.
[0058] 2. Data files are passed by passing the file path to the module to be verified when calling the interface. The module to be verified needs to read the contents of the file according to the path. Text files, Word documents and Excel spreadsheets mostly belong to this part. This part belongs to data input.
[0059] 3. Configuration files are passed in the same way as data files, but the purpose of these files is to modify the behavior of the module to be verified. XML, JSON and some custom configuration files mostly belong to this part, which is a control input.
[0060] 4. Macro files: This part of the input is not passed directly through the interface, but is introduced through the include preprocessor directive. This part can change the behavior of the module to be verified in a variety of ways, such as changing the size of the buffer through macro definitions, or directly changing the source code of the module to be verified through preprocessor directives such as ifdef. This part belongs to control input.
[0061] 5. Function pointers are passed as parameters to the module being verified when calling the interface. This part is special because the function pointer must be taken from an actual existing function and cannot be undefined. The handling of function pointers differs from that of ordinary parameters; therefore, function pointers are treated as a separate section. This part belongs to control input.
[0062] 6. Control parameters are passed in the same way as data parameters, but their purpose is to control the behavior of the module to be verified. For example, most bit flags belong to this category. Additionally, if command mode is used, the command is passed to the module to be verified as a string; this command string also belongs to control parameters. This part belongs to control input.
[0063] The called module includes interfaces to other modules and stub functions:
[0064] Other module interfaces, that is, directly calling the services of other software modules without using stub functions, have two disadvantages: first, the correctness of other modules cannot be guaranteed; second, it increases the amount of code to be verified and reduces the efficiency of the verification project.
[0065] Stub functions are abstractions of the service interfaces of other software modules in the source code, describing their functionality using the language of model checking. The purpose of abstraction can be to achieve isolation between verification modules, increase the efficiency of verification projects, and meet some special verification project requirements. During the verification process, if a stub function is written for a certain function, the model checking tool will replace the source code of that function with the stub function.
[0066] In practice, there should be as many stub functions as possible, and as few other module interfaces as possible.
[0067] The output module is used to reflect the processing result of the module to be verified for a certain input, mainly manifested as the directly returned result, the modification of the state, and the call to other modules, specifically including:
[0068] 1. Return values mainly include directly obtained interface return values, or modifications made to the pointer content by the module to be verified after passing a pointer as a parameter. In complex software modules, the return values of interfaces mostly represent the execution status of the interface, rather than directly reflecting the output of this call. Modifications to pointer parameters mostly occur in intermediate-level modules for data structure transformation, and are less common in top-level modules; this part belongs to the directly returned results.
[0069] 2. Modifications to static variables are not visible to the outside world, so an interface is needed to indirectly verify the output of this part. This part belongs to the modification of state.
[0070] 3. Modification of global variables: This part can be modified directly by reading the global variables. However, directly modifying global variables does not conform to software design principles, so it is relatively rare. This part belongs to the modification of state;
[0071] 4. Receive stub functions: This is the most important part of the input / output module. Its main functions include recording call information and simulating functionality. Most modules' output behavior manifests as calls to submodules, other modules, and the operating system. Therefore, stub functions need to be written to obtain the parameters used by the module under test when calling other modules, thereby verifying its functional correctness. For example, if the module under test ultimately uses the network to send its processing results, a stub function needs to be written to replace the operating system's network interface and check the sent content. Additionally, some output manifests as file writing, but this type also falls under the category of calling the operating system. A stub function can be used to override the operating system's file writing interface; this part belongs to calls to other modules.
[0072] Based on the above system, such as Figure 2 As shown, this method specifically includes the following steps:
[0073] (1) Preprocess the software source code in the module to be verified;
[0074] Specifically, the preprocessing part in step (1) includes macros and configuration files. Macros are written in header files and included by the module to be verified via the include preprocessing directive; in this application, such files are referred to as macro files. Furthermore, in this application, a specific set of macro files and configuration files is referred to as a configuration. The preprocessing part needs to ultimately obtain several configurations, and each configuration is verified once using the following steps, but no modification to the code of other modules is required when changing configurations. When there are too many configurations to be verified, a configuration generator is used to automatically generate configurations.
[0075] It's important to note that the configuration format (which configuration files are available and what configuration parameters each file contains) is determined by the software developers. For example, if a module accepts a header file and an XML file as configuration, then any set of header and XML files written according to the specified format can form a specific configuration. Different configurations may have the same format, but the values of the configuration parameters will differ.
[0076] (2) Formalize the input module and the called module, and construct the stub functions in the output module and the called module;
[0077] After the verification project is started, the initialization phase is carried out first. In this phase, the model detection language is used to describe all parts that were not preprocessed in step (1).
[0078] In this step, the processing of the input module, output module, and called module can be done in parallel.
[0079] Both the called module and the output module need to have stub functions written. Stub functions are only responsible for simulating the behavior of the real function and recording call information; they should not contain actual processing logic. The interface for obtaining call information should be exposed to other parts of the verification project. Furthermore, the scope of stub functions should be limited to functions that communicate with other modules or the operating system; stub functions should not be written for utility functions.
[0080] For stub functions of read type, they should implement corresponding deterministic and indeterminate versions to generate the appropriate version of data as needed. For indeterminate streaming data, both its content and length should be indeterminate. However, the source code of the module to be verified will not have parameters controlling the generation of deterministic or indeterminate data versions; therefore, specific data types should be generated within the stub function for different file descriptors or resource descriptors. Furthermore, stub functions of read type should record the generated content and expose the interface for retrieving the generated content to other parts of the verification project.
[0081] It's important to note that the formalization of the called module involves describing its functionality using stub functions and interfaces. For example, the module to be verified might call a string encryption function. This function's implementation could be very complex, or even flawed. However, the module to be verified only knows that this encryption function receives one string and returns another; it doesn't care what work it does. Therefore, during verification, it's unnecessary to use the original encryption function. Instead, a simple and secure stub function (e.g., directly returning the input string) should be written to replace it.
[0082] Figure 3 The detailed flow of the formal input module is shown below, including the following sub-steps:
[0083] S311: Determine whether all configurations need to be verified;
[0084] Specifically, a set of configuration files and macro files can constitute a configuration, and a verification method can only verify one configuration. Therefore, for different configurations, multiple verification methods need to be run, but there is no need to modify other parts of the verification method. Configuration processing can be divided into two types: (1) Verify the correctness of the module to be verified under all configurations to ensure the completeness of the verification. This method requires the automatic generation of all possible configurations through scripts, but the number of possible configurations will increase exponentially with the increase of configuration items, resulting in low verification efficiency. (2) Verify the correctness of the module to be verified under some configurations. In general, the module to be verified runs under one or several specific configurations, and verification can be performed only on these configurations to increase the efficiency of verification, but it will also lose coverage of other configurations.
[0085] S312: If all configurations need to be verified, use a script to generate configuration files / macros; otherwise, write specific configuration files / macros as needed.
[0086] Specifically, macros are difficult to handle because they cannot be set to indeterminate forms; therefore, they must be set to deterministic forms and tested multiple times. While configuration files can be set to indeterminate forms using stub functions, this is also cumbersome. However, both share the characteristic that the values of the configuration parameters do not change at runtime. This paper does not use model checking methods for configuration processing; instead, it uses a deterministic configuration during validation, similar to a regular call. If different configurations need to be validated, the configuration file must be modified and validation repeated. S312 discusses the process of writing configuration files; manual or script-based writing is acceptable, as long as a set of configuration files is ultimately obtained. However, if there are too many configurations to validate, scripts are preferable. The reason for this design, as mentioned in the first paragraph, is that configurations are difficult to set to indeterminate forms. Fortunately, the configuration is determined before program execution; therefore, we choose to "validate the correctness under multiple specific configurations" rather than "validate the correctness under all possible configurations."
[0087] It's important to note that the phrase "verifying the correctness of all configurations" actually covers all specific configurations. This is impossible in most cases. For example, if a macro has a `BUF_SIZE` to define the buffer size, considering all unsigned 32-bit integers, 4,294,967,296 configurations would need to be written. However, if the configuration only contains boolean values, such as `USE_BUFFER` to determine whether to use the buffer, then verifying all configurations is possible; however, the number of configurations required still increases exponentially with the number of configuration parameters.
[0088] S313: Set control parameters and data parameters to undefined;
[0089] S314: Set data files, configuration files, and function pointers as deterministic parameters;
[0090] Similar to a normal function call, no special processing is required; simply pass in the function pointer and the filename. However, the function pointer passed in is usually a pointer to a stub function, and the actual file processing is performed when reading the file content; no processing is needed when passing the filename.
[0091] The parameters in step S315 are all deterministic parameters, including data files, configuration files, and function pointers. Although data files and configuration files belong to data-type input and control-type input respectively, they are both file parameters and are passed in the same way, using filenames. For file type parameters, the module to be verified will eventually use a file system call (such as `read`) to read the file content by filename. For this scenario, a stub function for the corresponding system call must be written, and the module to be verified reads the file content through the stub function. To facilitate verification, the files used in the verification project can be compiled into a file library. The `read` stub function reads a specific string and length from the library by filename. The file content should also be divided into deterministic and indeterminate types. The length and value of each character in indeterminate files are both indeterminate, but the length should be limited according to the configuration. The configuration file should be a deterministic file, and its content comes from step S312. The content of the data file should be indeterminate.
[0092] Function pointer parameters can be divided into two types according to their purpose: one is to assist the work of the module to be verified, and the other is part of the output. The former requires the function pointer of the interface of the other module or the function pointer of the stub function to be passed in, and the latter requires the function pointer of the receiving stub function to be passed in.
[0093] For the receiving stub function, it mainly includes two parts: (1) Call information, which records the number of times the function is called and the parameters passed in each call. The call information should be recorded using variables and can be obtained by the verification project to check the output of the module to be verified. (2) Simulation function, where there is no need to write the actual processing logic, but to simulate some functions, such as using an undefined Boolean variable to simulate the failure of the function operation. This part is mainly used to provide specific return values to the module to be verified.
[0094] Stub functions only need to include the part that simulates the functionality.
[0095] No special processing is required for the other module interfaces. However, note that these interfaces are all source code, and stub functions should be written for them to make them stub functions.
[0096] Return values from the output module and modifications to global variables can be obtained and verified relatively directly. However, modifications to static variables require indirect access via other interfaces of the module being verified. There are also some static variables that are completely unavailable; the verification of these can be ignored. This is because the verification method is designed from the perspective of the module user. Static variables that are not exposed externally belong to the internal state of the module being verified. As long as all external interfaces pass verification, the functional correctness and security of the module being verified can be considered verified.
[0097] (3) Filter the input module, including invalid input and input that will cause excessive loop count;
[0098] The output obtained in step (2) needs to be filtered for two reasons: some interfaces have certain requirements for the output, such as range requirements for certain integer parameters, so invalid inputs need to be filtered out; since the efficiency of model detection will drop significantly when the number of loops increases, sometimes in order to verify the feasibility of the project, it is necessary to filter out some inputs that will cause too many loops.
[0099] Initially, both control parameters and data parameters are undefined. Control parameters and data parameters with restricted values need to be filtered. Control parameters need to be ensured to have valid configuration values, while data parameters are filtered according to the restrictions.
[0100] Filtering is mainly done in the preconditions. All source code model checking tools provide the `assume` primitive to declare the preconditions for verification. For example, if the module to be verified requires that a certain parameter `t` can only be a positive number when passing parameters, then `assume(t>0)` can be added to the preconditions to filter out negative numbers and 0.
[0101] Deterministic types can only cover one value; to cover multiple values, you must use indeterminate types. For example, `t=1` can only verify the correctness of `t` when `t` is 1. Correspondingly, to verify the correctness of `t` in the range (0, 100), you need to execute...
[0102] t = nondet_int();
[0103] assume(t>0);
[0104] assume(t<100);
[0105] The first line is for setting the undefined type, and the second and third lines are for filtering.
[0106] (4) Input the processed content from the input module into the module to be verified;
[0107] The module to be verified will call the service in the processed called module and input the result into the receiving stub function.
[0108] (5) Write assertions for the output module;
[0109] Assertions should be written according to the verification requirements, asserting that the output meets the expected properties. In addition, there are some assertions that are automatically generated by model checking tools, which do not need to be written manually.
[0110] It should be noted that steps (3) and (5) correspond to the preconditions and postconditions for the security and functional correctness of the module to be verified, respectively, and their writing should strictly follow the verification requirements.
[0111] (6) Use a model checking tool to verify the preprocessed software source code and the code written in steps (2)-(5);
[0112] Specifically, all the code written above, as well as the source code of the module to be verified, are input into a model checking tool for verification. Furthermore, the model checking tool needs to be configured specifically according to the verification requirements; special configurations may cause the model checking tool to generate additional assertions.
[0113] It should be noted that "configuring the model checking tool according to the verification requirements" means setting the model checking tool to be used according to the actual situation. For example, when using CBMC, it is necessary to set the upper bound of the loop unrolling, whether to detect array out-of-bounds errors, and whether to detect pointer errors, etc.
[0114] (7) Analyze the verification results in step (6);
[0115] Specifically, the verification results in step (6) are analyzed, with the analysis mainly focusing on failed assertions. For functional assertion failures, in addition to checking the source code, the correctness of the verification code also needs to be checked. The verification code is less numerous and complex than the source code, so it can be checked more quickly. After confirming that the verification code is accurate and that the source code does indeed contain the corresponding error, it proves that a defect has been found in this verification project, and the defect can be reported to the developer of the module to be verified. The failure of security assertions often proves that there is indeed a security defect in the source code, and it can be reported directly.
[0116] It should be noted that none of the above steps should involve modifying the software source code in the module to be verified.
[0117] Other embodiments of this application will readily occur to those skilled in the art upon consideration of the specification and practice of the disclosure herein. This application is intended to cover any variations, uses, or adaptations of this application that follow the general principles of this application and include common knowledge or customary techniques in the art not disclosed herein.
[0118] It should be understood that this application is not limited to the precise structure described above and shown in the accompanying drawings, and various modifications and changes can be made without departing from its scope.
Claims
1. A method for verifying complex software source code based on model detection, characterized in that, This is based on a complex software source code verification system, which includes a module to be verified, an input module, a called module, and an output module. The method includes: (1) Preprocess the software source code in the module to be verified; (2) Formalize the input module and the called module, and construct the stub functions in the output module and the called module; (3) Filter the input module. The filtered content includes invalid input and input that will cause too many loops. (4) Input the processed content from the input module into the module to be verified; (5) Write assertions for the output module; (6) Use a model checking tool to verify the preprocessed software source code and the code written in steps (2)-(5); (7) Analyze the verification results in step (6); The inputs in the input module include: Data-type parameters are passed as parameters to the module to be verified when calling the interface. The data file is transmitted by passing the file path to the module to be verified when calling the interface. The module to be verified needs to read the contents of the file according to the path. The configuration file is used to modify the behavior of the module to be verified. It is passed to the module to be verified by passing the file path when calling the interface. The module to be verified needs to read the contents of the file according to the path. Macro files are used to modify the behavior of the module to be verified, and are passed by including them through the include preprocessor directive. The function pointer is passed as a parameter to the module to be verified when calling the interface. Control parameters are used to control the behavior of the module to be verified. They are passed as parameters to the module to be verified when calling the interface. Data parameters and data files are data inputs, while configuration files, macro files, function pointers, and control parameters are control inputs. The output module is used to reflect the processing result of the module to be verified for a certain input, including the directly returned result, the modification of the state, and the call to other modules: Return values include directly obtained interface return values, or modifications made to the pointer content by the module to be verified after the pointer is passed as a parameter; Modifications to static and global variables are performed by indirectly verifying the corresponding output through an interface, and by reading the global variables. The stub function is used to record call information and functional simulation.
2. The method according to claim 1, characterized in that, The called module includes interfaces to other modules and stub functions: The other module interfaces are services that directly call other software modules without using stub functions; The stub function is used to abstract the service interfaces of other software modules in the software source code and describe their functions using the language of model checking.
3. The method according to claim 1, characterized in that, Step (1) specifically involves combining the macro files and configuration files in the software source code to obtain several configurations.
4. The method according to claim 1, characterized in that, In step (2), the formal input module includes: Determine whether all configurations need to be verified; If all configurations need to be verified, a script is used to generate configuration files / macros; otherwise, specific configuration files / macros are written according to requirements. Set control parameters and data parameters to undefined; Set the data file, configuration file, and function pointer as deterministic parameters.
5. The method according to claim 1, characterized in that, In step (3), control parameters and data parameters with restricted values are filtered. Control parameters need to be ensured to have valid configuration values, while data parameters are filtered according to restrictions.
6. The method according to claim 1, characterized in that, In step (7), the failed assertions are analyzed, including: For the failure of functional assertion, it is necessary to check the correctness of the software source code and the code written in steps (2)-(5). If there is no error, it proves that there is a defect in the software source code. The failure of a security assertion proves that there is a security flaw in the software source code.