forked from BinaryAnalysisPlatform/bap
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implements support for various relocations and improves existing that enables us to pass all tests without relying on external symbols or tools such as objdump or radare2. This branch support PLT-like relocations, as well as direct calls with GLOB_DAT relocations (fixes BinaryAnalysisPlatform#1135). The PLT entries are constant folded and memory references are then analyzed. We also extended the analysis that detects stub functions to support various ABI and file formats. For PowerPC MachO, that stores stubs directly in the text section, we implemented a signature matching procedure to reliably detect the stubs. We also significantly improved support of mips, which was sufferening from missing function starts that correspond to the stubbed functions as byteweigh is unable to detect these stubs. In addition, this PR brings a new library called Bap_relation that is a bidirectional mapping useful for storing addr <-> name mapping and ensure their bijection. This library is now used explicitly or implicitly (via the old symbolizer interface) by all our providers of symbolic information. This change prevents symbolizers from providing conflicting information, which may later lead to the knowledge base conflicts. We also removed so far the name to address translation service that we recently introduced BinaryAnalysisPlatform#1119. We are not ready for this service yet (our knowledge base is not having enough rules stored in it) and without this rule we can disassemble 25% faster. There are also a couple of minor fixes and quality of life improvements: - fixes Insn.dests domain functions - a better default for the KB.Domain.Powerset inspect parameter - makes glibc-runtime heuristic more aggressive
- Loading branch information
Showing
34 changed files
with
923 additions
and
213 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
open Base | ||
|
||
type ('k,'d) t = Rel : { | ||
vals : ('k, ('d,'vo) Set.t, 'ko) Map.t; | ||
keys : ('d, ('k,'ko) Set.t, 'vo ) Map.t; | ||
} -> ('k,'d) t | ||
|
||
let empty (type key) (type data) compare_key compare_data = | ||
let module D = struct | ||
type t = data | ||
include Comparator.Make(struct | ||
type t = data | ||
let compare = compare_data | ||
let sexp_of_t _ = Sexp.List [] | ||
end) | ||
end in | ||
let module K = struct | ||
type t = key | ||
include Base.Comparator.Make(struct | ||
type t = key | ||
let compare = compare_key | ||
let sexp_of_t _ = Sexp.List [] | ||
end) | ||
end in | ||
Rel { | ||
vals = Map.empty (module K); | ||
keys = Map.empty (module D); | ||
} | ||
|
||
let add (Rel {vals; keys}) key value = Rel { | ||
vals = Map.update vals key ~f:(function | ||
| Some vals -> Set.add vals value | ||
| None -> Set.singleton (Map.comparator_s keys) value); | ||
keys = Map.update keys value ~f:(function | ||
| Some keys -> Set.add keys key | ||
| None -> Set.singleton (Map.comparator_s vals) key); | ||
} | ||
|
||
type ('k,'s) non_injective = | ||
| Non_injective_fwd of 'k list * 's | ||
| Non_injective_bwd of 's list * 'k | ||
|
||
let skips _ _ x = x | ||
let skipu _ x = x | ||
|
||
|
||
let find_multi xs x = match Map.find xs x with | ||
| None -> [] | ||
| Some xs -> Set.to_list xs | ||
|
||
let matching (Rel {vals; keys}) ?(saturated=skips) ?(unmatched=skipu) init = | ||
Map.fold ~init vals ~f:(fun ~key ~data:vals init -> | ||
match Set.to_list vals with | ||
| [] -> assert false | ||
| _ :: _ :: _ as vals-> | ||
unmatched (Non_injective_bwd (vals,key)) init | ||
| [s] -> match find_multi keys s with | ||
| [_] -> saturated key s init | ||
| xs -> unmatched (Non_injective_fwd (xs,s)) init) | ||
|
||
let fold (Rel {vals}) ~init ~f = | ||
Map.fold vals ~init ~f:(fun ~key:left ~data:rights init -> | ||
Set.fold ~init rights ~f:(fun init right -> f left right init)) | ||
|
||
let iter rels ~f = fold rels ~init:() ~f:(fun x s () -> f x s) | ||
|
||
let is_empty (Rel {vals}) = Map.is_empty vals | ||
let findl (Rel {vals}) = find_multi vals | ||
let findr (Rel {keys}) = find_multi keys | ||
let mem (Rel {vals; keys}) x s = Map.mem vals x && Map.mem keys s |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
(** A representation of relations between two sets. | ||
A relation between two sets is a set of pairs made from the | ||
elements of these sets. The precise mathematical defition is given | ||
below. This module implements a bidirectional mapping between two | ||
sets and computes their matching that defines bijections between | ||
the sets. | ||
{2 Format Definition and Notation} | ||
Given two sets [K] and [S], with meta-variables [x,y,z] ranging | ||
over [K] and meta-variables [r,s,t] ranging over [S] we will | ||
denote a finitary relation [R] as a subset of the cartesian | ||
product [K x S], which is a set of pairs [(x,r), ..., (z,t)], | ||
which we represent as a bipartite graph [G = (K,S,R)]. | ||
*) | ||
|
||
(** the type for relation between ['k] and ['s]. *) | ||
type ('k,'s) t | ||
|
||
(** [empty compare_k compare_s] the empty relation between two sets. | ||
- [compare_k] is the function that defines order of the elements | ||
of the set [K]. | ||
- [compare_s] is the function that defines order of the elements | ||
of the set [S]. | ||
{3 Example} | ||
{[ | ||
let empty = Bap_relation.empty | ||
Int.compare | ||
String.compare | ||
]} | ||
*) | ||
val empty : ('k -> 'k -> int) -> ('s -> 's -> int) -> ('k,'s) t | ||
|
||
(** [is_empty rel] is true if the relation [rel] is an empty set. *) | ||
val is_empty : (_,_) t -> bool | ||
|
||
(** [add relation x s] establishes a relation between [x] and [s]. *) | ||
val add : ('k,'s) t -> 'k -> 's -> ('k,'s) t | ||
|
||
(** [mem rel x s] is [true] if [(k,s)] is in the relation [rel]. *) | ||
val mem : ('k,'s) t -> 'k -> 's -> bool | ||
|
||
(** [findl rel x] finds all pairs in [rel] that have [x] on the left. *) | ||
val findl : ('k,'s) t -> 'k -> 's list | ||
|
||
(** [findr rel s] finds all pairs in [rel] that have [s] on the right. *) | ||
val findr : ('k,'s) t -> 's -> 'k list | ||
|
||
(** [fold rel init f] folds over all pairs in the relation [rel]. *) | ||
val fold : ('k,'s) t -> init:'a -> f:('k -> 's -> 'a -> 'a) -> 'a | ||
|
||
(** [iter rel f] iterates over all pairs in the relation [rel]. *) | ||
val iter : ('k,'s) t -> f:('k -> 's -> unit) -> unit | ||
|
||
|
||
(** {2 Bijections and matching} | ||
The set of independent edges [M] (the matching) of the graph [G] | ||
forms a finite bijection between [K] and [S]. It is guaranteed | ||
that for each pair [(x,s)] in [M] there is no other pair in [M], | ||
that will include [x] or [s]. | ||
Edges [R] that are not in the matching [M] represent a subset of | ||
[R] that do not match because of one the two anomalies: | ||
- A non-injective forward mapping occurs when the same value from | ||
the set [S] is in relation with more than one value from the set | ||
[K], e.g., [(x,s), (y,s)] is encoded as | ||
[Non_injective_fwd ([x,y],s)]; | ||
- A non-injective backward mapping occurs when the same value from | ||
the set [K] is in relation with more than one value from the set | ||
[S], e.g., [(x,r), (x,s)] is encoded as | ||
[Non_injective_bwd ([r;s],x); | ||
*) | ||
|
||
(** the reason why was the pair left unmatched *) | ||
type ('k,'s) non_injective = | ||
| Non_injective_fwd of 'k list * 's (** Non-injective forward mapping. *) | ||
| Non_injective_bwd of 's list * 'k (** Non-injective backward mapping. *) | ||
|
||
(** [matching relation data] computes the matching for the given [relation]. | ||
Calls [saturated x s data] for each [(x,s)] in the matching | ||
[M] (see the module description) and [unmatched z reason d] for | ||
each [(z,t)] in the relation that are not matched, the reason | ||
is one of the: | ||
- [Non_injective_fwd (xs,s)] if the mapping [K -> S] that is | ||
induced by the [relation] is non-injective, because the set of | ||
values [xs] from [K] are mapped to the same value [s] in [S]. | ||
- [Non_injective_bwd (ss,x)] if the mapping [S -> K] that is | ||
induced by the [relation] is non-injective, because the set of | ||
values [ss] from [S] are mapped to the same value [x] in [K]. | ||
*) | ||
val matching : ('k,'s) t -> | ||
?saturated : ('k -> 's -> 'a -> 'a) -> | ||
?unmatched : (('k,'s) non_injective -> 'a -> 'a) -> 'a -> 'a |
This file contains 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
This file contains 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
Oops, something went wrong.