Commits

Carl Pulley  committed b59fbbe

Added in ability for usedef etc. to return python values.

  • Participants
  • Parent commits 885afb8

Comments (0)

Files changed (6)

File ocaml/Makefile

 
 # Build everything
 all:
-	$(OCAMLFIND) $(OCAMLC) -g -predicates $(PACKS) -package $(PACKS) -linkpkg -thread -output-obj -o bap.o $(INCLUDES) $(SRC) volatility.ml bap_ast.ml bap_cfg.ml bap_ssa.ml codegen.ml topredicate.ml iltrans.ml bap.ml
+	$(OCAMLFIND) $(OCAMLC) -g -predicates $(PACKS) -package $(PACKS) -linkpkg -thread -output-obj -o bap.o $(INCLUDES) $(SRC) volatility.ml bap_ast.ml bap_cfg.ml bap_ssa.ml bap_stp.ml codegen.ml topredicate.ml iltrans.ml bap.ml
 
 # Clean up
 clean:

File ocaml/bap.ml

   | Iltrans.Ssa(ssa) ->
       Bap_ssa.to_python(ssa)
 
-let model_to_python = function
-  | Some interp ->
-      let maplet_to_python (s, i) = PyTuple [| PyString s; Bap_ast.big_int_to_python i |] in
-        PyList(List.map maplet_to_python interp)
-  | None ->
-      PyNone
-
 let _ = Callback.register "apply_cmd" (fun cmd_opts ast_term -> 
   let filtered_cmds = List.filter (fun cmd -> Array.length cmd >= 2 && cmd.(0) <> "control") cmd_opts in
   let term, model, wp, foralls = if List.length filtered_cmds = 0 then (Iltrans.Ast ast_term, None, None, None) else exception_wrapper(fun () -> apply_cmd filtered_cmds (Iltrans.Ast ast_term, None, None, None)) in
     flush_all();
     if List.mem [| "control"; "-return" |] cmd_opts then (
-      if BatOption.is_some model then (
-        if BatOption.is_some wp then
-          PyDict [ (PyString "term", bap_to_python term); (PyString "model", model_to_python(BatOption.get model)); (PyString "wp", PyDict [ (PyString "pre", Bap_ast.exp_to_python(BatOption.get wp)); (PyString "foralls", Bap_ast.vars_to_python(BatOption.get foralls)) ]) ]
-        else
-          PyDict [ (PyString "term", bap_to_python term); (PyString "model", model_to_python(BatOption.get model)) ]
-      ) else (
-        if BatOption.is_some wp then
-          PyDict [ (PyString "term", bap_to_python term); (PyString "wp", PyDict [ (PyString "pre", Bap_ast.exp_to_python(BatOption.get wp)); (PyString "foralls", Bap_ast.vars_to_python(BatOption.get foralls)) ]) ]
-        else
-          PyDict [ (PyString "term", bap_to_python term) ]
-      )
+      let result_list = ref [ (PyString "term", bap_to_python term) ] in
+        if List.length !Iltrans.result > 0 then result_list := !Iltrans.result @ !result_list;
+        if BatOption.is_some model then result_list := (PyString "model", Bap_stp.to_python(BatOption.get model)) :: !result_list;
+        if BatOption.is_some wp then result_list := (PyString "wp", PyDict [ (PyString "pre", Bap_ast.exp_to_python(BatOption.get wp)); (PyString "foralls", Bap_ast.vars_to_python(BatOption.get foralls)) ]) :: !result_list;
+        PyDict !result_list
     ) else
         PyNone
 )

File ocaml/bap_stp.ml

+(* bap_stp.ml                                                              *)
+(* Copyright (C) 2013 Carl Pulley <c.j.pulley@hud.ac.uk>                   *)
+(*                                                                         *)
+(* This program is free software; you can redistribute it and/or modify    *)
+(* it under the terms of the GNU General Public License as published by    *)
+(* the Free Software Foundation; either version 2 of the License, or (at   *)
+(* your option) any later version.                                         *)
+(*                                                                         *)
+(* This program 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        *)
+(* General Public License for more details.                                *)
+(*                                                                         *)
+(* You should have received a copy of the GNU General Public License       *)
+(* along with this program; if not, write to the Free Software             *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *)
+
+open Volatility
+
+let to_python = function
+  | Some interp ->
+      let maplet_to_python (s, i) = (PyString s, Bap_ast.big_int_to_python i) in
+        PyDict(List.map maplet_to_python interp)
+  | None ->
+      PyNone

File ocaml/iltrans.ml

 (* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *)
 
 open Utils_common
+open Volatility
 
 type ast = Ast.program
 type astcfg = Cfg.AST.G.t
 
 let default_state = { pipeline = []; startdebug = 1 }
 
+let result = ref []
+
 let post_process_dot post_process filename = 
   if post_process then
     let _ = Sys.command ("xdot " ^ filename) in
 let ssa_chop srcbb srcn trgbb trgn p =
   Ssa_slice.CHOP_SSA.chop p srcbb srcn trgbb trgn
 
-let usedef p =
+let typecheck_prog p = 
+  try
+    Typecheck.typecheck_prog p;
+    result := (PyString "typecheck", PyBool true) :: !result
+  with Typecheck.TypeError msg ->
+    print_endline ("TypeError: " ^ msg);
+    result := (PyString "typecheck", PyBool false) :: !result
+
+let location_to_python = function
+  | Depgraphs.UseDef_AST.LocationType.Undefined ->
+      PyString "undefined"
+  | Depgraphs.UseDef_AST.LocationType.Loc(bb, i) ->
+      PyDict [ (PyString "loc", PyTuple [| PyString(Cfg.bbid_to_string(Cfg.AST.G.V.label bb)); Bap_ast.int_to_python i |]) ]
+
+let var_to_python var = PyString((Var.name var) ^ "_" ^ (string_of_int(Var.hash var)))
+
+let usedef usedef =
   let module UD = Depgraphs.UseDef_AST in
   let module VM = Var.VarMap in
-  let h,_ = UD.usedef p in
-    Hashtbl.iter
-      (fun (bb,i) varmap ->
-        Printf.printf "At location %s %d:\n" (Cfg_ast.v2s bb) i;
-        VM.iter
-          (fun v defset ->
-            let defs = try BatList.reduce (fun s s2 -> s^" "^s2) (List.map UD.LocationType.to_string (UD.LS.elements defset)) with _ -> "" in
-            Printf.printf "use %s -> def %s\n" (Pp.var_to_string v) defs
-          ) varmap;
-        Printf.printf "\n"
-      ) h
+  let h, _ = UD.usedef usedef in
+    result := (PyString "usedef", PyDict(Hashtbl.fold
+      (fun (bb, i) varmap py_usedefs ->
+        (PyTuple [| PyString(Cfg.bbid_to_string(Cfg.AST.G.V.label bb)); Bap_ast.int_to_python i |],
+         PyDict(VM.fold
+          (fun v defset py_vardefs ->
+            let py_defs = List.map location_to_python (UD.LS.elements defset) in
+              (var_to_python v, PyList py_defs) :: py_vardefs
+          )
+          varmap
+          []
+         )
+        ) :: py_usedefs
+      )
+      h
+      []
+    )) :: !result
 
-let defuse p =
+let defuse defuse =
   let module UD = Depgraphs.UseDef_AST in
   let module VM = Var.VarMap in
-  let h,_ = UD.defuse p in
-    Hashtbl.iter
-      (fun (bb,i) varmap ->
-        Printf.printf "At location %s %d:\n" (Cfg_ast.v2s bb) i;
-        VM.iter
-          (fun v defset ->
-            let defs = BatList.reduce (fun s s2 -> s^" "^s2) (List.map UD.LocationType.to_string (UD.LS.elements defset)) in
-            Printf.printf "def %s -> use %s\n" (Pp.var_to_string v) defs
-          ) varmap;
-        Printf.printf "\n"
-      ) h
+  let h, _ = UD.defuse defuse in
+    result := (PyString "defuse", PyDict(Hashtbl.fold
+      (fun (bb, i) varmap py_defuses ->
+        (PyTuple [| PyString(Cfg.bbid_to_string(Cfg.AST.G.V.label bb)); Bap_ast.int_to_python i |],
+         PyDict(VM.fold
+          (fun v defset py_vardefs ->
+            let py_defs = List.map location_to_python (UD.LS.elements defset) in
+              (var_to_python v, PyList py_defs) :: py_vardefs
+          )
+          varmap
+          []
+        )) :: py_defuses
+      )
+      h
+      []
+    )) :: !result
 
 let undef_vars cfg =
   let module DEFS = Depgraphs.DEFS_AST in
           { state with pipeline = (TransformSsa (Ssa_simp.simp_cfg ~liveout:Asmir.all_regs ~usesccvn ~usedc ~usemisc)) :: state.pipeline }
       else if arg.(cmd) = "-single-stmt-ssa" && arg_size = 2 then
         { state with pipeline = (TransformSsa Depgraphs.DDG_SSA.stmtlist_to_single_stmt) :: state.pipeline }
-      (* TODO: BEGIN DELETE *)
-      else if arg.(cmd) = "-trace-cut" && arg_size = 3 then
-        { state with pipeline = (TransformAst (BatList.take(int_of_string(argN 0 arg)))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-concrete" && arg_size = 2 then
-        { state with pipeline = (TransformAst Traces.concrete) :: state.pipeline }
-      else if arg.(cmd) = "-trace-concrete-subst" && arg_size = 2 then
-        { state with pipeline = (TransformAst Traces_surgical.concrete_substitution) :: state.pipeline }
-      else if arg.(cmd) = "-trace-slice" && arg_size = 2 then
-        { state with pipeline = (TransformAst Traces_surgical.check_slice) :: state.pipeline }
-      else if arg.(cmd) = "-trace-reconcrete" && arg_size = 3 then
-        { state with pipeline = (TransformAst (Traces.concrete_rerun(argN 0 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-dce" && arg_size = 2 then
-        { state with pipeline = (TransformAst Traces.trace_dce) :: state.pipeline }
-      else if arg.(cmd) = "-trace-start-debug" && arg_size = 3 then
-        { state with startdebug = int_of_string(argN 0 arg) }
-      else if arg.(cmd) = "-trace-debug" && arg_size = 2 then
-        { state with pipeline = (AnalysisAst Traces.TraceSymbolic.trace_valid_to_invalid) :: state.pipeline }
-      else if arg.(cmd) = "-trace-conc-debug" && arg_size = 3 then
-        let f = Traces.TraceSymbolic.formula_valid_to_invalid ~min:state.startdebug in
-          { state with pipeline = (AnalysisAst f) :: state.pipeline }
-      else if arg.(cmd) = "-trace-dsa" && arg_size = 2 then
-        { state with pipeline = (TransformAst to_dsa) :: state.pipeline }
-      else if arg.(cmd) = "-trace-target" && arg_size = 3 then
-        { state with pipeline = (TransformAst (Traces.control_flow(argN 0 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-symbolic-target" && arg_size = 2 then
-        { state with pipeline = (TransformAst Traces.limited_control) :: state.pipeline }
-      else if arg.(cmd) = "-trace-payload" && arg_size = 3 then
-        { state with pipeline = (TransformAst(Traces.add_payload(argN 0 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-payload-file" && arg_size = 3 then
-        { state with pipeline = (TransformAst(Traces.add_payload_from_file(argN 0 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-payload-after-file" && arg_size = 3 then
-        { state with pipeline = (TransformAst(Traces.add_payload_from_file_after ~offset:4L (argN 0 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-payload-after" && arg_size = 3 then
-        { state with pipeline = (TransformAst(Traces.add_payload_after ~offset:4L (argN 0 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-shell" && arg_size = 3 then
-        { state with pipeline = (TransformAst(Traces.inject_shellcode(int_of_string(argN 0 arg)))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-pivot" && arg_size = 5 then
-        { state with pipeline = (TransformAst(Traces.add_pivot (Int64.of_string(argN 0 arg)) (Int64.of_string(argN 1 arg)) (argN 2 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-pivot-file" && arg_size = 5 then
-        { state with pipeline = (TransformAst(Traces.add_pivot_file (Int64.of_string(argN 0 arg)) (Int64.of_string(argN 1 arg)) (argN 2 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-seh-pivot" && arg_size = 6 then
-        { state with pipeline = (TransformAst(Traces.add_seh_pivot (Int64.of_string(argN 0 arg)) (Int64.of_string(argN 1 arg)) (Int64.of_string(argN 2 arg)) (argN 3 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-seh-pivot-file" && arg_size = 6 then
-        { state with pipeline = (TransformAst(Traces.add_seh_pivot_file (Int64.of_string(argN 0 arg)) (Int64.of_string(argN 1 arg)) (Int64.of_string(argN 2 arg)) (argN 3 arg))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-formula" && arg_size = 3 then
-        { state with pipeline = (AnalysisAst(Traces.TraceSymbolic.generate_formula (argN 0 arg, !Solver.solver))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-solver" && arg_size = 3 then
-        (Solver.set_solver(argN 0 arg); state)
-      else if arg.(cmd) = "-trace-exploit" && arg_size = 3 then
-        { state with pipeline = (AnalysisAst(Traces.TraceSymbolic.output_exploit (argN 0 arg, !Solver.solver))) :: state.pipeline }
-      else if arg.(cmd) = "-trace-assignments" && arg_size = 2 then
-        { state with pipeline = (TransformAst Traces.add_assignments) :: state.pipeline }
-      else if arg.(cmd) = "-trace-length" && arg_size = 2 then
-        { state with pipeline = (AnalysisAst Traces.trace_length) :: state.pipeline }
-      else if arg.(cmd) = "-trace-no-padding" && arg_size = 2 then
-        (Traces.padding := false; state)
-      else if arg.(cmd) = "-trace-symbolic-indices" && arg_size = 2 then
-        (Traces.allow_symbolic_indices := true; state)
-      else if arg.(cmd) = "-trace-check" && arg_size = 2 then
-        (Traces.consistency_check := true; state)
-      else if arg.(cmd) = "-trace-check-all" && arg_size = 2 then
-        (Traces.checkall := true; state)
-      else if arg.(cmd) = "-trace-noopt" && arg_size = 2 then
-        (Traces.dce := false; state)
-      (* TODO: END DELETE *)
       else if arg.(cmd) = "-normalize-mem" && arg_size = 2 then
         { state with pipeline = (TransformAst Memory2array.coerce_prog) :: state.pipeline }
       else if arg.(cmd) = "-prune-cfg" && arg_size = 2 then
       else if arg.(cmd) = "-rm-indirect-ssa" && arg_size = 2 then
         { state with pipeline = (TransformSsa Hacks.ssa_remove_indirect) :: state.pipeline }
       else if arg.(cmd) = "-typecheck" && arg_size = 2 then
-        { state with pipeline = (AnalysisAst Typecheck.typecheck_prog) :: state.pipeline }
+        { state with pipeline = (AnalysisAst typecheck_prog) :: state.pipeline }
       else if arg.(cmd) = "-uniqueify-labels" && arg_size = 2 then
         { state with pipeline = (TransformAst Hacks.uniqueify_labels) :: state.pipeline }
       else if arg.(cmd) = "-replace-unknowns" && arg_size = 2 then
   )
 
 let apply_cmd cmd_opts prog_term =
+  let () = result := [] in
   let state = List.fold_left process_arg default_state cmd_opts in
     List.fold_left iltrans_apply_cmd prog_term (List.rev state.pipeline)

File python/commands/analysis.py

 
 def typecheck():
   "Typecheck program"
-  return [["iltrans", "-typecheck"]]
+  return [["iltrans", "-typecheck"], ["control", "-return"]]
 
 def vsa():
   """
 
 def usedef():
   "Compute and print use def chains"
-  return [["iltrans", "-usedef"]]
+  return [["iltrans", "-usedef"], ["control", "-return"]]
 
 def defuse():
   "Compute and print def use chains"
-  return [["iltrans", "-defuse"]]
+  return [["iltrans", "-defuse"], ["control", "-return"]]

File src/libbap.c

         while(!Is_long(list_cons)) {
           dict_key = ocaml_to_python(Field(Field(list_cons, 0), 0));
           dict_val = ocaml_to_python(Field(Field(list_cons, 0), 1));
-          if (PyDict_SetItem(py_term, dict_key, dict_val) == 0) {
+          if (!PyErr_Occurred() && PyDict_SetItem(py_term, dict_key, dict_val) == 0) {
             list_cons = Field(list_cons, 1);
           } else {
             // error occurred - assuming PyErr is already set