Results 1 - 10
of
16
WYSINWYX: What You See Is Not What You eXecute
, 2009
"... Over the last seven years, we have developed static-analysis methods to recover a good approximation to the variables and dynamically-allocated memory objects of a stripped executable, and to track the flow of values through them. The paper presents the algorithms that we developed, explains how the ..."
Abstract
-
Cited by 33 (7 self)
- Add to MetaCart
Over the last seven years, we have developed static-analysis methods to recover a good approximation to the variables and dynamically-allocated memory objects of a stripped executable, and to track the flow of values through them. The paper presents the algorithms that we developed, explains how they are used to recover intermediate representations (IRs) from executables that are similar to the IRs that would be available if one started from source code, and describes their application in the context of program understanding and automated bug hunting. Unlike algorithms for analyzing executables that existed prior to our work, the ones presented in this paper provide useful information about memory accesses, even in the absence of debugging information. The ideas described in the paper are incorporated in a tool for analyzing Intel x86 executables, called CodeSurfer/x86. CodeSurfer/x86 builds a system dependence graph for the program, and provides a GUI for exploring the graph by (i) navigating its edges, and (ii) invoking operations, such as forward slicing, backward slicing, and chopping, to discover how parts of the program can impact other parts. To assess the usefulness of the IRs recovered by CodeSurfer/x86 in the context of automated bug hunting, we built a tool on top of CodeSurfer/x86, called Device-Driver Analyzer for x86
A Logic of Secure Systems and its Application to Trusted Computing
"... We present a logic for reasoning about properties of secure systems. The logic is built around a concurrent programming language with constructs for modeling machines with shared memory, a simple form of access control on memory, machine resets, cryptographic operations, network communication and dy ..."
Abstract
-
Cited by 11 (2 self)
- Add to MetaCart
We present a logic for reasoning about properties of secure systems. The logic is built around a concurrent programming language with constructs for modeling machines with shared memory, a simple form of access control on memory, machine resets, cryptographic operations, network communication and dynamically loading and executing unknown (and potentially untrusted) code. The adversary’s capabilities are constrained by the system interface as defined in the programming model (leading to the name CSI-ADVERSARY). We develop a sound proof system for reasoning about programs, without explicitly reasoning about adversary actions. This form of reasoning was particularly difficult to codify for dynamically loaded unknown pieces of code. We use the logic to characterize trusted computing primitives and prove code integrity and execution integrity properties of two remote attestation protocols. The proofs make precise assumptions needed for the security of these protocols and reveal a surprising insecure interaction between the two protocols. 1
Verified Just-In-Time Compiler on x86
"... This paper presents a method for creating formally correct just-intime (JIT) compilers. The tractability of our approach is demonstrated through, what we believe is the first, verification of a JIT compiler with respect to a realistic semantics of self-modifying x86 machine code. Our semantics inclu ..."
Abstract
-
Cited by 10 (1 self)
- Add to MetaCart
This paper presents a method for creating formally correct just-intime (JIT) compilers. The tractability of our approach is demonstrated through, what we believe is the first, verification of a JIT compiler with respect to a realistic semantics of self-modifying x86 machine code. Our semantics includes a model of the instruction cache. Two versions of the verified JIT compiler are presented: one generates all of the machine code at once, the other one is incremental i.e. produces code on-demand. All proofs have been performed inside the HOL4 theorem prover.
Combining domain-specific and foundational logics to verify complete software systems
, 2008
"... A major challenge for verifying complete software systems is their complexity. A complete software system consists of program modules that use many language features and span different abstraction levels (e.g., user code and run-time system code). It is extremely difficult to use one verification s ..."
Abstract
-
Cited by 8 (4 self)
- Add to MetaCart
A major challenge for verifying complete software systems is their complexity. A complete software system consists of program modules that use many language features and span different abstraction levels (e.g., user code and run-time system code). It is extremely difficult to use one verification system (e.g., type system or Hoare-style program logic) to support all these features and abstraction levels. In our previous work, we have developed a new methodology to solve this problem. We apply specialized “domain-specific ” verification systems to verify individual program modules and then link the modules in a foundational open logical framework to compose the verified complete software package. In this paper, we show how this new methodology is applied to verify a software package containing implementations of preemptive threads and a set of synchronization primitives. Our experience shows that domain-specific verification systems can greatly simplify the verification process of low-level software, and new techniques for combining domain-specific and foundational logics are critical for the successful verification of complete software systems.
A Simple Model of Separation Logic for Higher-order Store
"... Abstract. Separation logic is a Hoare-style logic for reasoning about pointer-manipulating programs. Its core ideas have recently been extended from low-level to richer, high-level languages. In this paper we develop a new semantics of the logic for a programming language where code can be stored (i ..."
Abstract
-
Cited by 7 (3 self)
- Add to MetaCart
Abstract. Separation logic is a Hoare-style logic for reasoning about pointer-manipulating programs. Its core ideas have recently been extended from low-level to richer, high-level languages. In this paper we develop a new semantics of the logic for a programming language where code can be stored (i.e., with higher-order store). The main improvement on previous work is the simplicity of the model. As a consequence, several restrictions imposed by the semantics are removed, leading to a considerably more natural assertion language with a powerful specification logic. 1
Directed proof generation for machine code
, 2010
"... Abstract. We present the algorithms used in MCVETO (Machine-Code VErification TOol), a tool to check whether a stripped machinecode program satisfies a safety property. The verification problem that MCVETO addresses is challenging because it cannot assume that it has access to (i) certain structures ..."
Abstract
-
Cited by 3 (2 self)
- Add to MetaCart
Abstract. We present the algorithms used in MCVETO (Machine-Code VErification TOol), a tool to check whether a stripped machinecode program satisfies a safety property. The verification problem that MCVETO addresses is challenging because it cannot assume that it has access to (i) certain structures commonly relied on by source-code verification tools, such as control-flow graphs and call-graphs, and (ii) metadata, such as information about variables, types, and aliasing. It cannot even rely on out-of-scope local variables and return addresses being protected from the program’s actions. What distinguishes MCVETO from other work on software model checking is that it shows how verification of machine-code can be performed, while avoiding conventional techniques that would be unsound if applied at the machine-code level. 1
A Kripke Logical Relation Between ML and Assembly
"... There has recently been great progress in proving the correctness of compilers for increasingly realistic languages with increasingly realistic runtime systems. Most work on this problem has focused on proving the correctness of a particular compiler, leaving open the question of how to verify the c ..."
Abstract
-
Cited by 3 (3 self)
- Add to MetaCart
There has recently been great progress in proving the correctness of compilers for increasingly realistic languages with increasingly realistic runtime systems. Most work on this problem has focused on proving the correctness of a particular compiler, leaving open the question of how to verify the correctness of assembly code that is hand-optimized or linked together from the output of multiple compilers. This has led Benton and other researchers to propose more abstract, compositional notions of when a low-level program correctly realizes a high-level one. However, the state of the art in so-called “compositional compiler correctness ” has only considered relatively simple high-level and low-level languages. In this paper, we propose a novel, extensional, compilerindependent notion of equivalence between high-level programs in an expressive, impure ML-like λ-calculus and low-level programs in an (only slightly) idealized assembly language. We define this equivalence by means of a biorthogonal, step-indexed, Kripke logical relation, which enables us to reason quite flexibly about assembly code that uses local state in a different manner than the high-level code it implements (e.g., self-modifying code). In contrast to prior work, we factor our relation in a symmetric, languagegeneric fashion, which helps to simplify and clarify the formal presentation, and we also show how to account for the presence of a garbage collector. Our approach relies on recent developments in Kripke logical relations for ML-like languages, in particular the idea of possible worlds as state transition systems. 1.
Language-Independent Sandboxing of Just-In-Time Compilation and Self-Modifying Code
"... When dealing with dynamic, untrusted content, such as on the Web, software behavior must be sandboxed, typically through use of a language like JavaScript. However, even for such speciallydesigned languages, it is difficult to ensure the safety of highlyoptimized, dynamic language runtimes which, fo ..."
Abstract
-
Cited by 2 (2 self)
- Add to MetaCart
When dealing with dynamic, untrusted content, such as on the Web, software behavior must be sandboxed, typically through use of a language like JavaScript. However, even for such speciallydesigned languages, it is difficult to ensure the safety of highlyoptimized, dynamic language runtimes which, for efficiency, rely on advanced techniques such as Just-In-Time (JIT) compilation, large libraries of native-code support routines, and intricate mechanisms for multi-threading and garbage collection. Each new runtime provides a new potential attack surface and this security risk raises a barrier to the adoption of new languages for creating untrusted content. Removing this limitation, this paper introduces general mechanisms for safely and efficiently sandboxing software, such as dynamic language runtimes, that make use of advanced, lowlevel
Verification of Machine Code Implementations of Arithmetic Functions for Cryptography
"... Abstract. This report presents a methodology and some preliminary results for verification of machine code implementations of cryptographic operations. Modularity and reusability of proofs is emphasised. 1 ..."
Abstract
-
Cited by 2 (0 self)
- Add to MetaCart
Abstract. This report presents a methodology and some preliminary results for verification of machine code implementations of cryptographic operations. Modularity and reusability of proofs is emphasised. 1
Verification of Unloadable Modules
"... load and unload modules. For example, some operating system kernels support dynamic loading and unloading of device drivers. This causes specific difficulties in the verification of such programs and modules; in particular, it must be verified that no functions or global variables from the module ar ..."
Abstract
-
Cited by 1 (0 self)
- Add to MetaCart
load and unload modules. For example, some operating system kernels support dynamic loading and unloading of device drivers. This causes specific difficulties in the verification of such programs and modules; in particular, it must be verified that no functions or global variables from the module are used after the module is unloaded. We present the approach we used to add support for loading and unloading modules to our separation-logic-based program verifier VeriFast. Our approach to the specification and verification of function pointer calls, based on parameterizing function types by predicates, is sound in the presence of unloading, but at the same time does not complicate the verification of programs that perform no unloading, and does not require callers to distinguish between function pointers that point into unloadable modules and ones that do not. We offer a machine-checked formalization and soundness proof and we report on verifying a small kernel-like program using VeriFast. To the best of our knowledge, ours is the first approach for sound modular verification of C programs that load and unload modules. 1

