Created
February 13, 2019 13:46
-
-
Save jtpaasch/34922f3538e3b25625ffb6c356175254 to your computer and use it in GitHub Desktop.
A simple example of how to set registers with Primus
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (* | |
| plugin = primus_set_register_example | |
| all: clean build install | |
| build: | |
| bapbuild -pkg bap-primus -tags 'warn(A)' $(plugin).plugin | |
| install: | |
| bapbundle install $(plugin).plugin | |
| clean: | |
| bapbundle remove $(plugin).plugin | |
| bapbuild -clean | |
| rm -rf $(plugin).plugin | |
| *) | |
| open Core_kernel | |
| open Bap.Std | |
| open Bap_primus.Std | |
| include Self() | |
| (** The CLI. *) | |
| module Param = struct | |
| open Config;; | |
| manpage [ | |
| `S "DESCRIPTION"; | |
| `P | |
| "This Primus component sets values | |
| before running a subroutine."; | |
| ] | |
| let on = flag "run" | |
| ~doc:"When this flag is present, the component will be executed." | |
| end | |
| (** Abstracting out the reporting. *) | |
| module type Printer = sig | |
| val report : string -> unit | |
| end | |
| (** The Primus component. *) | |
| module Sam (Log : Printer) (Machine : Primus.Machine.S) = struct | |
| module Eval = Primus.Interpreter.Make(Machine) | |
| module Env = Primus.Env.Make(Machine) | |
| module Value = Primus.Value.Make(Machine) | |
| open Machine.Syntax | |
| let make_var ?width:(width=64) name = Var.create name (Type.imm width) | |
| let make_word ?width:(width=64) i = Word.of_int i ~width:width | |
| let word_of_val v = Value.to_word v | |
| let string_of_word w = Format.asprintf "%a" Word.pp_bin w | |
| let string_of_val v = string_of_word (word_of_val v) | |
| let report_value k v = | |
| Log.report (Printf.sprintf " => %s is set to: %s" k (string_of_val v)) | |
| let enter_sub s = | |
| let name = Sub.name s in | |
| Log.report (Printf.sprintf "Entering subroutine [%s]" name); | |
| match name with | |
| | "main" -> | |
| begin | |
| let rsp = make_var "RSP" in | |
| let w = (make_word 10) in | |
| Value.of_word w >>= fun v' -> | |
| Env.set rsp v' >>= fun _ -> | |
| Env.get rsp >>= fun v'' -> report_value "RSP" v''; | |
| Machine.return () | |
| end | |
| | _ -> Machine.return () | |
| let init () = Machine.sequence [ | |
| Primus.Interpreter.enter_sub >>> enter_sub; | |
| ] | |
| end | |
| (** Instantiate the component with an appropriate printer | |
| and register it with Primus. *) | |
| let main {Config.get=(!)} = | |
| let module P : Printer = struct | |
| let report msg = | |
| match !Param.on with | |
| | true -> Format.printf "%s\n%!" msg | |
| | false -> () | |
| end in | |
| let module Component = Sam(P) in | |
| Primus.Machine.add_component (module Component) | |
| (** When BAP and Primus are ready, call [main]. *) | |
| let () = Config.when_ready main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment