Fuzzing method based on program end points
Patent Information
- Application Number
- CN202610674545.3
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-05-15
- Publication Date
- 2026-08-18
AI Technical Summary
[0004]本发明的目的是提供一种基于程序结束点的模糊测试方法,用以解决现有模糊测试方法在适配和支持等方面存在的问题,基于程序结束点技术来获取程序覆盖率的模糊测试方法,优化了模糊测试的性能开销和平台需求
[0018]与现有技术相比,本发明具有以下技术特点:
Smart Images

Figure CN122594147A_ABST
Abstract
Description
Technical Field
[0001] This invention relates to the field of software fuzzing, and more specifically to a fuzzing method based on the program's end point. Background Technology
[0002] The rapid development of software technology has introduced a series of security issues. The increasing complexity of software makes security protection increasingly difficult. Fuzzing, as a dynamic detection technique, is one of the effective methods for software testing and vulnerability discovery. The core idea of fuzzing is to input automatically or semi-automatically generated random data into a program and monitor for program anomalies, such as crashes and assertion failures, to discover potential program errors. Combined with program analysis and runtime feedback methods, it efficiently generates test cases, reducing the amount of testing. Currently, the advantages of fuzzing technology in software testing and vulnerability discovery have been verified in multiple application areas, including but not limited to web applications, desktop applications, operating system kernels, embedded devices, browsers, web applications, connected vehicles, and mobile applications. Many domestic and international manufacturers, such as Google and Microsoft, have also applied fuzzing technology to their internal development processes.
[0003] Traditional fuzzing tools are imperfect, suffering from incompatibility, lack of support, and incomplete support for scenarios such as complex large programs and new platforms. Currently, the most commonly used fuzzing tools are AFL and its derivatives. These tools are generally designed for small programs. Testing large software requires additional adaptation work, often involving analyzing the target data processing function, constructing the target function's parameters, and then passing the fuzz-generated data to the software for processing. The complexity of this process is program-dependent. Avoiding adaptation necessitates full instrumentation of the executable program, such as with qemu or dynamorio, which significantly impacts program performance and imposes platform limitations. Summary of the Invention
[0004] The purpose of this invention is to provide a fuzzing method based on program end points, which solves the problems of existing fuzzing methods in terms of adaptation and support. The fuzzing method based on program end point technology to obtain program coverage optimizes the performance overhead and platform requirements of fuzzing.
[0005] To achieve the above objectives, the present invention employs the following technical solution: Fuzzy testing methods based on program endpoints include: Identify the module under test in the program under test; insert breakpoint instructions at the entry point of each basic block of the module under test, so that when the program under test executes a certain basic block during subsequent test execution, it can be captured by the debugger, thereby recording that the basic block has been overwritten. A set of variant seed files is constructed based on the initial seed file set, and each variant seed in the set is provided to the program under test for testing. Set up the test execution environment and load the program to be tested under the monitoring of the debugger; Load the auxiliary tracing module in the debugger, start the program under test, and record the basic block sequence executed by the program under test through the breakpoint tracing mechanism to determine the final basic block after the program under test completes the mutation seed parsing. By continuously testing mutated files in the mutated seed file set, potential vulnerabilities in the program under test are triggered; at the same time, the seed mutation strategy is optimized based on coverage. During test execution, when the program under test triggers a debug exception by executing a breakpoint instruction or triggers a crash signal, the debugger pauses the execution of the program under test and resumes the original instructions; After the breakpoint is handled, resume the execution of the program under test and let it continue running until it encounters the next breakpoint or execution ends; The test is completed and a test report is generated once the preset termination conditions are met.
[0006] Furthermore, firstly, the selected modules in the program under test that require coverage statistics are loaded using the IDA tool; then, all identified basic blocks are traversed, and the entry address, the original first byte of the entry address, and the instruction length of each basic block are extracted and exported as a basic block information file. Based on the basic block information file, the first byte at the entry point of each basic block in the module under test is rewritten as a breakpoint instruction, and then a binary file is generated so that the debugger can be triggered at these entry points when the program under test runs.
[0007] Furthermore, a set of variant seed files is constructed based on the initial seed file set, and each variant seed is provided to the program under test for testing, including: Construct an initial seed file set; the initial seed file set contains valid seeds that can be parsed by the program under test; the seed selection follows the following principles: first, the input format meets the syntax / validation rules of the program under test; second, it covers the diversity of input structures; and third, it keeps the inputs concise to facilitate efficient compilation and fast regression verification. Random or semi-random mutations are performed on the initial seed file to generate a set of mutated seed files; the mutation focuses on length / offset related fields, boundary value sensitive fields, the organization of structural sub-blocks, and the position of key byte patterns; Each mutation seed in the mutation seed file set is passed as an input parameter to the program under test.
[0008] Furthermore, after setting up the test environment, it was confirmed that the prerequisites were met, including: breakpoints had been inserted and basic block information files had been generated and saved; a batch of mutation seeds had been generated; and a debugger and the program under test and its dependent library files had been deployed in the test environment.
[0009] Furthermore, the tracing module is a GDB Python extension script used to: register a callback function for breakpoint triggering, which is automatically executed each time the breakpoint is paused; read the current PC register value to determine the address of the basic block that triggers the breakpoint, and record the address in the basic block execution log; query the basic block information file to obtain the original instruction bytes corresponding to the address, restore the breakpoint instruction to the original instruction, and automatically allow the program to continue execution.
[0010] Furthermore, the program under test is started to execute. During the process of the program under test processing the mutation seed, whenever a breakpoint instruction at the entry point of a basic block is executed, the following automated process is triggered in sequence: The processor executes a breakpoint instruction, triggering a debug exception; the operating system passes the debug exception to the debugger, which suspends program execution; the callback function of the tracing module reads the PC register value to obtain the current basic block address and records it in the basic block execution log file; the tracing module queries the basic block information file to recover the original instruction at that address; the tracing module sends a continue execution instruction to the debugger, and the program resumes execution until it encounters the next breakpoint or completes execution; After the program under test has successfully completed the parsing of the mutant seed, the last basic block executed by the program during the parsing process is found by checking the basic block execution log and recorded as the end basic block.
[0011] Furthermore, after determining the end of the basic block, the automated loop phase begins, with each loop executing the following steps sequentially: providing a mutation seed as input to the program under test; executing the program under test under the monitoring of the debugger and tracing module, recording the coverage information of each newly triggered basic block; determining the end of this round of testing when the program reaches the end of the basic block or crashes; recording the coverage data and exception information for this round; selecting the next mutation seed, restarting the program under test, and entering the next round of testing. When a certain mutant seed file triggers a vulnerability in the program under test, the program under test exhibits abnormal behavior, and the debugger captures the corresponding abnormal signal. When the debugger captures the abnormal signal, it immediately pauses program execution and preserves the crash context, recording the mutant seed that triggered the crash, the PC register value at the time of the crash, the call stack information, and the register state.
[0012] Furthermore, during the test loop, the seed mutation strategy is optimized using coverage data; if a mutation seed triggers a new basic block that has never been executed before in this round of testing, the mutation seed is added to an optimized seed queue as the basis for subsequent mutations; if a mutation seed does not trigger any new basic blocks, it is discarded.
[0013] Furthermore, regarding breakpoint triggering, the debugger pauses the execution of the program under test and resumes the original instructions as follows: Obtain the PC register value and locate the module under test; read the PC register value to obtain the PC address where the program is paused; then, by querying the memory mapping information of the process, compare the PC register value with the address range of each loaded module under test to determine the module under test where the PC is located, and subtract the loading base address of the module under test from the PC register value to obtain the offset within the module; Based on the offset within the module, a matching basic block is found in the basic block information file, and the original first byte at the entry point of the basic block, i.e., the original instruction, is obtained. Restore original instructions: Replace the breakpoint instruction at the current PC address with the original first byte using the debugger's memory write function.
[0014] Furthermore, after restoring the original instructions, the tracing module sends a continue execution instruction to the debugger; The program under test continues execution from the recovered original instructions, proceeding along the program control flow until one of the following three conditions is met: When the execution reaches the breakpoint instruction of the next basic block entry that has not yet been triggered, the execution of the program under test is paused again and the original instruction is resumed. Once the execution reaches the end of the basic block, it indicates that the processing of the current mutant seed has been completed, and this round of testing ends; The program under test triggers a crash signal due to a vulnerability. The debugger captures the signal and enters the crash recording process.
[0015] Furthermore, the test includes the following three parts: coverage statistics, with data sourced from basic block execution logs and coverage data; crash and exception information, with data sourced from vulnerability trigger records; and test execution statistics, with data sourced from the overall execution process of the test.
[0016] A terminal device includes a processor, a memory, and a computer program stored in the memory; when the processor executes the computer program, it implements the fuzz testing method based on the program end point.
[0017] A computer-readable storage medium storing a computer program; when the computer program is executed by a processor, it implements the fuzz testing method based on the program's end point.
[0018] Compared with the prior art, the present invention has the following technical features: This invention is applicable to large and complex software; it has low performance overhead and can be instrumented in a single module; by using gdb breakpoint technology, the fuzzing engine and its dependencies are packaged into an image, thereby increasing consistency and portability, facilitating distribution and deployment, and enabling rapid deployment of fuzzing tests. Attached Figure Description
[0019] Figure 1 This is a schematic diagram of the framework of the method of the present invention; Figure 2 This is a schematic diagram of the overall process of the method of the present invention. Detailed Implementation
[0020] This invention discloses a fuzzing method based on program endpoints, applicable to large and complex software systems. This method exhibits low performance overhead during operation, enables instrumentation at the single-module level, and has low dependence on the target platform. To minimize additional overhead during fuzzing, this invention performs static localization of all basic blocks within the target module using IDA during the preprocessing stage: the first instruction of each basic block is replaced with a breakpoint instruction, and the original location information, instruction size, and instruction content of the replaced instruction are saved. During the fuzzing execution stage, triggering a breakpoint instruction indicates that the program has entered a new basic block. Subsequently, the execution information of the corresponding basic block is recorded based on the hit breakpoint location, and the previously saved original instructions are restored to their original addresses, allowing the program to continue execution according to the original control flow. Through these steps, this invention can obtain program coverage information during execution without significantly increasing runtime overhead. The specific steps of this invention are as follows: Step 1: Identify the module under test in the program under test; Insert breakpoint instructions at the entry point of each basic block of the module under test, so that when the program under test executes a certain basic block during subsequent test execution, it can be captured by the debugger, thereby recording that the basic block has been overwritten.
[0021] Step 101: First, use the IDA tool to load the selected test module (e.g., main program .exe or key library .dll / .so) in the program under test (e.g., software system) that needs coverage statistics. Let the IDA tool automatically analyze the function structure of the module and identify all the basic blocks.
[0022] Step 102: Run the IDAPython script within the IDA tool, traverse all identified basic blocks, extract the entry address (offset within the module), the original first byte of the entry address (referring to the first machine instruction byte originally stored at the entry address of the basic block), and the instruction length of each basic block, and export them as a basic block information file. Step 103: Read the basic block information file, rewrite the first byte of each basic block entry point in the module under test with a breakpoint instruction, such as the 0xCC instruction under the x86 architecture, to facilitate breakpoint exception triggering, and then generate a binary file; so that the debugger can be triggered at these entry points when the program under test runs; the coverage statistics are calculated by subsequent steps based on the actual basic block records triggered, thereby capturing the number of basic blocks executed each time the program runs, and realizing the coverage statistics.
[0023] Step 2: Construct a set of variant seed files based on the initial seed file set, and provide each variant seed in the set to the program under test for testing.
[0024] Step 201: Construct an initial seed file set. The initial seed file set is a collection of seeds containing valid seeds that can be parsed by the program under test. Seed selection follows these principles: First, the input format must meet the syntax / validation rules of the program under test (e.g., header structure, field length, encoding method, etc. must pass the initial verification); second, it should cover as much as possible the format specifications and data organization patterns of the input files expected by the program under test (different branches / different boundary forms, such as different sizes, optional field combinations, different encoding paths, etc.); and third, it should be kept as concise as possible to facilitate efficient compilation and rapid regression verification.
[0025] Step 202: Based on the initial seed file, perform random or semi-random mutation to generate a set of mutated seed files. The set of mutated seed files consists of "semi-legal" mutated seeds. They still try to meet the basic format constraints and can pass the first-level verification of the program under test and enter the deep parsing, but they are deliberately violated in terms of semantics and boundary conditions. The mutation focus usually falls on length / offset related fields, boundary value sensitive fields, the organization of structural sub-blocks, and key byte patterns. Therefore, these inputs may trigger boundary processing defects or logical errors (such as out-of-bounds access, abnormal branches, error states, etc.) in subsequent processing stages.
[0026] Step 203: Pass each mutant seed in the mutant seed file set as an input parameter to the program under test.
[0027] Step 3: Set up the test execution environment and load the program under test under the monitoring of the debugger GDB (GNU Debugger, an open source program debugging tool) to prepare for subsequent coverage tracking and exception capture.
[0028] After setting up the test environment, it was confirmed that the prerequisites were met, including: breakpoints were inserted in step 1 and the basic block information file was generated and saved; a batch of mutation seeds were generated in step 2; and GDB and the program under test and its dependent library files were deployed in the test environment.
[0029] Step 4: Load the auxiliary tracing module in the debugger, start the program under test, and record the sequence of basic blocks executed by the program under test through the breakpoint tracing mechanism to determine the final basic block after the program under test completes the mutation seed parsing.
[0030] Step 401: Load the tracing module in the debugger; the tracing module is a GDB Python extension script used to: register a callback function for breakpoint triggering, which is automatically executed each time the breakpoint is paused; read the current PC register value to determine the address of the basic block that triggers the breakpoint, and record the address in the basic block execution log; query the basic block information file to obtain the original instruction byte corresponding to the address, restore the breakpoint instruction to the original instruction, and automatically allow the program to continue execution.
[0031] Step 402: Start the execution of the program under test. During the process of the program under test processing the mutation seed, whenever a breakpoint instruction at the entry point of a basic block is executed, the following automated process is triggered in sequence: The processor executes a breakpoint instruction, triggering a debugging exception. The breakpoint tracing mechanism records the sequence of basic blocks executed by the program under test. The operating system forwards the exception to the debugger, which then suspends program execution. The callback function of the tracing module reads the PC register value to obtain the current basic block address and records it in the basic block execution log file. The tracing module queries the basic block information file to recover the original instruction at that address. The tracing module sends a continue execution instruction to the debugger, and the program resumes execution until it encounters the next breakpoint or completes execution. Step 403, determine the end basic block END_BBL: After the program under test has successfully completed the parsing of the mutant seed, the last basic block executed by the program during the parsing process is found by checking the basic block execution log and recorded as END_BBL.
[0032] The END_BBL indicates that the program under test has completed a full processing cycle of a mutant seed without triggering a crash exception, and is used as a criterion for determining the completion of a single round of testing in subsequent automated testing.
[0033] Step 5: By continuously testing the mutated files in the mutated seed file set, potential vulnerabilities in the program under test are triggered; at the same time, the seed mutation strategy is optimized based on coverage.
[0034] Step 501: After determining the end of the basic block, enter the automated loop stage. Each loop executes the following steps in sequence: provide a mutation seed as input to the program under test; execute the program under test under the monitoring of the debugger and tracing module, and record the coverage information of each newly triggered basic block; determine the end of this round of testing when the program reaches the end of the basic block or crashes; record the coverage data and exception information of this round; select the next mutation seed and restart the program under test to enter the next round of testing.
[0035] Step 502: When a certain mutant seed file triggers a vulnerability in the program under test, the program under test produces abnormal behavior, and the debugger captures the corresponding abnormal signal; when the debugger captures the abnormal signal, it immediately pauses the program execution and preserves the crash scene, recording the mutant seed that triggered the crash, the PC register value at the time of the crash, the call stack information, and the register state. The abnormal signals include, but are not limited to: SIGSEGV (segmentation fault, indicating that the program accessed an illegal memory address, which may correspond to buffer overflow, null pointer dereference, or out-of-bounds access), SIGABRT (abnormal termination, indicating that the program actively called the termination function, which may correspond to assertion failure or heap corruption), SIGFPE (floating-point exception, indicating illegal arithmetic operation, which may correspond to division by zero error or integer overflow), SIGBUS (bus error, indicating illegal memory alignment access), etc.
[0036] Step 503: During the test loop, optimize the seed mutation strategy using coverage data. Specifically, if a mutated seed triggers a new basic block that has never been executed before in this round of testing, the mutated seed is added to an optimized seed queue as the basis for subsequent mutations. If a mutated seed does not trigger any new basic blocks, it is discarded. In subsequent tests, the optimized seed queue can replace or supplement the initial seed file set, thereby generating new mutated seeds through mutation.
[0037] Through the aforementioned coverage guidance mechanism, the test gradually explores deeper code paths in the program under test, increasing the probability of discovering vulnerabilities.
[0038] Step 6: During the test execution, when the program under test triggers a debug exception by executing a breakpoint instruction or triggers a crash signal, the debugger pauses the execution of the program under test and resumes the original instructions.
[0039] Taking breakpoint triggering as an example, the specific steps include the following: Step 601: Obtain the PC register value and locate the module under test; read the PC register value through the debugger's Python interface to obtain the PC address where the program is paused; then, by querying the process's memory mapping information, compare the PC register value with the address range of each loaded module under test to determine the module under test where the PC is located, and subtract the loading base address of the module under test from the PC register value to obtain the offset within the module.
[0040] The PC (Program Counter) is a special-purpose register in the processor (called the RIP register in the x86_64 architecture), and its value points to the address of the instruction that is currently being executed or is about to be executed.
[0041] Step 602: Query the original instruction; based on the offset within the module, search for the matching basic block in the basic block information file, and obtain the original first byte at the entry point of the basic block, i.e., the original instruction. Step 603: Restore the original instruction; replace the breakpoint instruction 0xCC at the current PC address with the original first byte using the debugger's memory write function; after restoration, the breakpoint of the basic block is consumed, and when the program executes the basic block again, it will directly execute the original instruction without triggering the breakpoint again, thus ensuring that each basic block triggers the breakpoint only once, which ensures the accuracy of coverage statistics and gradually reduces performance overhead as the test progresses.
[0042] Step 7: After the breakpoint is handled, resume the execution of the program under test and let it continue running until it encounters the next breakpoint or the execution ends.
[0043] Step 701: After restoring the original instructions, the tracing module sends a continue command to the debugger through the debugger's Python interface. After receiving the command, the debugger resumes the program under test from the paused state to the running state.
[0044] Step 702: The program under test continues execution from the recovered original instruction and runs along the program control flow until one of the following three situations occurs: when the program reaches the breakpoint instruction of the next basic block entry that has not yet been triggered, it re-enters the processing flow of step 6; when the program reaches the end of the basic block, it indicates that the processing of the current mutation seed has been completed and the current test ends; or the program under test triggers a crash signal due to a vulnerability, the debugger captures the signal and enters the crash recording process in step 502.
[0045] Steps 6 and 7 are executed multiple times in a single test cycle; each time a new breakpoint instruction is triggered, a "pause-record-resume-continue" processing flow is executed; as the test progresses, the basic blocks that have already been triggered no longer generate breakpoints, the number of remaining breakpoints gradually decreases, and the running speed of the program under test gradually recovers until the processing of the current mutant seed ends.
[0046] Step 8: Once the testing process reaches the preset termination conditions (e.g., reaching the preset test time limit, coverage no longer increasing, or a sufficient number of vulnerabilities being discovered), the test is completed and a test report is generated. The test includes the following three parts: coverage statistics, with data from the basic block execution logs and coverage data recorded in Steps 4 and 5; crash and exception information, with data from the vulnerability trigger records recorded in Step 5; and test execution statistics (such as the total number of mutation seeds, execution rounds, etc.), with data from the overall execution process from Steps 2 to 7.
[0047] Example: This embodiment of the invention takes a command-line parser running on the Linux X86_64 platform as an example to perform fuzz testing.
[0048] Step 1, Basic Block Information Extraction and Program Instrumentation: Open the target program in IDA and wait for it to automatically complete disassembly and analysis. Run the preset IDA script, which traverses all identified functions and their basic blocks in the target program's .text code segment. For each basic block, the script extracts its entry address, the first byte of the original instruction at that address, and the instruction content, and records them in the basic block information file. Subsequently, the script modifies the first byte at the entry point of each basic block in the file to the breakpoint instruction 0xCC (INT3); finally, the modified program is saved as the instrumented target program.
[0049] Step 2, Seed Queue Construction and Input Mutation: Collect several legal sample files that can be correctly parsed by the original target program and place them in the seed directory as initial seeds. Write a mutation script that uses strategies such as random bit flipping, byte block insertion / deletion, and arithmetic addition / subtraction of fields of known length to mutate the files in the seed queue, generating a large number of "semi-legal" test cases, which are then saved to the corpus directory for subsequent testing.
[0050] Step 3, Test execution environment deployment: Deploy the GDB debugger, the instrumented target program, and all the dynamic link libraries required for its operation on the test machine to ensure that the program can start normally under GDB monitoring.
[0051] Step 4, Program Execution Tracing and Endpoint Identification: A GDB Python extension script is written to implement an auxiliary tracing module. Its functions include: loading the basic block information file; during program execution, whenever a breakpoint at the entry point of a basic block is hit, automatically recording the address of that basic block to the coverage log, restoring the instruction at that address to its original bytes, and then allowing the program to continue execution. The instrumented target program is run using a valid seed, and its complete execution path is recorded through the tracing module. After the program completes normal execution, the last basic block address recorded in the log is marked as the program end point (END_BBL), which signifies the end of a complete input parsing process.
[0052] Step 5, Coverage-Driven Automated Testing Loop: Enter the automated testing loop. In each loop, the testing framework performs the following operations: Step 501: Take a mutated seed file from the corpus directory as input and start the instrumented target program.
[0053] Step 502: Execute the program under the monitoring of GDB and the auxiliary tracing module. The auxiliary tracing module will record all new basic blocks triggered in this round of execution. The current test round ends when the program execution triggers a crash (such as SIGSEGV) or normally reaches the program end point (END_BBL) determined in Step 4. Record the coverage data for this round. If a crash occurs, save the input file to the crash seed directory.
[0054] Step 503: Optimize the seed queue based on the coverage data: If the current input triggers a new basic block coverage, add it to the optimized seed queue for further mutation; otherwise, discard it.
[0055] Step 6, Breakpoint Triggering and Instruction Recovery: When the program executes to the breakpoint instruction (0xCC) at the entry point of a basic block, the CPU triggers a debug exception, and GDB takes over control. The callback function of the auxiliary tracing module is activated and performs the following operations: reads the value of the program counter (PC / RIP) through the GDB interface and calculates its offset address within the module; uses this offset address as the key to query the basic block information file and obtain the original instruction byte before it was replaced at that location; and uses GDB's memory write command to restore the 0xCC byte at the current PC address to the queried original instruction byte.
[0056] Step 7, Resume Program Execution: After restoring the original instructions in Step 6, the auxiliary tracing module uses GDB commands to resume program execution from the restored instructions. The program will run along the original control flow until it encounters the next uncovered basic block breakpoint, reaches END_BBL, or crashes. Steps 6 and 7 will be executed multiple times in a single test round until the test round ends. As the test progresses, the covered basic block breakpoints are permanently restored, and the program's runtime overhead gradually decreases.
[0057] Step 8, Test Result Analysis and Report Generation: The test cycle ends after reaching a preset time, number of rounds, or coverage plateau. The system automatically generates a test report, including: coverage statistics (such as total basic block coverage and growth curves), a list of discovered crashes (with trigger signals and input files), and a test execution overview (total number of rounds, execution speed, etc.). These results are used to evaluate test effectiveness and locate potential vulnerabilities.
[0058] The above embodiments are only used to illustrate the technical solutions of this application, and are not intended to limit them. Although this application has been described in detail with reference to the foregoing embodiments, those skilled in the art should understand that modifications can still be made to the technical solutions described in the foregoing embodiments, or equivalent substitutions can be made to some of the technical features. Such modifications or substitutions do not cause the essence of the corresponding technical solutions to deviate from the spirit and scope of the technical solutions of the embodiments of this application, and should all be included within the protection scope of this application.
Claims
1. A fuzzy testing method based on program endpoint, characterized in that, include: Identify the modules to be tested in the program under test; Insert breakpoint instructions at the entry point of each basic block of the module under test, so that when the program under test executes a certain basic block during subsequent test execution, it can be captured by the debugger, thereby recording that the basic block has been overwritten. A set of variant seed files is constructed based on the initial seed file set, and each variant seed in the set is provided to the program under test for testing. Set up the test execution environment and load the program to be tested under the monitoring of the debugger; Load the auxiliary tracing module in the debugger, start the program under test, and record the basic block sequence executed by the program under test through the breakpoint tracing mechanism to determine the final basic block after the program under test completes the mutation seed parsing. By continuously testing mutated files in the mutated seed file set, potential vulnerabilities in the program under test are triggered; at the same time, the seed mutation strategy is optimized based on coverage. During test execution, when the program under test triggers a debug exception by executing a breakpoint instruction or triggers a crash signal, the debugger pauses the execution of the program under test and resumes the original instructions; After the breakpoint is handled, resume the execution of the program under test and let it continue running until it encounters the next breakpoint or execution ends; The test is completed and a test report is generated once the preset termination conditions are met.
2. The fuzzy testing method based on the program termination point according to claim 1, characterized in that, First, use the IDA tool to load the selected modules in the program under test whose coverage needs to be calculated; then, traverse all the identified basic blocks, extract the entry address, the original first byte of the entry address, and the instruction length of each basic block, and export them as a basic block information file. Based on the basic block information file, the first byte at the entry point of each basic block in the module under test is rewritten as a breakpoint instruction, and then a binary file is generated so that the debugger can be triggered at these entry points when the program under test runs.
3. The fuzzy testing method based on the program endpoint according to claim 1, characterized in that, A set of variant seed files is constructed based on the initial seed file set, and each variant seed is provided to the program under test for testing, including: Construct an initial seed file set; the initial seed file set contains valid seeds that can be parsed by the program under test; the seed selection follows the following principles: first, the input format meets the syntax / validation rules of the program under test; second, it covers the diversity of input structures; and third, it keeps the inputs concise to facilitate efficient compilation and fast regression verification. Random or semi-random mutations are performed on the initial seed file to generate a set of mutated seed files; the mutation focuses on length / offset related fields, boundary value sensitive fields, the organization of structural sub-blocks, and the position of key byte patterns; Each mutation seed in the mutation seed file set is passed as an input parameter to the program under test.
4. The fuzzy testing method based on the program endpoint according to claim 1, characterized in that, The tracing module is a GDB Python extension script used to: register callback functions for breakpoint triggering, which are automatically executed each time the breakpoint is paused; read the current PC register value to determine the address of the basic block that triggered the breakpoint, and record the address in the basic block execution log; query the basic block information file to obtain the original instruction bytes corresponding to the address, restore the breakpoint instruction to the original instruction, and automatically allow the program to continue execution.
5. The fuzzy testing method based on the program endpoint according to claim 1, characterized in that, When the program under test is started, during the process of the program under test processing the mutation seed, whenever a breakpoint instruction at the entry point of a basic block is executed, the following automated process is triggered in sequence: The processor executing a breakpoint instruction triggers a debug exception; The operating system passes the debugging exception to the debugger, which then suspends program execution; the callback function of the tracing module reads the PC register value to obtain the current basic block address and records it in the basic block execution log file; The tracing module queries the basic block information file to recover the original instruction at that address; the tracing module sends a continue execution instruction to the debugger, and the program resumes execution until it encounters the next breakpoint or completes execution. After the program under test has successfully completed the parsing of the mutant seed, the last basic block executed by the program during the parsing process is found by checking the basic block execution log and recorded as the end basic block.
6. The fuzzy testing method based on the program termination point according to claim 1, characterized in that, After determining the end of the basic block, the automated loop phase begins, with each loop executing the following steps: providing a mutation seed as input to the program under test; executing the program under test under the monitoring of the debugger and tracing module, recording the coverage information of each newly triggered basic block; determining the end of the current test when the program reaches the end of the basic block or crashes; recording the coverage data and exception information for this round; selecting the next mutation seed and restarting the program under test to enter the next round of testing. When a certain mutant seed file triggers a vulnerability in the program under test, the program under test exhibits abnormal behavior, and the debugger captures the corresponding abnormal signal. When the debugger captures the abnormal signal, it immediately pauses program execution and preserves the crash context, recording the mutant seed that triggered the crash, the PC register value at the time of the crash, the call stack information, and the register state.
7. The fuzzy testing method based on the program endpoint according to claim 1, characterized in that, During the test loop, the seed mutation strategy is optimized using coverage data. If a mutation seed triggers a new basic block that has never been executed before in this round of testing, the mutation seed is added to an optimized seed queue as the basis for subsequent mutations. If a mutation seed does not trigger any new basic blocks, it is discarded. Furthermore, regarding breakpoint triggering, the debugger pauses the execution of the program under test and resumes the original instructions as follows: Obtain the PC register value and locate the module under test; read the PC register value to obtain the PC address where the program is paused; then, by querying the memory mapping information of the process, compare the PC register value with the address range of each loaded module under test to determine the module under test where the PC is located, and subtract the loading base address of the module under test from the PC register value to obtain the offset within the module; Based on the offset within the module, a matching basic block is found in the basic block information file, and the original first byte at the entry point of the basic block, i.e., the original instruction, is obtained. Restore original instructions: Replace the breakpoint instruction at the current PC address with the original first byte using the debugger's memory write function.
8. The fuzzy testing method based on the program termination point according to claim 1, characterized in that, After restoring the original instructions, the tracing module sends a continue execution command to the debugger; The program under test continues execution from the recovered original instructions, proceeding along the program control flow until one of the following three conditions is met: When the execution reaches the breakpoint instruction of the next basic block entry that has not yet been triggered, the execution of the program under test is paused again and the original instruction is resumed. Once the execution reaches the end of the basic block, it indicates that the processing of the current mutant seed has been completed, and this round of testing ends; The program under test triggers a crash signal due to a vulnerability. The debugger captures the signal and enters the crash recording process.
9. A terminal device, comprising a processor, a memory, and a computer program stored in the memory; characterized in that, When the processor executes a computer program, it implements the fuzz testing method based on the program end point as described in any one of claims 1-8.
10. A computer-readable storage medium storing a computer program; characterized in that, When a computer program is executed by a processor, it implements the fuzz testing method based on the program end point as described in any one of claims 1-8.