Reverse debugging delta recording method based on dynamic layering and predictive filtering
By using dynamic layering and predictive filtering, program region types are identified and distinguished, and differentiated recording and intelligent compression are performed. This solves the problems of high memory overhead and insufficient cross-architecture adaptability of existing reverse debugging tools, and achieves low-overhead and efficient cross-architecture reverse debugging.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-12-11
- Publication Date
- 2026-03-03
AI Technical Summary
Existing reverse debugging tools suffer from excessive memory overhead, insufficient cross-architecture adaptability, fixed recording granularity, indiscriminate recording, and a single compression method, resulting in low efficiency.
By employing a dynamic layering and predictive filtering approach, static analysis tools are used to identify regions such as code segments, data segments, and stack memory, which are then divided into four types. Differentiated recording and intelligent compression are performed based on the region type. A global region mapping table is established, and a modification record circular queue and branch instruction history table are constructed. Duplicate coverage filtering and branch stability prediction are performed to achieve low-overhead reverse debugging that is compatible with cross-architecture systems.
While ensuring debugging accuracy, it significantly reduces memory overhead, decreasing memory usage by 50% to 80%, improving reverse debugging response speed by over 40%, increasing compression rate by 30%, and supporting reverse debugging of multiple architectures such as x86 and ARM.
Smart Images

Figure CN121301173B_ABST
Abstract
Description
Technical Field
[0001] This invention belongs to the field of computer software development technology, specifically relating to a reverse debugging incremental recording method based on dynamic layering and predictive filtering. Background Technology
[0002] Reverse debugging tools, such as Mozilla's RR tool, achieve reverse execution by recording program execution traces. Their core is an incremental recording strategy, which records only changes in program state, such as memory modifications and register changes, rather than a complete snapshot, thus reducing memory usage. However, existing reverse debugging tools still have the following limitations: First, the recording granularity is fixed, using the same recording strategy for all types of state changes without distinguishing data lifecycles, such as temporary variables and global variables; second, indiscriminate recording occurs, even if some memory modifications are quickly overwritten, such as temporary variables on the stack, they are still fully recorded; third, the compression method is singular, using a uniform compression algorithm for different types of operations, such as heap allocation and stack operations, resulting in limited compression efficiency; fourth, instruction set adaptability is insufficient, lacking targeted design for the register and instruction characteristics of different architectures such as x86 and ARM, limiting versatility.
[0003] In summary, existing reverse debugging incremental recording methods mainly suffer from problems such as excessive memory overhead and insufficient cross-architecture adaptability. Summary of the Invention
[0004] In view of this, the present invention provides a reverse debugging incremental recording method based on dynamic hierarchical and predictive filtering, which achieves low-overhead reverse debugging that is compatible with cross-architecture while ensuring debugging accuracy.
[0005] The reverse debugging incremental recording method based on dynamic hierarchical and predictive filtering provided by this invention specifically includes the following steps:
[0006] Parse the segment table of the target program's binary file to identify the code segment, read-only data segment, writable data segment, and uninitialized data segment, determine the potential allocation range of heap memory, and mark the starting address and growth direction of stack memory;
[0007] The code segment, read-only data segment, and global variable area modified by the set keyword are classified as the first type of area; the function stack frame and temporarily allocated stack memory are classified as the second type of area; the writable data segment, uninitialized data segment, and heap memory are classified as the third type of area; and the CPU status register is classified as the fourth type of area. The debugging attributes of the above areas are marked; and a global area mapping table between address range, area type and debugging attributes is established.
[0008] The reverse debugger executes the target program to obtain the current address, establishes the first mapping table from the current address to the circular queue of modification records, and obtains the current region to which the current address belongs from the global region mapping table;
[0009] If the current region is a Class I region, abnormal write operations are monitored to form a first record, the modified record is added to the modified record circular queue, and duplicate overwrite filtering is performed; if the current region is a Class II region, the records are merged to form a stack frame snapshot; if the current region is a Class III region, memory modifications are performed to form a second record, the modified record is added to the modified record circular queue, duplicate overwrite filtering is performed, and allocation events, release events, and reallocation events are recorded for heap operations; if the current region is a Class IV region, a register group snapshot is recorded; the execution state trajectory is composed of the first record, stack frame snapshot, second record, register group snapshot, and first mapping table.
[0010] The execution status trajectory is compressed based on the type of data-related region.
[0011] Furthermore, the method for identifying the code segment, read-only data segment, writable data segment, and uninitialized data segment in the segment table of the target program binary file is as follows: the binary file of the target program is preprocessed using a static analysis tool.
[0012] Furthermore, the method for determining the potential allocation range of heap memory is as follows: function call analysis is performed on the binary file of the target program.
[0013] Furthermore, the first record is formed when an exception occurs by recording the destination address of the write operation, the original value in the destination address, the new value to be written, the trigger instruction address, and the exception context.
[0014] Furthermore, the stack frame snapshot includes the stack base address, stack top pointer, function parameters, and key local variables.
[0015] Furthermore, the second record includes the destination address of each write operation, the original value within the destination address, the new value to be written, the instruction context, and the thread ID.
[0016] Furthermore, the recording process of the register group snapshot is as follows: the instruction records within the set window are used as a group to record the register group snapshot, and adjacent register group snapshots only record the changes compared to the previous one; if the rate of change of registers in a set number of consecutive register group snapshots is greater than a threshold, the set window is reduced; otherwise, the set window is increased.
[0017] Furthermore, the implementation of the duplicate coverage filtering is as follows: when there are more than a set number of records in the modified record circular queue, the instruction interval between adjacent records in the most recent N records is calculated. The instruction interval is the number of instruction intervals between the two trigger instructions of adjacent records in the program execution sequence. If the instruction interval between all adjacent records is less than the threshold, the retention flag of the middle records in the most recent N records other than the first and last records is set to not be retained; otherwise, all of the most recent N records are set to be retained.
[0018] When the modified record circular queue is full, if there are records marked as not to be retained, remove these records; otherwise, remove the set number of records at the head of the modified record circular queue.
[0019] Furthermore, for a stack frame snapshot, the address of the stack frame variable and the stack base address are obtained, the offset of the stack frame variable relative to the stack base address is calculated, and the offset is encoded using variable-length encoding to convert the stack frame variable address into the stack base address and offset encoding; for the stack frame array, the address, length and value of the first element are recorded, and other elements are represented as relative indexes and value encodings.
[0020] Furthermore, for the second record, a heap memory base address table is established to store the heap memory base address and the heap memory size. The table index of the heap memory base address table is a unique number of the heap memory. Variable-length encoding is used to encode the offset between the operation address in the heap memory and the heap memory base address. The operation address in the heap memory is represented by the heap memory base address and offset encoding. For global variables, they are represented as data pairs consisting of their corresponding symbol ID and offset. For the value of the variable, the repetition rate, the continuous increment ratio, and the bit density are calculated by sampling. When the repetition rate is greater than the threshold, the LZW algorithm is selected. When the continuous increment ratio is greater than the threshold, the difference encoding is selected. When the bit density is less than the threshold, the Huffman encoding is selected. In other cases, a general compression algorithm is used. Beneficial effects
[0021] This invention first preprocesses the target program binary file using static analysis tools, identifying and classifying regions such as code segments, data segments, and heap or stack memory into four categories, marking corresponding debugging attributes, and establishing a global region mapping table between address ranges, region types, and debugging attributes. The reverse debugger executes the binary file, constructing a first mapping table for a modification record loop queue and a branch instruction history table. Based on the global region mapping table, it performs differentiated recording on the four types of regions, forming a first record, stack frame snapshot, second record, and register set snapshot. Simultaneously, it performs duplicate overwrite filtering on the first and third types of regions. For branch instructions, it determines the specific information of the record based on branch stability. The filtered first record, stack frame snapshot, second record, register set snapshot, and first mapping table then constitute the execution state trajectory. Intelligent compression is performed on the stack frame snapshots, heap memory and global variable records, register snapshots, and variable values in the execution state trajectory, ultimately forming a low-overhead and accurate execution state trajectory to support reverse debugging backtracking. Attached Figure Description
[0022] Figure 1 This is a flowchart illustrating the reverse debugging incremental recording method based on dynamic hierarchical and predictive filtering provided by the present invention. Detailed Implementation
[0023] The present invention will be described in detail below with reference to the accompanying drawings and embodiments.
[0024] The reverse debugging incremental recording method based on dynamic layering and predictive filtering provided by this invention has the following core idea: First, the target program binary file is preprocessed using static analysis tools to identify and classify regions such as code segments, data segments, heap or stack memory into four categories, and mark the corresponding debugging attributes to establish a global region mapping table between address ranges, region types, and debugging attributes. The reverse debugger executes the binary file, constructs a first mapping table of modification record circular queues and a branch instruction history table, and performs differentiated recording on the four types of regions according to the global region mapping table to form a first record, stack frame snapshot, second record, and register group snapshot. At the same time, duplicate overwrite filtering is performed on the first and third types of regions, and the specific information of the record is determined according to the branch stability of the branch instructions. Then, the filtered first record, stack frame snapshot, second record, register group snapshot, and first mapping table constitute the execution state trajectory. The stack frame snapshot, heap memory and global variable records, register snapshots and variable values in the execution state trajectory are intelligently compressed to finally form a low-overhead and accurate execution state trajectory to support reverse debugging backtracking.
[0025] The reverse debugging incremental recording method based on dynamic hierarchical and predictive filtering provided by this invention has the following process: Figure 1 As shown, the specific steps include:
[0026] Step 1: Use static analysis tools to preprocess the binary file of the target program, parse the segment table to identify standard areas such as code segment, read-only data segment, writable data segment, and uninitialized data segment; determine the potential allocation range of heap memory through function call analysis, and mark the starting address and growth direction of stack memory through stack frame layout analysis;
[0027] The code segment, read-only data segment, and global variable region modified by the specified keyword are classified as a first-class region, and their debugging attribute is marked as monitoring abnormal write operations; function stack frames and temporarily allocated stack memory are classified as a second-class region, and their debugging attribute is marked as merged record; writable data segment, uninitialized data segment, and heap memory are classified as a third-class region, and their debugging attribute is marked as fine-grained record; general-purpose registers, program counter, stack pointer, and other CPU status registers are classified as a fourth-class region, and their debugging attribute is marked as snapshot and differential mixed record; a global region mapping table is established between address ranges, region types, and debugging attributes.
[0028] Step 2: The reverse debugger executes the binary file of the target program, obtains the address of the current execution location and records it as the current address, and establishes the first mapping table from the current address to its modification record circular queue. The modification record circular queue stores the modification records of set entries. The modification record includes the trigger instruction sequence number, the modified value, and the retention flag. The retention flag includes retention and filtering. According to the global region mapping table, the region to which the current execution location belongs, the region type, and the debugging attributes are identified, and the region to which it belongs is recorded as the current region.
[0029] If the current region is a type of region, write protection is set for the current region, and exceptions triggered by write operations are captured. When an exception occurs, the destination address of the write operation, the original value in the destination address, the new value to be written, the trigger instruction address, and the exception context are recorded to form the first record. At the same time, a modification record for the current address is generated and added to the tail of the modification record circular queue, and duplicate overwrite filtering is performed.
[0030] If the current region is a type II region, intercept function call and return instructions and detect the boundary, record a stack frame snapshot consisting of stack base address, stack top pointer, function parameters, and key local variables, and use stack-style storage to manage the stack frame snapshots of nested functions;
[0031] If the current region is a type 3 region, for memory modifications, the destination address, the original value at the destination address, the new value to be written, the instruction context, and the thread ID of each write operation are recorded to form a second record. At the same time, the modification record at the current address is added to the tail of the modification record circular queue, and duplicate overwrite filtering is performed. For heap operations, allocation events, release events, and reallocation events also need to be recorded.
[0032] If the current region is a type four region, the instruction records within the set window are used as a set of register group snapshots, and adjacent register group snapshots only record the changes compared to the previous one; if the rate of change of registers in a set number of consecutive register group snapshots is greater than the threshold, the set window is reduced; otherwise, the set window is increased.
[0033] The execution state trajectory consists of the first record, stack frame snapshot, second record, register group snapshot, and first mapping table.
[0034] The process of repeated coverage filtering includes:
[0035] When there are more than a set number of records in the modified record circular queue, calculate the instruction interval between adjacent records in the most recent N records. The instruction interval refers to the number of instructions between two trigger instructions of adjacent records in the program execution sequence. If the instruction interval between all adjacent records is less than the threshold, then set the retention flag of the middle records in the most recent N records (excluding the first and last records) to not be retained; otherwise, set all the most recent N records to be retained.
[0036] When the modified record circular queue is full, if there are records marked as not to be retained, remove these records; otherwise, remove the set number of records at the head of the modified record circular queue.
[0037] Furthermore, the reverse debugger executes the binary file of the target program and constructs a branch instruction history table to store branch instruction addresses, jump counts, non-jump counts, last jump instruction number, last non-jump instruction number, stable state flags, stable direction, and branch instruction opcodes.
[0038] When the currently executing instruction is a branch instruction, the branch instruction history table is queried based on the instruction address. If the entry exists, it is retrieved; otherwise, a new entry is created and added to the branch instruction history table.
[0039] Get the execution result of the current branch instruction. If it is a jump, increment the jump count by 1 and update the last jump instruction number with the instruction number corresponding to the current jump behavior; otherwise, increment the count by 1 and update the last non-jump instruction number with the instruction number corresponding to the current non-jump behavior.
[0040] When the jump count is greater than the threshold and the non-jump count is zero, the stable state is set to stable and the stable direction is set to jump; when the non-jump count is greater than the threshold and the jump count is zero, the stable state is set to stable and the stable direction is set to non-jump; when a stable branch exhibits its first reverse behavior, the stable state is set to unstable and the jump count and non-jump count are reset.
[0041] When the branch is stable, only the branch instruction address, stable direction, and instruction number range of the branch execution instruction are recorded, without recording changes in registers and memory; when the branch is unstable, changes in registers and memory are supplemented by recording the last jump instruction number and the last non-jump instruction number.
[0042] Furthermore, to prevent changes in branch types caused by self-modified code, this invention verifies the consistency between the branch instruction opcode and the actual instruction in memory when querying the branch instruction history table.
[0043] Step 3: For the stack frame snapshot in the execution state trajectory, obtain the stack frame variable address and stack base address, calculate the offset of the stack frame variable relative to the stack base address, and use variable-length encoding to encode the offset. Convert the stack frame variable address into the stack base address and offset encoding. In addition, for the stack frame array, record the address, length and value of the first element, and other elements are represented as relative indexes and value encodings to compress the storage space of the stack frame snapshot.
[0044] For the second record in the execution status trace, a heap memory base address table is established to store the heap memory base address and heap memory size. The table index of the heap memory base address table is the unique number of the heap memory. Variable-length encoding is used to encode the offset between the operation address in the heap memory and the heap memory base address. The operation address in the heap memory is represented by the heap memory base address and offset encoding to compress the storage space of the heap memory. For global variables, they are represented as data pairs consisting of their corresponding symbol ID and offset. The base address is located in the symbol table according to the symbol ID, and then the global variable can be determined by the base address and offset, realizing the compressed storage of global variables. For the value of the variable, sampling is performed to calculate the repetition rate, the continuous increment ratio, and the bit density. When the repetition rate is greater than the threshold, the LZW algorithm (Lempel-Ziv-Welch encoding) is selected. When the continuous increment ratio is greater than the threshold, the difference encoding is selected. When the bit density is less than the threshold, the Huffman encoding is selected. In other cases, a general compression algorithm is selected.
[0045] For register group snapshots in the execution state trajectory, bitmap encoding is used to mark changed registers, and only the changed parts are stored. Differential encoding is combined to optimize the storage overhead of continuous snapshots.
[0046] Among them, the repetition rate is the ratio of the number of times the same value appears to the total number of times, the continuous increment ratio is the ratio of the difference between the subsequent value and the previous value to a fixed step size, and the bit density is the ratio of the number of 1s in the value to the total number of bits. Example
[0047] This embodiment takes x86 and ARM systems as examples, and adopts the reverse debugging incremental recording method based on dynamic layering and predictive filtering provided by this invention. Through dynamic layering recording, predictive filtering, and intelligent compression, it optimizes reverse debugging recording for C and C++ programs, significantly reducing memory overhead while ensuring reverse debugging accuracy. The specific process includes:
[0048] S1. Static analysis and region division before program execution.
[0049] Before the program starts, static analysis tools, such as LLVM-based binary analysis plugins, are used to preprocess the target program's binary file, enabling automatic classification and attribute labeling of memory regions, including:
[0050] S1.1 Region Scanning and Type Identification: Parse the Section Header of the binary file to identify standard regions such as the code segment (.text), read-only data segment (.rodata), writable data segment (.data), and uninitialized data segment (.bss); determine the potential allocation range of heap memory through function call analysis, such as tracing references to malloc or free functions; and mark the starting address and growth direction of stack memory based on stack frame layout analysis, such as push or pop instructions in function prologues.
[0051] S1.2 Define attribute tagging rules:
[0052] The first type (read-only area): includes the code segment .text, the read-only data segment .rodata, and the global variable area modified by the const keyword, which is marked as not recording by default and only monitoring abnormal write operations;
[0053] The second type (short-lived lifespan region): includes function stack frames, such as local variables and function parameters, as well as temporarily allocated stack memory, such as the region allocated by alloca. These are marked as having a lifespan bound to function calls, and modifications made in between can be merged into the records.
[0054] The third type (long-lived region): includes the writable data segment .data, the uninitialized data segment .bss, and the region managed by malloc or free in the heap memory, marked as requiring fine-grained recording of all modifications;
[0055] The fourth type (transient region) includes general-purpose registers such as rax and rbx, CPU status registers such as the program counter rip and stack pointer rsp, which are marked as high-frequency changes and require snapshot and differential mixed recording.
[0056] S1.3 Generate a region mapping table: Store the above classification results as a mapping table between address ranges, types, and attributes for quick querying by the runtime recording module.
[0057] By using static analysis to obtain the lifecycle and access characteristics of memory regions in advance, a basis is provided for subsequent differentiated recording, reducing invalid records for read-only and short-lived regions from the source. Compared with the existing technology based on runtime dynamic judgment, static marking can reduce the performance overhead of real-time analysis.
[0058] S2, Dynamic Hierarchical Recording.
[0059] Based on the region division obtained from S1, a differentiated but logically unified hierarchical recording strategy is designed to address the hardware characteristics of x86 and ARM architectures:
[0060] S2.1, Type 1 (Read-only area) recording strategy.
[0061] S2.1.1 Monitoring Mechanism:
[0062] x86 architecture: Use the WP (Write Protect) flag of the page table entry PTE to set write protection for read-only areas, and capture write operations through the #PF (page fault) exception;
[0063] ARM architecture: Read-only permissions are set through the AP (Access Permission) field of the page table, and write operations are captured through the DataAbort exception.
[0064] S2.1.2 Record Trigger: Record only when a write operation is detected, and the content includes:
[0065] The operation address is a virtual address;
[0066] The original value and the new value, 32-bit or 64-bit, depend on the architecture bit width;
[0067] Trigger instruction address: x86 RIP, ARM PC;
[0068] Exception contexts, such as cs:rip for x86 and ESR_ELx register values for ARM.
[0069] S2.2, Second type (short life cycle area) recording strategy.
[0070] S2.2.1 Function boundary detection:
[0071] x86 architecture: Identifies boundaries by intercepting call function calls and ret function return instructions, recording the stack frame entry after call and the stack frame exit before ret; ARM architecture: Identifies boundaries by intercepting bl branches with links and ret or bx lr instructions, recording the stack frame entry after bl and the stack frame exit before ret.
[0072] S2.2.2 Stack frame snapshot content:
[0073] Stack base address, such as rbp in x86 and fp in ARM, and stack top pointer, such as rsp in x86 and sp in ARM; function parameters, such as those passed through the stack or registers rdi and rsi in x86, and through r0-r3 in ARM; critical local variables, non-temporary variables marked by static analysis.
[0074] S2.2.3 Nested Management: A stack-based snapshot storage method is used for scenarios where function A calls function B:
[0075] When function A is called, such as ARM's bl and x86's call, a snapshot of A's stack frame is pushed onto the stack.
[0076] When function B returns, a snapshot of A is popped and the context is restored.
[0077] S2.3, Third type (long-term lifecycle area) recording strategy.
[0078] S2.3.1 Memory Modification Record: Record the following information for each write operation:
[0079] Address, i.e., virtual address; value before operation, such as old_val and value after operation, such as new_val; instruction context, such as rip for x86 and pc for ARM, instruction opcode; thread ID, suitable for multi-threaded scenarios.
[0080] S2.3.2, Enhanced Heap Operation Records:
[0081] Allocation events: Record the return address, size, and call stack of malloc and new, such as x86 using rbp backtracking and ARM using fp backtracking;
[0082] Release events: Record the target address of free and delete, and the memory value at the time of release;
[0083] Reallocation events: Record the old and new addresses of realloc, size changes, and data migration.
[0084] S2.4, Fourth Type (Instantaneous Region) Recording Strategy.
[0085] S2.4.1, Register Group Snapshot:
[0086] x86 architecture: A complete register set is recorded every 100 instructions, including general-purpose registers RAX-R15, control registers RIP, RSP and RBP, and flag register EFLAGS;
[0087] ARM architecture: A complete register set is recorded every 100 instructions, including general-purpose registers r0-r15, program status registers cpsr and spsr.
[0088] S2.4.2 Differential Recording: Registers that only record changes between two snapshots:
[0089] For example, when rax and rip change in x86, only the new values of these two registers are recorded;
[0090] For example, in ARM, when r0 and pc change, only the new values of these two registers are recorded.
[0091] S2.4.3 Dynamically Adjust Snapshot Interval: If the register change rate exceeds 50% in three consecutive snapshots, the interval will be shortened from 100 instructions to 50 instructions; if the change rate is less than 10%, the interval will be extended to 200 instructions. The register change rate is the ratio of the number of changed registers to the total number of registers.
[0092] To address the hardware characteristics of x86 and ARM, including register sets, instruction sets, and exception mechanisms, an adaptive recording logic is constructed to achieve cross-architecture compatibility. Stack frame snapshots are bound to function boundary detection, and key variables are marked through static analysis, reducing the recording of intermediate stack states by 80% while ensuring backtracking accuracy. The register snapshot interval is dynamically adjusted to optimize the recording density based on the frequency of change, balancing overhead and accuracy.
[0093] S3, Filtering mechanism based on execution prediction.
[0094] By constructing an execution trajectory analysis model that adapts to dual architectures, we can achieve precise filtering of redundant modifications.
[0095] S3.1, Repeat Coverage Prediction Module.
[0096] S3.1.1 Core Data Structure Design:
[0097] / / Single address modification record queue item
[0098] typedef struct {
[0099] uint64_t inst_seq; / / Instruction sequence number (globally incrementing)
[0100] uint64_t value; / / Modified value
[0101] uint8_t is_kept; / / Whether to retain (1=retain, 0=filter)
[0102] ModifyEntry;
[0103] / / Address-Modification Record Mapping Table
[0104] typedef struct {
[0105] void* addr; / / Memory address (key)
[0106] ModifyEntry queue
[50] ; / / Record of the last 50 modifications
[0107] int tail; / / Tail pointer of the queue (circular queue)
[0108] int count; / / Number of valid records
[0109] AddressModifyMap;
[0110] / / Globally modify the trajectory table (implemented using a hash table, with dynamically expandable capacity)
[0111] HashTable* addr_modify_table = create_hash_table(1024); / / Initial capacity 1024
[0112] S3.1.2 Real-time monitoring and filtering process:
[0113] When a write operation occurs at memory address addr, a ModifyEntry is generated, which contains the current instruction number inst_seq and the new value value;
[0114] Query the AddressModifyMap for this address from addr_modify_table: if not found, create a new mapping and insert it into the queue (is_kept=1); if it already exists, insert the new entry into the tail of the queue and update tail and count;
[0115] When count ≥ 3, a filtering decision is triggered: Calculate the instruction interval of the three most recent records: Δ1 = queue[tail].inst_seq - queue[tail-1].inst_seq, Δ2 = queue[tail-1].inst_seq - queue[tail-2].inst_seq; If Δ1 ≤ 10 and Δ2 ≤ 10, mark the middle record as is_kept=0;
[0116] When the queue is full (count=50), remove the earliest record with is_kept=0; otherwise, remove the earliest record with is_kept=1 to ensure queue capacity.
[0117] S3.1.3 Cross-architecture adaptation:
[0118] x86 architecture: Instruction sequence number inst_seq is counted according to the actual executed instructions, and variable-length instructions are supported; ARM architecture: Instruction sequence number is counted according to the instruction cycle, fixed-length 32-bit instructions, and Thumb mode counts 2 16-bit instructions as 1 cycle; Threshold dynamic adjustment: For ARM's higher instruction density Thumb mode, Δ≤10 is adjusted to Δ≤15, because 16-bit instructions execute faster and are modified more frequently within the same cycle.
[0119] S3.2, Branch Stability Prediction Module
[0120] S3.2.1 Branch History Table Design:
[0121] typedef struct {
[0122] uint64_t addr; / / Branch instruction address (key)
[0123] uint32_t taken_count; / / Number of jumps
[0124] uint32_t not_taken_count; / / Number of times not to jump
[0125] uint64_t last_taken_inst; / / Instruction number of the last jump
[0126] uint64_t last_nt_inst; / / The sequence number of the last instruction that did not jump.
[0127] bool is_stable; / / Stable state flag
[0128] uint8_t stable_dir; / / Stable direction (0 = unstable, 1 = jump, 2 = no jump)
[0129] / / Architecture-related fields
[0130] uint8_t arch; / / 0=x86, 1=ARM
[0131] uint8_t opcode; / / Branch instruction opcode (used to verify instruction consistency)
[0132] BranchHistory;
[0133] HashTable* branch_history_table = create_hash_table(512); / / Initial capacity 512
[0134] S3.2.2 Stability Determination and Update Process:
[0135] When a branch instruction is executed, such as je for x86 or beq for ARM, the branch_history_table is queried for BranchHistory. If it is not found, a new entry is created, taken_count=0, not_taken_count=0, and is_stable=false.
[0136] Update the count based on the execution result: If the execution jumps to taken: increment taken_count, and update last_taken_inst = current inst_seq; if the execution jumps to not taken: increment not_taken_count, and update last_nt_inst = current inst_seq.
[0137] Stability determination: When taken_count ≥ 20 and not_taken_count == 0: mark is_stable=true, stable_dir=1; when not_taken_count ≥ 20 and taken_count == 0: mark is_stable=true, stable_dir=2; when reverse behavior occurs in a stable state, such as stable_dir=1 but no jump occurs this time: reset is_stable=false, taken_count=1, not_taken_count=1;
[0138] Recording strategy for stable branches: During the stable period, only the branch instruction address, stable_dir and inst_seq range are recorded, and register and memory changes are not recorded; when restoring the record, the intermediate state is supplemented by executing forward to the current point through last_taken_inst or last_nt_inst.
[0139] S3.2.3 Branch instruction feature adaptation:
[0140] x86 architecture: Conditional jump to JCC, unconditional call, and unconditional jump to JMP are handled separately, and stability prediction is enabled only for JCC.
[0141] ARM architecture: Conditional branches B.cond and linked branches BL are handled separately, and stability prediction is only enabled for B.cond;
[0142] Opcode verification: Each time a query is performed, the opcode is checked to ensure it matches the actual instruction in memory, preventing changes in branch types caused by self-modified code.
[0143] A hybrid structure of circular queue and hash table is adopted to realize O(1) time complexity for querying and filtering modification trajectory, supporting high-frequency memory modification scenarios, such as more than 100,000 times per second; the branch history table adds an opcode verification mechanism to solve the prediction failure problem caused by self-modified code, and the accuracy is improved to 99%; the threshold dynamically adapts to the characteristics of the architecture, such as the instruction density of ARM Thumb mode, and the filtering accuracy remains consistent under different architectures.
[0144] S4, Type-Aware Intelligent Compression.
[0145] Customized compression algorithms are designed for different region types and architectural characteristics:
[0146] S4.1, Type 2 (Stack Frame) Compression.
[0147] Deep adaptation to S4.1.1 and x86 architecture:
[0148] Stack frame structure analysis: At the function entry point, push rbp; mov rbp, rsp, the stack base address rbp is fixed, and the addresses of local variables are rbp-0x8, rbp-0x10, etc., all aligned to 8 bytes;
[0149] Offset encoding: 1-byte uleb128 encoding is used. 1 byte is used for offsets no greater than 127, and 2 bytes are used for offsets between 128 and 255.
[0150] Example: rbp-0x8 is encoded as 0x08, rbp-0x100 is encoded as 0x80 0x01;
[0151] Stack frame array compression: For arrays on a contiguous stack, such as int arr
[10] , record the address and length of the first element, and encode subsequent elements using relative indices and values. The index is represented by 4 bits to support contiguous arrays with up to 16 elements.
[0152] S4.1.2, Deep Adaptation to ARM Architecture:
[0153] Stack frame structure analysis: In ARMv7, push {fp, lr}; mov fp, sp, the local variable address is fp-0x4, fp-0x8, etc.; In ARMv8, the stack frame is based on sp, such as sub sp, sp, #0x20, the variable address is sp+0x8, etc.
[0154] Offset encoding: Uses 2-byte uleb128 encoding, supports offsets no greater than 4095, covering 99% of ARM stack frame scenarios;
[0155] Example: fp-0x10 is encoded as 0x10, sp+0x100 is encoded as 0x80 0x02, and the high bit marks the offset direction;
[0156] Register-passed parameter compression: ARM passes the first 4 parameters through r0-r3, and only stores the 2-bit register index instead of the value when recording.
[0157] S4.2, Third type (heap / global variable) compaction.
[0158] S4.2.1, Address Encoding Enhancement:
[0159] Heap memory base address table: A global table heap_base_table that maintains malloc allocation records, storing base addresses and sizes. Operation addresses are represented by table indexes (1 byte) and offsets (uleb128);
[0160] Example: heap_base_table[3] = 0x7f000000, then 0x7f000008 is encoded as 0x03 0x08, with index 3 and offset 8;
[0161] Global variable symbol mapping: A mapping between symbol names and addresses is established through a symbol table, such as ELF's .symtab, and the symbol ID (2 bytes) and offset are used when recording.
[0162] Example: If the address of global_var is 0x601000, then 0x601004 is encoded as 0x000A 0x04, with symbol ID 10 and offset 4.
[0163] S4.2.2 Automatic Algorithm Selection Mechanism for Value Compression:
[0164] During the feature extraction stage, for 100 consecutive values, such as new_val of the heap modification record, the following features are extracted: repetition rate: the number of times the same value appears / the total number of times (R); continuous increment: the ratio of the later value - the previous value = the fixed step size (S); bit density: the number of 1s in the value / the total number of bits (D).
[0165] Algorithm decision logic:
[0166] If R ≥ 0.3, it indicates a large number of duplicate values: select the LZW algorithm and use the duplicate patterns to build a dictionary;
[0167] If S ≥ 0.5, it indicates that the continuous increment is obvious: select difference encoding, and record the initial value and step size;
[0168] If D < 0.2, it indicates a sparse bit distribution: choose Huffman coding and optimize for high-frequency 0 bits;
[0169] Otherwise: Choose the LZ77 algorithm;
[0170] Dynamic switching mechanism: Features are recalculated every 1000 values, and the algorithm is automatically switched when the feature changes by more than 20%.
[0171] S4.2.3, x86 / ARM universal value adaptation:
[0172] 32-bit values, such as ARM's r0-r3 and x86's eax: use 32-bit mode compression, and the Huffman tree is constructed based on 32-bit values; 64-bit values, such as x86's rax and ARMv8's x0-x7: use 64-bit mode compression, and automatically convert the case where the high 32 bits are 0 to 32-bit encoding.
[0173] Example: The 64-bit value 0x0000000012345678 of x86 is automatically compressed to the 32-bit value 0x12345678, saving 50% of space.
[0174] S4.3, Fourth Type (Register) Compression.
[0175] S4.3.1, x86 register compression details:
[0176] Register set classification: 16 general-purpose registers such as RAX-R15, 3 control registers such as RIP, RSP, or RBP, and 1 flag register such as EFLAGS, for a total of 20 registers that need to be monitored;
[0177] Bitmap encoding: Represented using a 32-bit integer, requiring only 20 bits. Bit 0 corresponds to rax, bit 16 corresponds to rip, and bit 19 corresponds to eflags.
[0178] Flag register optimization: Only the changing flag bits (such as CF / ZF / SF) are recorded in eflags, and stored in 1 byte (instead of the full 8 bytes);
[0179] Example: Changes in rax (bit0) and rip (bit16) → bitmap=0x00010001, storing 0x00010001 + new value of rax + new value of rip.
[0180] S4.3.2, ARM Register Compression Details:
[0181] Register set classification: 16 general-purpose registers (r0-r15) (including pc=r15), 1 program status register (cpsr), for a total of 17 registers that need to be monitored;
[0182] Bitmap encoding: Represented by a 32-bit integer (only 17 bits are needed), with bit 0 corresponding to r0, bit 15 corresponding to pc (r15), and bit 16 corresponding to cpsr;
[0183] CPSR optimization: Only record 4 flag bits: N (negative), Z (zero), C (carry), and V (overflow), and store them with 4 bits (instead of the full 4 bytes);
[0184] Example: r0 (bit0) and pc (bit15) change → bitmap=0x80000001, store 0x80000001 + new value of r0 + new value of pc.
[0185] S4.3.3, Cross-architecture differential coding:
[0186] Calculate the XOR result (current_val ^ last_val) for the register values of consecutive snapshots.
[0187] If the XOR result contains 24 consecutive 0 bits (3 bytes), then use "mask + valid bits" encoding (only store non-zero bits);
[0188] Example: The x86 rax changes from 0x12345678 to 0x12345679, the XOR result is 0x00000001, and the encoding is 0x01 0x01 (mask + valid bits).
[0189] Stack frame compression, combined with the architecture's unique stack layout, such as alignment and base address registers, achieves over 90% address storage optimization; the dynamic algorithm selection mechanism based on value features improves the average compression rate by 25% compared to a single algorithm and is compatible with 32 / 64-bit cross-architecture data; the register bitmap adopts an on-demand bit allocation design, saving 40% and 50% of metadata storage for x86 and RM respectively, while preserving complete state recoverability.
[0190] Compared with existing technologies, this invention has the following advantages: Significantly reduced memory overhead, with 0% reduction in intermediate states through cross-architecture layered recording, 0% to 50% reduction in redundancy through intelligent filtering, and a 30% improvement in compression ratio through instruction set-aware compression, resulting in a 50% to 80% reduction in overall memory usage compared to reverse engineering (RR); In terms of cross-architecture compatibility, adaptation logic is designed for the instruction sets, registers, and stack layout characteristics of x86 and ARM, supporting reverse debugging of mainstream architectures; High reproducibility, with steps detailed to specific data structures and algorithms, including address encoding rules and compression index formats, facilitating developer implementation according to descriptions; Optimized debugging experience, with dynamically adjusted recording density and on-demand decompression mechanisms improving reverse debugging response speed by over 40%.
[0191] In summary, the above are merely preferred embodiments of the present invention and are not intended to limit the scope of protection of the present invention. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of the present invention should be included within the scope of protection of the present invention.
Claims
1. A reverse debugging incremental recording method based on dynamic hierarchical and predictive filtering, characterized in that, Specifically, the following steps are included: Parse the segment table of the target program's binary file to identify the code segment, read-only data segment, writable data segment, and uninitialized data segment, determine the potential allocation range of heap memory, and mark the starting address and growth direction of stack memory; The code segment, read-only data segment, and global variable area modified by the set keyword are classified as the first type of area; the function stack frame and temporarily allocated stack memory are classified as the second type of area; the writable data segment, uninitialized data segment, and heap memory are classified as the third type of area; and the CPU status register is classified as the fourth type of area. The debugging attributes of the above areas are marked; and a global area mapping table between address range, area type and debugging attributes is established. The reverse debugger executes the target program to obtain the current address, establishes the first mapping table from the current address to the circular queue of modification records, and obtains the current region to which the current address belongs from the global region mapping table; If the current region is a Class I region, abnormal write operations are monitored to form a first record, the modified record is added to the modified record circular queue, and duplicate overwrite filtering is performed; if the current region is a Class II region, the records are merged to form a stack frame snapshot; if the current region is a Class III region, memory modifications are performed to form a second record, the modified record is added to the modified record circular queue, duplicate overwrite filtering is performed, and allocation events, release events, and reallocation events are recorded for heap operations; if the current region is a Class IV region, a register group snapshot is recorded; the execution state trajectory is composed of the first record, stack frame snapshot, second record, register group snapshot, and first mapping table. The execution status trajectory is compressed based on the type of data-related region.
2. The reverse debugging incremental recording method according to claim 1, characterized in that, The method for identifying the code segment, read-only data segment, writable data segment, and uninitialized data segment in the segment table of the target program's binary file is as follows: the binary file of the target program is preprocessed using a static analysis tool.
3. The reverse debugging incremental recording method according to claim 1, characterized in that, The method for determining the potential allocation range of heap memory is as follows: function call analysis is performed on the binary file of the target program.
4. The reverse debugging incremental recording method according to claim 1, characterized in that, The first record is formed when an exception occurs by recording the destination address of the write operation, the original value in the destination address, the new value to be written, the trigger instruction address, and the exception context.
5. The reverse debugging incremental recording method according to claim 1, characterized in that, The stack frame snapshot includes the stack base address, stack top pointer, function parameters, and key local variables.
6. The reverse debugging incremental recording method according to claim 1, characterized in that, The second record includes the destination address, the original value at the destination address, the new value to be written, the instruction context, and the thread ID for each write operation.
7. The reverse debugging incremental recording method according to claim 1, characterized in that, The process of recording the register group snapshot is as follows: the instruction records within the set window are used as a group to record the register group snapshot, and adjacent register group snapshots only record the changes compared to the previous one; if the rate of change of registers in a set number of consecutive register group snapshots is greater than a threshold, the set window is reduced; otherwise, the set window is increased.
8. The reverse debugging incremental recording method according to claim 1, characterized in that, The implementation of the duplicate coverage filtering is as follows: when there are more than a set number of records in the modified record circular queue, the instruction interval between adjacent records in the most recent N records is calculated. The instruction interval is the number of instruction intervals between the two trigger instructions of adjacent records in the program execution sequence. If the instruction interval between all adjacent records is less than the threshold, the retention flag of the middle records in the most recent N records other than the first and last records is set to not be retained; otherwise, all the most recent N records are set to be retained. When the modified record circular queue is full, if there are records marked as not to be retained, remove these records; otherwise, remove the set number of records at the head of the modified record circular queue.
9. The reverse debugging incremental recording method according to claim 1, characterized in that, For a stack frame snapshot, obtain the stack frame variable address and stack base address, calculate the offset of the stack frame variable relative to the stack base address, encode the offset using variable-length encoding, and convert the stack frame variable address into the stack base address and offset encoding; for the stack frame array, record the address, length and value of the first element, and represent other elements as relative indexes and value encodings.
10. The reverse debugging incremental recording method according to claim 1, characterized in that, For the second record, a heap memory base address table is established to store the heap memory base address and the heap memory size. The table index of the heap memory base address table is a unique number of the heap memory. Variable-length encoding is used to encode the offset between the operation address in the heap memory and the heap memory base address. The operation address in the heap memory is represented by the heap memory base address and offset encoding. For global variables, they are represented as data pairs consisting of their corresponding symbol ID and offset. For the values of variables, the sampling calculates the repetition rate, the continuous increment ratio, and the bit density. When the repetition rate is greater than the threshold, the LZW algorithm is selected. When the continuous increment ratio is greater than the threshold, the difference coding is selected. When the bit density is less than the threshold, the Huffman coding is selected. In other cases, a general compression algorithm is used.
Citation Information
Patent Citations
Dynamic taint analysis device and application thereof to document format reverse analysis
CN103440201A
Instruction conversion context switching optimization method based on stack frame hierarchical compression
CN119829133A