package binsec
Semantic analysis of binary executables
Install
Dune Dependency
Authors
-
AAdel Djoudi
-
BBenjamin Farinier
-
CChakib Foulani
-
DDorian Lesbre
-
FFrédéric Recoules
-
GGuillaume Girol
-
JJosselin Feist
-
LLesly-Ann Daniel
-
MManh-Dung Nguyen
-
MMathéo Vergnolle
-
MMathilde Ollivier
-
MMatthieu Lemerre
-
OOlivier Nicole
-
RRichard Bonichon
-
RRobin David
-
SSébastien Bardin
-
SSoline Ducousso
-
TTa Thanh Dinh
-
YYaëlle Vinçont
Maintainers
Sources
binsec-0.6.0.tbz
sha256=e9101e68d317c837d5cff9608c6fba2127dd31ef6373b9b90806780c1d80bb52
sha512=c01af277239b8cc84fb904c301897f7d2388a8c850c7cb6a53acb8a4f8d51115c8a595c5517843d076421a76f4b2becb16e722b4c90f19a8fa208cce5f3ba274
doc/src/binsec.smt/smt_symbolic.ml.html
Source file smt_symbolic.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
(**************************************************************************) (* This file is part of BINSEC. *) (* *) (* Copyright (C) 2016-2022 *) (* CEA (Commissariat à l'énergie atomique et aux énergies *) (* alternatives) *) (* *) (* you can redistribute it and/or modify it under the terms of the GNU *) (* Lesser General Public License as published by the Free Software *) (* Foundation, version 2.1. *) (* *) (* It is distributed in the hope that it will be useful, *) (* but WITHOUT ANY WARRANTY; without even the implied warranty of *) (* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) (* GNU Lesser General Public License for more details. *) (* *) (* See the GNU Lesser General Public License version 2.1 *) (* for more details (enclosed in the file licenses/LGPLv2.1). *) (* *) (**************************************************************************) open Smt_options let byte_size = Natural.to_int Basic_types.Constants.bytesize module F = struct let full name index = name ^ "_" ^ string_of_int index let memory = "__memory" let full_mem = full memory let memory_type word_size = Formula.ax_sort word_size byte_size let pc = "__pc" let full_pc = full pc let var name = let open Formula in function | BlSort -> BlVar (bl_var name) | BvSort i -> BvVar (bv_var name i) | AxSort (i, j) -> AxVar (ax_var name i j) let decl = let open Formula in function | BlVar v -> mk_bl_decl v [] | BvVar v -> mk_bv_decl v [] | AxVar v -> mk_ax_decl v [] let def value var = let open Formula in match (value.term_desc, var) with | BlTerm value, BlVar v -> mk_bl_def v [] value | BvTerm value, BvVar v -> mk_bv_def v [] value | AxTerm value, AxVar v -> mk_ax_def v [] value | _ -> failwith "F.def has incompatible types" end (* global mutable state to assign unique indices *) let next_index = ref 0 let mk_index () = next_index := !next_index + 1; !next_index (* variable bindings but one per branch *) module State = struct module S = Basic_types.String.Map module B = Bitvector.Collection.Map type infos = int * Formula.sort (* index, type *) type t = { fml : Formula.formula; var_infos : infos S.t; initialisation : int B.t; (* list of memory locations to read *) uncontrolled : Formula.VarSet.t; } let add_entry entry state = let fml = Formula.push_front entry state.fml in { state with fml } let add_uncontrolled var st = { st with uncontrolled = Formula.VarSet.add var st.uncontrolled } let havoc ?(wild = false) name var_type state = let open Formula in let index = mk_index () in let var = F.var (F.full name index) var_type in let declaration = F.decl var in let var_infos = S.add name (index, var_type) state.var_infos in let state' = add_entry (mk_declare declaration) { state with var_infos } in if wild then add_uncontrolled var state' else state' let declare ?wild name var_type state = if S.mem name state.var_infos then failwith "variable already declared"; havoc ?wild name var_type state let assign ?(wild = false) name var_type value state = let open Formula in (match S.find name state.var_infos with | _, vtype when vtype <> var_type -> failwith "Store.get_last_index with wrong type" | _ -> () | exception Not_found -> ()); let index = mk_index () in let var = F.var (F.full name index) var_type in let definition = F.def value var in let var_infos = S.add name (index, var_type) state.var_infos in let state' = add_entry (mk_define definition) { state with var_infos } in if wild then add_uncontrolled var state' else state' let create () = let open Formula in let fml = Formula.empty and var_infos = S.singleton F.memory (0, F.memory_type (Kernel_options.Machine.word_size ())) in let initialisation = B.empty in let uncontrolled = Formula.VarSet.empty in let self = { fml; var_infos; initialisation; uncontrolled } in assign F.pc bl_sort (mk_bl_term mk_bl_true) self let initializations st = st.initialisation let comment cmt state = add_entry (Formula.mk_comment cmt) state let pp ppf state = let open Format in fprintf ppf "@[<v 0># State var_infos @ @[<hov 0>%a@]@]" (fun ppf m -> S.iter (fun name (n, _) -> fprintf ppf "%s:%d;@ " name n) m) state.var_infos let get_last_index state name var_type = match S.find name state.var_infos with | _, v when v <> var_type -> failwith "State.get_last_index with wrong type" | n, _ -> n let get_memory state = let word_size = Kernel_options.Machine.word_size () in let index = get_last_index state F.memory (F.memory_type word_size) in let name = F.full_mem index in Formula.(mk_ax_var (ax_var name word_size byte_size)) let get_path_constraint state = let index = get_last_index state F.pc Formula.bl_sort in let name = F.full_pc index in Formula.(mk_bl_var (bl_var name)) let constrain cond state = let open Formula in let current_pc = get_path_constraint state in let pc = mk_bl_and current_pc cond in assign F.pc bl_sort (mk_bl_term pc) state let get_bv name size state = let sort = Formula.bv_sort (Size.Bit.to_int size) in let index, state'' = match get_last_index state name sort with | n -> (n, state) | exception Not_found -> let state' = declare (*FIXME wild ? *) name sort state in (get_last_index state' name sort, state') in let name = F.full name index in let value = Formula.(mk_bv_var (bv_var name (Size.Bit.to_int size))) in (value, state'') let init_mem_at ~addr ~size state = { state with initialisation = B.add addr size state.initialisation } let get_entries state = let open Formula in let word_size = Kernel_options.Machine.word_size () in let var = F.(var memory (memory_type word_size)) in let declaration = F.decl var in let symbolic_memory = mk_ax_var (ax_var F.memory word_size byte_size) in let read_bitvector addr sz = let b = Buffer.create (2 * sz) in (* The loop below is little-endian *) let rec loop offset = if offset < 0 then ( let v = Z.of_string ("0x" ^ Buffer.contents b) in let bv = Bitvector.create v (byte_size * sz) in Logger.debug ~level:5 "[sse] C bitvector %s (%d): %a" (Z.to_string v) sz Bitvector.pp_hex bv; bv) else let off_bv = Bitvector.of_int ~size:word_size offset in let load_addr = Bitvector.add addr off_bv in let img = Kernel_functions.get_img () in let byte = Loader_utils.get_byte_at img load_addr in let byte_str = Format.sprintf "%02x" byte in Buffer.add_string b byte_str; loop (offset - 1) in loop (sz - 1) in let load_at addr size mem = assert (word_size = Bitvector.size_of addr); mk_store size mem (mk_bv_cst addr) (mk_bv_cst (read_bitvector addr size)) in let initial_memory_value = mk_ax_term (B.fold load_at state.initialisation symbolic_memory) in let definition = F.var (F.full_mem 0) (F.memory_type word_size) |> F.def initial_memory_value in state.fml |> Formula.push_back_define definition |> Formula.push_back_declare declaration let formula state = Formula.push_front_assert (get_path_constraint state) (get_entries state) let uncontrolled st = st.uncontrolled let memory_term fml = ( F.memory, F.memory_type (Kernel_options.Machine.word_size ()), Formula.mk_ax_term fml ) end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>