Skip to content

Instantly share code, notes, and snippets.

@jtpaasch
Created February 13, 2019 13:46
Show Gist options
  • Select an option

  • Save jtpaasch/34922f3538e3b25625ffb6c356175254 to your computer and use it in GitHub Desktop.

Select an option

Save jtpaasch/34922f3538e3b25625ffb6c356175254 to your computer and use it in GitHub Desktop.
A simple example of how to set registers with Primus
(*
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