Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3cfbbc5
rectifies x86 primus loader
gitoleg Jan 22, 2020
9ad34dc
Merge remote-tracking branch 'upstream/master' into rectifies-x86-loader
gitoleg Jan 29, 2020
8baae4e
refactoring
gitoleg Jan 30, 2020
0d5d8f3
moved abi pass to a plugin. wip
gitoleg Feb 6, 2020
8daf889
updated docs
gitoleg Feb 6, 2020
2b1d82e
wip
gitoleg Feb 6, 2020
5c7112e
merge with master
gitoleg Feb 13, 2020
4824890
rolled back unintended changes
gitoleg Feb 13, 2020
ac868c0
fixes start and exit insertion for singleton graphs
ivg Feb 19, 2020
6d7971a
merge with master
gitoleg Feb 21, 2020
00eb99b
Merge remote-tracking branch 'origin/rectifies-x86-loader' into recti…
gitoleg Feb 21, 2020
8b7c22b
Merge remote-tracking branch 'upstream/master' into rectifies-x86-loader
gitoleg Feb 26, 2020
b8344ce
reimplemented
gitoleg Feb 27, 2020
1ee5a2c
Merge remote-tracking branch 'upstream/master'
gitoleg Feb 28, 2020
8b5710e
Merge remote-tracking branch 'upstream/master'
gitoleg Mar 6, 2020
704b018
Merge remote-tracking branch 'upstream/master'
gitoleg Mar 15, 2020
318509f
Merge branch 'master' into rectifies-x86-loader
gitoleg Mar 15, 2020
75daa1a
Merge remote-tracking branch 'origin/rectifies-x86-loader' into recti…
gitoleg Mar 15, 2020
84e74db
refactored a little
gitoleg Mar 15, 2020
2b8755d
Merge remote-tracking branch 'upstream/master' into rectifies-x86-loader
gitoleg Apr 13, 2020
6e2d94b
rolls back primus x86 loader
gitoleg Apr 13, 2020
896803b
rolls back primus x86 loader
gitoleg Apr 13, 2020
880ae67
wip
gitoleg Apr 15, 2020
3ce0056
wrote unit tests, refactoring
gitoleg Apr 16, 2020
6b951ba
Merge remote-tracking branch 'origin/rectifies-x86-loader' into recti…
gitoleg Apr 16, 2020
91395ef
rewrote oasis file
gitoleg Apr 16, 2020
0eb1081
adds stub resolver tests on travis
gitoleg Apr 16, 2020
6742437
now we mangle new subroutines
gitoleg Apr 17, 2020
da31f61
updated testsuite, a couple new unit tests
gitoleg Apr 17, 2020
e6edeb6
just a tiny stylistic update
gitoleg Apr 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/bap_sema/bap_sema_lift.ml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ let program symtab =
let addr = Block.addr entry in
let blk_tid = Tid.for_addr addr in
let sub_tid = tid_for_sub name in
Tid.set_addr sub_tid addr;
let sub = lift_sub ~symtab ~tid:sub_tid entry cfg in
Ir_program.Builder.add_sub b (Ir_sub.with_name sub name);
Hashtbl.add_exn sub_of_blk ~key:blk_tid ~data:sub_tid;);
Expand Down
2 changes: 1 addition & 1 deletion lib/bap_types/bap_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ module Tid = struct
KB.provide slot tid (Some name)
end

let set_addr = set Theory.Label.addr
let set_addr t w = set Theory.Label.addr t (Bap_bitvector.to_bitvec w)
let set_ivec = set Theory.Label.ivec


Expand Down
1 change: 1 addition & 0 deletions lib/bap_types/bap_ir.mli
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ module Tid : sig

val create : unit -> t Bap_toplevel.t
val set_name : t -> string -> unit Bap_toplevel.t
val set_addr : t -> word -> unit Bap_toplevel.t
val name : t -> string Bap_toplevel.t
val from_string : string -> tid Or_error.t
val from_string_exn : string -> tid
Expand Down
13 changes: 13 additions & 0 deletions oasis/stub-resolver
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Flag stub_resolver
Description: Build Stub Resolver plugin
Default: false

Library stub_resolver_library_plugin
Build$: flag(everything) || flag(stub_resolver)
Path: plugins/stub_resolver/
BuildDepends: bap, bap-abi, bap-knowledge, bap-core-theory, core_kernel, bitvec, bitvec-order, bap-main
FindlibName: bap-plugin-stub_resolver
CompiledObject: best
InternalModules: Stub_resolver_main
XMETADescription: Substitutes calls to stubs with calls to real functions
XMETAExtraLines: tags="abi"
2 changes: 2 additions & 0 deletions opam/opam
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ install: [
["ocamlfind" "remove" "bap-plugin-print"]
["ocamlfind" "remove" "bap-plugin-report"]
["ocamlfind" "remove" "bap-plugin-read_symbols"]
["ocamlfind" "remove" "bap-plugin-stub_resolver"]
["ocamlfind" "remove" "bap-plugin-x86"]
["ocamlfind" "remove" "bap-traces"]
["ocamlfind" "remove" "bap-taint"]
Expand Down Expand Up @@ -226,6 +227,7 @@ remove: [
["ocamlfind" "remove" "bap-plugin-raw"]
["ocamlfind" "remove" "bap-plugin-report"]
["ocamlfind" "remove" "bap-plugin-read_symbols"]
["ocamlfind" "remove" "bap-plugin-stub_resolver"]
["ocamlfind" "remove" "bap-plugin-x86"]
["ocamlfind" "remove" "bap-traces"]
["ocamlfind" "remove" "bap-taint"]
Expand Down
2 changes: 2 additions & 0 deletions plugins/api/api/c/gnu.h
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
int __libc_start_main(int (*main) (int, char **, char **), int, char **, void *auxv);

void __stack_chk_fail(void) __attribute__((noreturn));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it here?

10 changes: 1 addition & 9 deletions plugins/primus_x86/primus_x86_loader.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ let is_section name v =
| Some x -> String.(x = name)
| _ -> false

module Make_unresolved(Machine : Primus.Machine.S) = struct
module Linker = Primus.Linker.Make(Machine)

let exec =
Linker.exec (`symbol Primus.Linker.unresolved_handler)
end

module SetupPLT(Machine : Primus.Machine.S) = struct
module Linker = Primus.Linker.Make(Machine)
open Machine.Syntax
Expand Down Expand Up @@ -44,8 +37,7 @@ module SetupPLT(Machine : Primus.Machine.S) = struct
Seq.exists memory ~f:(fun mem -> Memory.contains mem a))

let unlink addrs =
Machine.List.iter addrs ~f:(fun addr ->
Linker.link ~addr (module Make_unresolved))
Machine.List.iter addrs ~f:(fun a -> Linker.unlink (`addr a))

let unresolve =
load_table >>=
Expand Down
148 changes: 148 additions & 0 deletions plugins/stub_resolver/stub_resolver_main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
open Core_kernel
open Bap.Std
open Bap_core_theory
open Bap_knowledge
include Self ()

open Bap_main
open KB.Syntax

type t = {
aliases : tid option String.Map.t;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type binding = Unique of tid | Ambiguous instead of tid option so that at the end you will have a tri-state binding - either None, Some (Unique x), or Some Ambiguous .

Maps with 'a option as a value is very confusing, as you have the None constructor overloaded to have two completely different meanings. And that in Some None, None meanys too many. Something is wrong in representing "too many" with None.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, rename aliases to stubs and symbols to reals or impls to reflect the actual meaning of both fields.

symbols : tid String.Map.t;
}

let empty = {
aliases = Map.empty (module String);
symbols = Map.empty (module String);
}

let is_stub sub =
KB.collect (Value.Tag.slot Sub.stub) (Term.tid sub) >>= function
| None -> KB.return false
| Some () -> KB.return true

let at_most_one t key data =
Map.update t key ~f:(function
| None -> Some data
| Some _ -> None)

let add_alias t name s = at_most_one t name (Term.tid s)

let update_aliases aliases sub =
KB.collect Theory.Label.aliases (Term.tid sub) >>|
Set.fold ~init:aliases ~f:(fun als name -> add_alias als name sub)

let partition prog =
Term.to_sequence sub_t prog |>
Knowledge.Seq.fold ~init:empty
~f:(fun {symbols; aliases} s ->
is_stub s >>= fun is_stub ->
if is_stub then
update_aliases aliases s >>= fun aliases ->
KB.return {symbols; aliases}
else
let symbols = Map.set symbols (Sub.name s) (Term.tid s) in
KB.return {symbols; aliases})

let resolve prog =
partition prog >>= fun {symbols; aliases} ->
Map.fold aliases
~init:(Map.empty (module Tid))
~f:(fun ~key:alias ~data:stub_tid links ->
match Map.find symbols alias, stub_tid with
| Some tid', Some stub_tid -> at_most_one links stub_tid tid'
| _ -> links) |>
KB.return

let tids = Knowledge.Domain.mapping (module Tid) "tids"
~equal:(Option.equal Tid.equal)
~inspect:(Option.sexp_of_t sexp_of_tid)

let slot = Knowledge.Class.property
Theory.Program.cls "stubs"
tids
~persistent:(Knowledge.Persistent.of_binable (module struct
type t = tid option Tid.Map.t
[@@deriving bin_io]
end))
~public:true
~desc:"The mapping from stubs to real symbols"

let cls = Knowledge.Slot.cls slot

let provide prog =
Knowledge.Object.create cls >>= fun obj ->
resolve prog >>= fun links ->
KB.provide slot obj links >>= fun () ->
KB.return obj

let find_links prog =
match Knowledge.run cls (provide prog) (Toplevel.current ()) with
| Ok (v,_) -> Knowledge.Value.get slot v
| Error cnf ->
error "%a\n" Knowledge.Conflict.pp cnf;
Map.empty (module Tid)

let relink prog links =
(object
inherit Term.mapper

method! map_jmp jmp =
match Jmp.alt jmp with
| None -> jmp
| Some alt -> match Jmp.resolve alt with
| Second _ -> jmp
| First tid -> match Map.find links tid with
| Some (Some tid') ->
Jmp.reify
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't create a new jmp term as we will lose as a result al the attributes of the old term. Map the old term using the with_alt function. That is not exposed in the interface, so please expose it also (together with the with_dst function).

?cnd:(Jmp.guard jmp)
?dst:(Jmp.dst jmp)
~alt:(Jmp.resolved tid')
~tid:(Term.tid jmp)
()
| _ -> jmp
end)#run prog

module Plt = struct

let is_section name v =
match Value.get Image.section v with
| Some x -> String.(x = name)
| _ -> false

let section_memory proj sec_name =
let collect_addresses addrs (mem,_ )=
Memory.foldi mem ~word_size:`r8 ~init:addrs
~f:(fun addr _ acc -> Set.add acc (Word.to_bitvec addr)) in
Memmap.filter (Project.memory proj) ~f:(is_section sec_name) |>
Memmap.to_sequence |>
Seq.fold ~init:(Set.empty (module Bitvec_order)) ~f:collect_addresses

let provide proj =
let stubs = section_memory proj ".plt" in
KB.promise (Value.Tag.slot Sub.stub) @@ fun label ->
KB.collect Theory.Label.addr label >>| function
| Some addr when Set.mem stubs addr -> Some ()
| _ -> None
end

let update prog = relink prog (find_links prog)

let main proj =
Plt.provide proj;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be removed from the abi pass. In other words, move this line to line 148.

Project.with_program proj (update @@ Project.program proj)

let () = Extension.documentation {|
# DESCRIPTION

Provides an abi pass that transforms a program by substituting calls
to stubs with calls to real subroutines when they are present in
the binary.

|}


let () = Extension.declare @@ fun _ctxt ->
Bap_abi.register_pass main;
Ok ()