Memory security vulnerability fuzzy testing method combined with dynamic analysis

By using dynamic analysis tools to detect memory security vulnerabilities in fuzz testing, the problem of invalid performance loss and coverage information in the existing technology is solved, and efficient memory security vulnerability detection and fuzz testing performance improvement is achieved.

CN119473869AActive Publication Date: 2025-02-18NANJING UNIV OF AERONAUTICS & ASTRONAUTICS

Patent Information

Application Number
CN202411372498.4
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2024-09-29
Publication Date
2025-02-18
Estimated Expiration
2044-09-29

AI Technical Summary

Technical Problem

In the prior art, when using dynamic analysis tools to assist in coverage-guided fuzz testing, there are problems such as performance loss, invalid coverage information and difficulty in effectively discovering memory security errors.

Method used

By inserting type definitions and function definitions for dynamic analysis in the source code of the program to be tested, traversing the abstract syntax tree for instrumentation, maintaining shared memory variables with minimum pointer boundary distance and memory allocation peaks, and using these in fuzzy tests Information is used as feedback to guide the generation of test cases.

Benefits of technology

Reduces memory management time-consuming, improves the running performance of fuzz testing, ensures the accuracy of coverage information, and effectively detects memory security errors.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN119473869A_ABST
    Figure CN119473869A_ABST
Patent Text Reader

Abstract

The invention discloses a dynamic analysis-combined memory security vulnerability fuzzy test method. The method comprises the following steps of inserting pointer metadata for dynamic analysis into a source code file of a to-be-tested program, performing memory security detection, and performing related type definition and function definition of a memory allocation packaging function; analyzing the source code by using a compiler, generating an abstract syntax tree, traversing the abstract syntax tree, performing instrumentation on nodes of the abstract syntax tree, and maintaining a shared memory variable of a minimum pointer boundary distance and a memory allocation peak value; compiling the source code after instrumentation to obtain an assembly code; performing coverage rate instrumentation on the assembly code, and skipping the previously inserted code for dynamic analysis; assembling and linking the instrumented assembly codes to obtain an executable file; performing fuzzy testing on the executable file; and running the fuzzy test to output a program input file which enables the target program to have a memory security error. According to the method, memory vulnerabilities in the target program can be found, and the error detection capability of fuzzy testing is improved.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the field of computer software technology, and in particular to a memory security vulnerability fuzz testing method combined with dynamic analysis. Background Art

[0002] C language is widely used in the development of embedded software and system software. It has the ability to control the underlying memory. However, due to the lack of detection of the legitimacy of memory access, C programs are prone to memory safety errors during operation. In the CVE (Common Vulnerabilities and Exposures) report, common memory safety errors include buffer overflow, pointer use after free, repeated pointer release, and memory leak, and memory safety errors are currently one of the most dangerous software errors in the CVE report.

[0003] Nowadays, more and more technologies are focusing on detecting the memory security of software systems. Dynamic analysis technology refers to extracting and analyzing the state information in the program while the target program is running. This information can be pointer values, pointer safety upper and lower bounds, memory allocation size, etc. By checking whether this information meets the memory safety conditions during the program running, memory security vulnerabilities can be detected.

[0004] Fuzz testing is a software testing technology that mutates the automatically or semi-automatically generated program input at the bit level, provides the mutated program input as a parameter to the target program for multiple runs, monitors the program status during the program running, and finally outputs a test case that can cause the program to crash. Testers locate program vulnerabilities by analyzing the test case that causes the program to crash and the context state when the program crashes.

[0005] Combining dynamic analysis technology with fuzz testing can generate program inputs that trigger memory vulnerabilities. Dynamic analysis technology can report memory safety errors that do not cause program crashes as program exceptions, assisting fuzz testing tools in generating corresponding test cases. At the same time, coverage-guided fuzz testing tools generate test cases with higher program coverage as much as possible, which can improve the deficiency of dynamic analysis technology that relies on program input.

[0006] However, when using existing dynamic analysis tools to assist coverage-guided fuzz testing, there will be serious performance loss due to the increase in memory management time. Fuzz testing tools will perform coverage stubs on the additional code generated by dynamic analysis tools, resulting in invalid coverage information. In addition, blindly improving the code coverage of test cases cannot effectively discover memory safety errors in the program.

[0007] The main problems existing in the prior art are analyzed below:

[0008] 1) The shadow space used by dynamic analysis tools causes serious performance loss

[0009] Existing dynamic analysis tools use a large volume of virtual memory as the shadow space to store pointer metadata, which is offset from the memory space of the original program. During the initialization of the original program, the red zone is used to mark the entire shadow space to indicate the memory availability status. Therefore, when combined with the thread forking server mode of fuzz testing, a large number of page faults will be generated, which will increase the time consumption of memory management and seriously reduce the running performance of fuzz testing.

[0010] 2) The code inserted by the dynamic analysis tool leads to invalid coverage information

[0011] Existing dynamic analysis tools need to perform code stubs on the original program to detect memory errors, which will generate new functions and branch jumps that are unrelated to the original program logic. Coverage-guided fuzz testing will perform coverage stubs on these new functions and branch jumps, generating invalid coverage information, which has a serious negative impact on exploring new branch code paths.

[0012] 3) The code coverage guidance used by fuzz testing tools is not good at discovering memory errors

[0013] Existing coverage-guided fuzz testing blindly explores new program execution paths without considering how to efficiently trigger memory safety errors in the code. Therefore, fuzz testing requires additional information guidance in the process of collecting and mutating test cases. Summary of the invention

[0014] Purpose of the invention: The purpose of the present invention is to provide a memory security vulnerability fuzz testing method combined with dynamic analysis, so as to efficiently discover memory vulnerabilities in the target program and improve the error detection capability and operating performance of the fuzz test.

[0015] Technical solution: A memory safety vulnerability fuzz testing method combined with dynamic analysis, including the following steps:

[0016] S1, open the source code file of the program to be tested, and insert the source code of type definition and function definition for dynamic analysis into the source code file;

[0017] S2, using a compiler to preprocess the source code of the program to be tested, and then using the compiler to parse the source code of the program to be tested;

[0018] S3, traverses the abstract syntax tree and instruments its nodes to detect memory errors while the program is running, and maintains shared memory variables with minimum pointer boundary distance and memory allocation peak;

[0019] S4, compile the source code after the stub to obtain the assembly code;

[0020] S5, perform coverage instrumentation on the assembly code and skip the previously inserted code for dynamic analysis;

[0021] S6, assemble and link the assembly code after the stub to obtain an executable file,

[0022] S7, performs fuzz testing on the executable file, using the coverage, minimum pointer boundary distance, and memory allocation peak provided by dynamic analysis as feedback information to guide the fuzz testing;

[0023] S8, runs the fuzz test and outputs a program input file that causes a memory safety error in the target program.

[0024] Further, in step S1, source code for type definition and function definition for dynamic analysis is inserted, including the following steps:

[0025] S11, inserting the type definition of pointer metadata, the structure type of the pointer metadata includes: the first address and the last address of the memory space pointed to by the pointer variable, the address of the pointer variable, and the state of the memory space;

[0026] S12, insert the type definition of the data structure for maintaining pointer metadata, the data structure includes a hash table and a secondary tree, both of which use the address value of the pointer variable as the index value; in the secondary tree, the 26th to 48th bits starting from the low bit of the index value are used as the primary index value, and the 4th to 25th bits are used as the secondary index value; the initial capacities of the primary table and the secondary table are 2^23 and 2^22 respectively, each element in the primary table is a pointer to the secondary table, and each element in the secondary table is a pointer to the pointer metadata;

[0027] S13, inserting the function definition for maintaining pointer metadata. When creating a pointer variable during program execution, inserting the pointer metadata into the hash table or the secondary tree, and dynamically expanding the capacity when the capacity is insufficient;

[0028] S14, insert the memory safety detection function definition, update the difference between the current pointer value and the legal first address of the corresponding pointer metadata, and the difference between the pointer value and the legal last address of the corresponding pointer metadata, and retain the smallest difference as the minimum pointer boundary distance, which is used to judge whether there is a tendency for the pointer to cross the boundary;

[0029] S15, inserting the wrapper function definition of the memory allocation library function. After the wrapper function executes the memory allocation library function, it is determined whether the execution is successful according to the function return value: if successful, the total value of the memory allocated when the program runs to this point is updated, and the global memory allocation peak value is updated with the total value of the allocated memory to judge whether there is a tendency to allocate too much memory, and finally the return value of the memory allocation library function is returned; if unsuccessful, no operation is performed.

[0030] Furthermore, the specific processing logic for storing pointer metadata is as follows:

[0031] In hash table mode, the pointer variable address value is used as the index value, and the chain address method is used to handle conflicts. When the number of table elements reaches more than three times the number of buckets, the number of buckets is expanded to two times;

[0032] In the two-level tree mode, the 26th to 48th bits of the low-order pointer variable address value are used as the primary index value, and the 4th to 25th bits are used as the secondary index value. When the secondary table corresponding to the primary index value is missing, the secondary table is created and the pointer metadata is inserted into the secondary table.

[0033] Further, in step S3, traversing the abstract syntax tree and inserting its nodes includes the following steps:

[0034] S31, inserting a stub at the main function entry of the program to obtain the shared memory of the fuzz test and establish inter-process communication with the fuzz test;

[0035] S32, inserting the definition and initialization statements of the pointer variable to create pointer metadata and inserting the pointer metadata into a hash table or a secondary tree;

[0036] S33, inserting pointer dereference, array subscript access, and member access statements of structure pointer variables to detect memory errors, and updating the minimum difference between the pointer value and the legal first address of the pointer metadata, and the minimum difference between the pointer value and the legal last address of the pointer metadata, and storing the minimum difference as the minimum pointer boundary distance in the shared memory variable of the fuzz test;

[0037] S34, insert the function call statements of memory allocation and memory release, replace them with the calls of corresponding wrapper functions, which are used to maintain the pointer metadata of heap type pointer variables, and update the current maximum allocated memory value, and store the maximum memory value as the memory allocation peak value in the shared memory variable of the fuzz test.

[0038] Further, in step S5, the previously inserted code for dynamic analysis is skipped, the code including pointer metadata operation function, common wrapper function, and inline wrapper library function; the steps are as follows:

[0039] S51, skip the insertion of the pointer metadata operation function, by identifying the function name prefix of the inserted pointer metadata operation function and the .LFE in the assembly code that represents the end of the function body. <num>Flag to skip coverage instrumentation for the code between the function name and the end flag;

[0040] S52, skipping the stubbing of the common wrapper function; the common wrapper function passes the pointer type function return value and the pointer metadata of the function parameter to the original function, which is used for the original function to perform a memory safety check during the execution process. After the transfer is completed, the original function is called to obtain the return value, and then the return value of the original function is returned;

[0041] S53, skipping the stubbing of the inline wrapper library function; by identifying whether the source of the inline code block belongs to the source file for dynamic analysis, skipping the coverage stubbing of the inline code block of the source file for dynamic analysis.

[0042] Further, in step S7, the coverage, minimum pointer boundary distance, and memory allocation peak value provided by the dynamic analysis are used as feedback information to guide the fuzz test, including the following steps:

[0043] S71, collect test cases and add them to the seed queue: First, based on the coverage information provided by the fuzz test, determine whether a new program execution path is found during the program running process:

[0044] If there is a new program execution path, the test case is directly added to the seed queue;

[0045] If there is no new program execution path, determine whether there are several pointers closer to the legal upper and lower bounds of its pointer metadata during this run, and whether there is a higher memory allocation peak during this run: if there are several pointers closer to the legal upper and lower bounds of its pointer metadata, or a higher memory allocation peak is generated, add the test case to the seed queue; if there are no several pointers closer to the legal upper and lower bounds of its pointer metadata, and no higher memory allocation peak is generated, discard the test case;

[0046] S72, streamlining the seed queue: if the test case can be added to the seed queue after judging the coverage, minimum pointer boundary distance, and memory allocation peak indicators, then replace the test case in the seed queue with a test case that has the same execution path as the current test case and has a larger minimum pointer boundary distance or a lower memory allocation peak;

[0047] S73, evaluate the seeds in the seed queue: use the execution consumption time, file size, minimum pointer boundary distance, and memory allocation peak to calculate the seed excellence, retain the excellent seeds in the seed queue, and further streamline the seed queue for subsequent mutation.

[0048] Compared with the prior art, the present invention has the following significant effects:

[0049] 1. The present invention uses a dynamically expanded hash table and a tree data structure to store pointer metadata. Only when the program runs to the pointer creation part will the heap memory be applied to store the pointer metadata. Only when the program runs to the pointer operation part will the pointer metadata be accessed, thereby reducing the time consumption of memory management and improving the running performance of fuzzy testing.

[0050] 2. The present invention identifies the code inserted by the dynamic analysis tool during the coverage plugging stage, and does not perform coverage plugging on it, thereby ensuring accurate original program coverage information;

[0051] 3. The present invention collects program inputs that cause pointers in the program to get closer and closer to their legal upper and lower bounds and allocate larger and larger memory values ​​as value seeds, and simplifies and mutates the seed queue and repeats the above operations, thereby efficiently detecting memory errors. Since dynamic analysis tools have the ability to analyze the runtime state of programs, these memory safety-related information can be collected as guidance information for fuzz testing;

[0052] 4. The present invention uses the minimum pointer boundary distance and the memory allocation peak as additional feedback information to guide the fuzzy test, thereby improving the efficiency of the fuzzy test in generating program inputs that can trigger memory vulnerabilities. BRIEF DESCRIPTION OF THE DRAWINGS

[0053] Figure 1 It is a schematic diagram of the overall process of the present invention. DETAILED DESCRIPTION

[0054] The present invention is further described in detail below in conjunction with the accompanying drawings and specific implementation methods.

[0055] The present invention provides a memory security vulnerability fuzz testing method combined with dynamic analysis, the flow chart is as follows: Figure 1 As shown, the following steps are included:

[0056] Step 1, open the source code file of the program to be tested, and insert the source code of the type definition and function definition for dynamic analysis into the source code file, including the following steps:

[0057] Step 11, insert the type definition of pointer metadata. The structure type of pointer metadata includes: the first address and the last address of the memory space pointed to by the pointer variable, the address of the pointer variable, and the state of the memory space, wherein the state of the memory space is used to determine whether the memory space is initialized.

[0058] In this embodiment, the code for the structure type definition of the pointer metadata is as follows, where PRFptr_addr is a pointer variable address type:

[0059]

[0060]

[0061] Step 12, insert the type definition of the data structure for maintaining pointer metadata. The data structure includes a hash table and a secondary tree, both of which use the address value of the pointer variable as the index value; in the secondary tree, the 26th to 48th bits starting from the low bit of the index value are used as the primary index value, and the 4th to 25th bits are used as the secondary index value. The initial capacity of the primary table and the secondary table are 2^23 and 2^22 respectively. Each element in the primary table is a pointer to the secondary table, and each element in the secondary table is a pointer to the pointer metadata.

[0062] In this embodiment, the codes for the type definition of the hash table and the secondary tree are as follows, where PRFpmd is a pointer metadata type, and PRFtrie_primary_entries and PRFtrie_secondary_entries are the capacities of the primary table and the secondary table, respectively:

[0063]

[0064] Step 13, insert the function definition for maintaining pointer metadata. Pointer metadata can be maintained using either hash table or secondary tree. When creating a pointer variable during program execution, insert pointer metadata into the hash table or secondary tree, and dynamically expand the capacity when the capacity is insufficient.

[0065] In both hash table and secondary tree modes, the specific processing logic for storing pointer metadata is as follows:

[0066] (A1) Hash table: Use pointer variable address value as index value, use chain address method to handle conflicts, and when the number of table elements reaches three times the number of buckets, expand the number of buckets to two times. The function declaration for inserting elements is as follows:

[0067] PRFpmd*PRFhashtbl_insert_pmd(PRFhashtbl*tbl,PRFpmd*pmd);

[0068] In this embodiment, the function code for inserting elements into the hash table is as follows: take the address of the pointer variable as the index value, use the hash function PRFhashtbl_hash to convert it into the subscript of the hash table, traverse the elements in the bucket corresponding to the subscript, and determine whether there is already pointer metadata with the same index value. If so, replace it; if not, directly insert the pointer metadata. When inserting pointer metadata, determine whether a new bucket is inserted. If so, add 1 to the number of used buckets. Determine whether the elements of the current hash table are greater than three times the number of used buckets: if so, expand the number of buckets to twice, and migrate the elements of the hash table to the expanded hash table; if not, do nothing. Among them, PRFpmd is the pointer metadata type, and the ptra member of PRFpmd is the pointer variable address:

[0069]

[0070] (A2) Secondary tree: Use the 26th to 48th bits of the pointer variable address value as the primary index value, and the 4th to 25th bits as the secondary index value. When the secondary table corresponding to the primary index value is missing, the secondary table is created and the pointer metadata is inserted into the secondary table. The function declaration for inserting elements is as follows, where PRFptr_addr is the pointer variable address type:

[0071] PRFpmd*PRFtrie_insert_pmd_ptr(PRFpmd**tbl,PRFptr_addr ptra);

[0072] In this embodiment, the function code for inserting an element into the secondary tree is as follows:

[0073]

[0074]

[0075] Step 14, insert the memory safety detection function definition. The memory safety detection function checks whether the current pointer value is within the legal first address and last address range of the corresponding pointer metadata, and updates the difference between the current pointer value and the legal first address and last address of the corresponding pointer metadata (that is, updates the difference between the current pointer value and the first address, and the difference between the current pointer value and the last address), and retains the smallest difference as the minimum pointer boundary distance, which is used to judge whether there is a tendency for the pointer to cross the boundary. The function declaration is as follows:

[0076] void*PRFcheck_dpv(const PRFpmd*pmd,const void*ptr,size_t size,constchar*file_name,unsigned line,unsigned column);

[0077] In this embodiment, the memory safety detection function code is as follows:

[0078]

[0079]

[0080] Step 15, insert the wrapper function definition of the memory allocation library function. After the wrapper function executes the memory allocation library function, it determines whether the execution is successful based on the function return value: if successful, the total value of the memory allocated when the program runs to this point is updated, and the global memory allocation peak value is updated with the total value of the allocated memory to judge whether there is a tendency to allocate too much memory, and finally returns the return value of the memory allocation library function; if unsuccessful, no operation is performed. The wrapper function declarations for memory allocation and memory release are as follows:

[0081] void*PRFmalloc(PRFpmd*ret_pmd,size_t size);

[0082] void PRFfree(PRFpmd*ptr_pmd,void*ptr);

[0083] In this embodiment, the wrapper function codes for memory allocation and memory release are as follows:

[0084]

[0085] Step 2: Use the compiler to preprocess the source code of the program under test, including macro replacement and header file import, and then use the compiler to parse the source code of the program under test, including lexical analysis, syntax analysis, semantic analysis, and generation of an abstract syntax tree.

[0086] Step 3, traverse the abstract syntax tree and instrument its nodes to detect memory errors while the program is running, and maintain shared memory variables with minimum pointer boundary distance and memory allocation peak.

[0087] Step 31, insert a stub into the main function entry of the program to obtain the shared memory of the fuzz test and establish inter-process communication with the fuzz test.

[0088] Step 32, inserting the definition and initialization statements of the pointer variable to create pointer metadata and inserting the pointer metadata into a hash table or a secondary tree.

[0089] In this embodiment, the function code to be inserted is as follows:

[0090] void test(){

[0091] int*ptr=malloc(sizeof(int));

[0092] }

[0093] The function code after instrumentation is as follows, where the PRFpmd_tbl_create function creates a hash table or a secondary tree and inserts pointer metadata:

[0094] void test(){

[0095] int*ptr=PRFmalloc(PRFpmd_tbl_create((PRFptr_addr)&ptr),sizeof(int));

[0096] }

[0097] Step 33, inserting pointer dereference, array subscript access, and member access statements of structure pointer variables to detect memory errors, and updating the minimum difference between the pointer value and the first address of the pointer metadata, and the minimum difference between the pointer value and the last address of the pointer metadata, and storing the minimum difference as the minimum pointer boundary distance in the shared memory variable of the fuzzy test.

[0098] In this embodiment, the function code to be inserted is as follows:

[0099] void test(int*ptr){

[0100] int num = *ptr;

[0101] }

[0102] The function code after instrumentation is as follows, where the PRFcheck_dpv function adds the pointer value to the size of the object pointed to by the pointer to determine whether it is within the legal upper and lower bounds of the pointer metadata to determine memory safety, and determines whether the pointer value dereferenced here is closer to the legal upper and lower bounds of the pointer. If so, the smaller pointer boundary distance is updated to the shared memory variable of the fuzz test:

[0103]

[0104] Step 34, insert the function call statements of memory allocation and memory release, replace them with calls to corresponding wrapper functions, maintain the pointer metadata of the heap type pointer variable, and update the current maximum allocated memory value, and store the maximum memory value as the memory allocation peak in the shared memory variable of the fuzz test.

[0105] In this embodiment, the function code to be inserted is as follows:

[0106]

[0107] The function code after instrumentation is as follows, where the PRFmalloc function executes the malloc function to allocate memory, and determines whether the currently allocated memory value is greater than the memory allocation peak value at this point in the program's execution, and updates the memory allocation peak value to the shared memory variable of the fuzz test. The PRFfree function executes the free function to release memory space and updates the currently allocated memory value:

[0108]

[0109] Step 4: compile the source code after the stub to obtain the assembly code.

[0110] Step 5: Perform coverage stubbing on the assembly code and skip the previously inserted code for dynamic analysis. That is to say, the following three types of code need to be skipped: pointer metadata operation function, common wrapper function, and inline wrapper library function. The specific processing logic is as follows:

[0111] (B1) Skip the insertion of pointer metadata operation functions. Pointer metadata operation functions use hash tables or secondary trees to maintain pointer metadata, which involves operations such as inserting, modifying, and releasing pointer metadata, and will check for memory errors. By identifying the function name prefix of the inserted pointer metadata operation function and the .LFE in the assembly code that represents the end of the function body, <num>Flag to skip coverage instrumentation for the code between the function name and the end marker.

[0112] In this embodiment, if the code inserted previously for dynamic analysis is covered by stubbing, the resulting code is as follows, where coverage stubbing is performed at the beginning of the PRFcheck function; coverage stubbing is performed at the jnb non-unconditional jump; and coverage stubbing is performed at the .L3853 conditional jump destination basic block:

[0113]

[0114]

[0115] By identifying the inserted function name prefix PRF, the code from the function name to the .LFE221 mark representing the end of the function body can be identified as the code inserted for dynamic analysis. If the coverage of the code inserted for dynamic analysis is not instrumented, the resulting code is as follows:

[0116]

[0117] (B2) Skip the instrumentation of ordinary wrapper functions. Ordinary wrapper functions pass pointer-type function return values ​​and function parameter pointer metadata to the original function, which is used for memory safety checks during the execution of the original function. After the transfer is completed, the original function is called to obtain the return value, and then the return value of the original function is returned. The method of skipping coverage instrumentation for ordinary wrapper functions is the same as that for pointer metadata operation functions, that is, by identifying the function name prefix and the end of the function body. LFE <num>Flag to skip coverage instrumentation for the code between the function name and the end marker.

[0118] (B3) Skip the instrumentation of inline wrapper library functions. Inline wrapper library functions are preset wrapper functions of system functions. Since they are inline functions, they will be embedded in the original program after compilation and become part of the original program code, and the name of the wrapper function cannot be obtained. However, the assembly code will use the .loc identifier to display the source file source of the inline code block. By identifying whether the source of the inline code block belongs to the source file used for dynamic analysis, skip the coverage instrumentation of the inline code block of the source file used for dynamic analysis.

[0119] In this embodiment, if the previously inserted inline wrapper library function code is covered by stubbing, the result code is as follows:

[0120]

[0121] Since the assembly file header stores the mapping relationship between the file name and the file ID, we can know whether the basic block code comes from the source file used for dynamic analysis by identifying the ID after the .loc mark. If the coverage of the inline wrapper library function code is not instrumented, the resulting code is as follows:

[0122]

[0123] Step 6, assemble and link the assembly code after the stub to obtain an executable file.

[0124] Step 7: Perform fuzz testing on the executable file, and use the coverage, minimum pointer boundary distance, and memory allocation peak provided by dynamic analysis as feedback information to guide the fuzz testing. The guidance part is specifically divided into three steps: collecting test cases to add to the seed queue, streamlining the seed queue, and evaluating the seeds in the seed queue.

[0125] Step 71: Collect test cases and add them to the seed queue. First, based on the coverage information provided by the fuzz test, determine whether a new program execution path is found during the program execution:

[0126] If there is a new program execution path, the test case is directly added to the seed queue;

[0127] If there is no new program execution path, determine whether there are several pointers closer to the legal upper and lower bounds of their pointer metadata during this run, and whether there is a higher memory allocation peak generated during this run: if there are several pointers closer to the legal upper and lower bounds of their pointer metadata, or a higher memory allocation peak is generated, add the test case to the seed queue; if no higher memory allocation peak is generated, and no higher memory allocation peak is generated, discard the test case.

[0128] Step 72, streamlining the seed queue. If the test case can be added to the seed queue after judging the coverage, minimum pointer boundary distance, and memory allocation peak indicators, then replace the test case in the seed queue that has the same execution path as the current test case and has a larger minimum pointer boundary distance or a lower memory allocation peak.

[0129] In this embodiment, the minimum pointer boundary distance is used as an indicator to collect test cases and add them to the seed queue, and the function code of the simplified seed queue is as follows:

[0130] int save_if_interesting(FILE*case){

[0131] / *if found new path,hnb is 1* /

[0132] hnb = has_new_bits(case);

[0133] / *if found smaller pointer distance,hnm is 1* /

[0134] hnm = has_new_min(case);

[0135] if(!hnb&&!hnm)

[0136] return 0;

[0137] / *replace seed which has same path by new seed* /

[0138] delete_same_path(case);

[0139] add_to_queue(case);

[0140] }

[0141] Step 73, evaluate the seeds in the seed queue. The seed excellence is calculated using factors such as execution time, file size, minimum pointer boundary distance, and memory allocation peak value, and the excellent seeds in the seed queue are retained, and the seed queue is further streamlined for subsequent mutation.

[0142] In this embodiment, the code for calculating the seed evaluation index function is as follows, where the smaller the value of the fav_factor variable is, the better the current seed is:

[0143]

[0144]

[0145] Step 8: Run the fuzz test and output a program input file that causes a memory safety error in the target program.

[0146] The technical features of the above embodiments may be combined arbitrarily. To make the description concise, not all possible combinations of the technical features in the above embodiments are described. However, as long as there is no contradiction in the combination of these technical features, they should be considered to be within the scope of this specification.

[0147] The above-mentioned embodiments only express several implementation methods of the present application, and the description is relatively specific and detailed, but it cannot be understood as limiting the scope of the invention. It should be pointed out that for ordinary technicians in this field, several modifications and improvements can be made without departing from the concept of the present invention, which all belong to the protection scope of the present invention.< / num> < / num> < / num>

Claims

1. A memory security vulnerability fuzz testing method combined with dynamic analysis, characterized in that: The following steps are involved: S1, open the source code file of the program to be tested, and insert the source code of type definition and function definition for dynamic analysis into the source code file; S2, using a compiler to preprocess the source code of the program to be tested, and then using the compiler to parse the source code of the program to be tested; S3, traverses the abstract syntax tree and instruments its nodes to detect memory errors while the program is running, and maintains shared memory variables with minimum pointer boundary distance and memory allocation peak; S4, compile the source code after the stub to obtain the assembly code; S5, perform coverage instrumentation on the assembly code and skip the previously inserted code for dynamic analysis; S6, assemble and link the assembly code after the stub to obtain an executable file, S7, performs fuzz testing on the executable file, using the coverage, minimum pointer boundary distance, and memory allocation peak provided by dynamic analysis as feedback information to guide the fuzz testing; S8, runs the fuzz test and outputs a program input file that causes a memory safety error in the target program.

2. The memory security vulnerability fuzz testing method combined with dynamic analysis according to claim 1 is characterized in that: Inserting source code of type definition and function definition for dynamic analysis in step S1 includes the following steps: S11, inserting the type definition of pointer metadata, the structure type of the pointer metadata includes: the first address and the last address of the memory space pointed to by the pointer variable, the address of the pointer variable, and the state of the memory space; S12, insert the type definition of the data structure for maintaining pointer metadata, the data structure includes a hash table and a secondary tree, both of which use the address value of the pointer variable as the index value; in the secondary tree, the 26th to 48th bits starting from the low bit of the index value are used as the primary index value, and the 4th to 25th bits are used as the secondary index value; the initial capacities of the primary table and the secondary table are 2^23 and 2^22 respectively, each element in the primary table is a pointer to the secondary table, and each element in the secondary table is a pointer to the pointer metadata; S13, inserting the function definition for maintaining pointer metadata. When creating a pointer variable during program execution, inserting the pointer metadata into the hash table or the secondary tree, and dynamically expanding the capacity when the capacity is insufficient; S14, insert the memory safety detection function definition, update the difference between the current pointer value and the legal first address of the corresponding pointer metadata, and the difference between the pointer value and the legal last address of the corresponding pointer metadata, and retain the smallest difference as the minimum pointer boundary distance to judge whether there is a tendency for the pointer to cross the boundary; S15, inserting the wrapper function definition of the memory allocation library function. After the wrapper function executes the memory allocation library function, it is determined whether the execution is successful according to the function return value: if successful, the total value of the memory allocated when the program runs to this point is updated, and the global memory allocation peak value is updated with the total value of the allocated memory to judge whether there is a tendency to allocate too much memory, and finally the return value of the memory allocation library function is returned; if unsuccessful, no operation is performed.

3. The memory security vulnerability fuzz testing method combined with dynamic analysis according to claim 2 is characterized in that: The specific processing logic for storing pointer metadata is as follows: In hash table mode, the pointer variable address value is used as the index value, and the chain address method is used to handle conflicts. When the number of table elements reaches more than three times the number of buckets, the number of buckets is expanded to two times; In the two-level tree mode, the 26th to 48th bits of the low-order pointer variable address value are used as the primary index value, and the 4th to 25th bits are used as the secondary index value. When the secondary table corresponding to the primary index value is missing, the secondary table is created and the pointer metadata is inserted into the secondary table.

4. The memory security vulnerability fuzz testing method combined with dynamic analysis according to claim 1 is characterized in that: In step S3, the abstract syntax tree is traversed and its nodes are plugged, including the following steps: S31, inserting a stub at the main function entry of the program to obtain the shared memory of the fuzz test and establish inter-process communication with the fuzz test; S32, inserting the definition and initialization statements of the pointer variable to create pointer metadata and inserting the pointer metadata into a hash table or a secondary tree; S33, inserting pointer dereference, array subscript access, and member access statements of structure pointer variables to detect memory errors, and updating the minimum difference between the pointer value and the legal first address of the pointer metadata, and the minimum difference between the pointer value and the legal last address of the pointer metadata, and storing the minimum difference as the minimum pointer boundary distance in the shared memory variable of the fuzz test; S34, insert the function call statements of memory allocation and memory release, replace them with the calls of corresponding wrapper functions, which are used to maintain the pointer metadata of heap type pointer variables, and update the current maximum allocated memory value, and store the maximum memory value as the memory allocation peak value in the shared memory variable of the fuzz test.

5. The memory security vulnerability fuzz testing method combined with dynamic analysis according to claim 1 is characterized in that: In step S5, the previously inserted code for dynamic analysis is skipped, and the code includes pointer metadata operation functions, common wrapper functions, and inline wrapper library functions; the steps include: S51, skip the insertion of the pointer metadata operation function, by identifying the function name prefix of the inserted pointer metadata operation function and the .LFE in the assembly code that represents the end of the function body. <num> Flag to skip coverage instrumentation for the code between the function name and the end flag;< / num> S52, skipping the stubbing of the common wrapper function; the common wrapper function passes the pointer type function return value and the pointer metadata of the function parameter to the original function, which is used for the original function to perform a memory safety check during the execution process. After the transfer is completed, the original function is called to obtain the return value, and then the return value of the original function is returned; S53, skipping the stubbing of the inline wrapper library function; by identifying whether the source of the inline code block belongs to the source file for dynamic analysis, skipping the coverage stubbing of the inline code block of the source file for dynamic analysis.

6. The memory security vulnerability fuzz testing method combined with dynamic analysis according to claim 1 is characterized in that: In step S7, the coverage, minimum pointer boundary distance, and memory allocation peak value provided by dynamic analysis are used as feedback information to guide fuzz testing, including the following steps: S71, collect test cases and add them to the seed queue: First, based on the coverage information provided by the fuzz test, determine whether a new program execution path is found during the program running process: If there is a new program execution path, the test case is directly added to the seed queue; If there is no new program execution path, determine whether there are several pointers closer to the legal upper and lower bounds of its pointer metadata during this run, and whether there is a higher memory allocation peak during this run: if there are several pointers closer to the legal upper and lower bounds of its pointer metadata, or a higher memory allocation peak is generated, add the test case to the seed queue; if there are no several pointers closer to the legal upper and lower bounds of its pointer metadata, and no higher memory allocation peak is generated, discard the test case; S72, streamlining the seed queue: if the test case can be added to the seed queue after judging the coverage, minimum pointer boundary distance, and memory allocation peak indicators, then replace the test case in the seed queue with a test case that has the same execution path as the current test case and has a larger minimum pointer boundary distance or a lower memory allocation peak; S73, evaluate the seeds in the seed queue: use the execution consumption time, file size, minimum pointer boundary distance, and memory allocation peak to calculate the seed excellence, retain the excellent seeds in the seed queue, and further streamline the seed queue for subsequent mutation.

Citation Information

Patent Citations

  • Binary program bug testing method and device and readable storage medium

    CN111581106A

  • Method for dynamically analyzing memory security of program containing specific statement

    CN116126705A

  • Concurrent program vulnerability detection method based on fuzzy testing and static analysis

    CN116305162A

  • Grey box fuzzy software testing method based on unique execution path filtering

    CN118194300A

  • Continuous vulnerability management system for blockchain smart contract based digital asset using sandbox and artificial intelligence

    US20210110047A1

Cited By

  • C language memory security detection method based on source code instrumentation

    CN120470580A