Machine Code Integrity via Static Verification and Stack Separation

Resolve Bottlenecks,
Find Innovative Solutions
Generate Solutions

Solution Overview

Problem

Existing software security solutions, such as reference monitors, fail to effectively prevent insidious memory accesses within a program and do not account for practical software characteristics like multi-threading, dynamic memory allocation, and control flow transitions, leading to difficulties in ensuring memory access integrity.

Innovation Solution

A verification system that performs static and dynamic checks on machine code to ensure proper control flow integrity and memory access, using a verifier and a code rewriter to generate protected code modules with guards that enforce safe execution, separating data and control stacks, and implementing memory-range guards for efficient memory protection.

Engineering Contradictions & Design Principles

VSEngineering Contradiction Analysis

1Reliability

If reference monitors are inserted into hardware systems to observe memory accesses, then memory access integrity between different programs is improved, but the system cannot prevent insidious memory accesses within the same program and the device complexity increases

Engineering Contradiction:
Improvememory access integrityVSAvoidsystem complexity
Core Design Contradiction:
ReliabilityVSDevice complexity

Solution Approach 1:

The patent segments memory protection into two layers: (1) hardware reference monitors that enforce coarse-grained memory access control between different programs, and (2) software-based fine-grained protection mechanisms including control flow integrity checks and memory access logs that operate within each program. This segmentation allows the hardware to handle inter-program protection while software handles intra-program protection, resolving the contradiction between improving memory access integrity and reducing system complexity.

Inventive Principle:
Principle #1Segmentation

Solution Approach 2:

The patent introduces software-based intermediaries (control flow integrity monitors, memory access logging mechanisms, and verification systems) that act as mediators between the hardware reference monitor and the program code. These intermediaries capture and verify memory access patterns, control flow transitions, and function calls, enabling fine-grained protection without requiring direct hardware intervention for every memory access, thus improving reliability while managing complexity.

Inventive Principle:
Principle #24Intermediary (Mediator)

2Reliability

If software-based solutions are implemented to address reference monitor limitations, then intra-program memory access protection is improved, but the solutions fail to account for practical software characteristics like multi-threading and dynamic memory allocation

Engineering Contradiction:
Improveintra-program memory access protectionVSAvoidcompatibility with software characteristics
Core Design Contradiction:
ReliabilityVSAdaptability or versatility

Solution Approach 1:

The patent implements dynamic protection mechanisms that adapt to runtime software characteristics. The control flow integrity system dynamically tracks function calls and returns, adjusting protection based on the current execution context. Memory access logs are dynamically created and verified for each thread and memory region, allowing the system to accommodate multi-threading, dynamic memory allocation, and control flow transitions while maintaining intra-program memory access protection.

Inventive Principle:
Principle #15Dynamics

Solution Approach 2:

The patent changes key parameters of the protection mechanism from static to dynamic. Instead of fixed protection rules, the system uses runtime-verifiable properties that change based on execution state, including thread ID, memory region, control flow context, and access pattern. This allows the protection system to adapt to various software characteristics while maintaining security, resolving the contradiction between reliability and adaptability.

Inventive Principle:
Principle #35Parameter changes

3Reliability

If static verification is performed on machine code to ensure proper operations on shared state, then code integrity is improved, but the verification overhead and execution time increase

Engineering Contradiction:
Improvecode integrityVSAvoidexecution efficiency
Core Design Contradiction:
ReliabilityVSProductivity

Solution Approach 1:

The patent performs static verification of machine code before execution to establish verified properties such as control flow integrity, memory access patterns, and function call/return relationships. This preliminary action creates a verification log that is executed once during code loading, ensuring code integrity without requiring continuous verification during execution, thus improving reliability while minimizing verification overhead.

Inventive Principle:
Principle #10Preliminary action

Solution Approach 2:

The patent uses the static verification results to enable continuous efficient execution. The verified properties are cached and used throughout execution, allowing the system to maintain code integrity guarantees without repeating the expensive verification process. The verification log is generated once and then used continuously, resolving the contradiction between code integrity and execution efficiency.

Inventive Principle:
Principle #20Continuity of useful action

Data Source

PatentUS8104021B2Verifiable integrity guarantees for machine code programs
Publication Date: 2012.01.24 MICROSOFT TECHNOLOGY LICENSING LLC
  • US8104021B2 patent drawing
  • US8104021B2 patent drawing
  • US8104021B2 patent drawing

AI summary

A verifier performs static checks of machine code to ensure that the code will execute safely. After verification is performed, the code is executed. The code modules generated by the rewriter and verified by the verifier prevent runtime code modifications so that properties established by the verifier cannot be invalidated during execution. Guards ensure that control flows only as expected. Stack data that must be shared within a code module, and which may therefore be corrupted during execution, is placed on a separate data stack. Other stack data remains on the regular execution stack, called the control stack. Multiple memory accesses can be checked by a single memory-range guard, optimized for fast access to the most-frequently used memory.