-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type inference #14
Merged
Merged
Type inference #14
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
7bc533d
Type inference and unit tests initial commit
Enkelmann 8e71c61
Correct stack_offset initial value
Enkelmann 85ffb3c
Adding sexp-derivers
Enkelmann 91f8658
Rename module State to TypeInfo
Enkelmann 8bce707
Refactor unit tests, added unit tests for type inference, added rudim…
Enkelmann 6ed2faf
Speed up dynamic symbol lookup
Enkelmann e73b7a0
added thumb mode to calling conventions
Enkelmann 24a3b19
Fixed bug for elements with negative start index
Enkelmann fd74e8b
Mem_region.get also returns the size of an element
Enkelmann 7879dc9
Removed some TODOs
Enkelmann 5eacb6a
Print type info tags as debug messages
Enkelmann 2e5b8ea
Refactor to support multiple plugins
Enkelmann 3b7a7f3
fixed typo
Enkelmann a8a6997
added dummy pass to print results of type inference pass
Enkelmann 1ba50c3
Fixed typo
Enkelmann 48a890b
Updated Changes.md
Enkelmann 3e8186d
Fixed some JaneStreet Core issues related to Maps
tbarabosch d174c87
Merge branch 'type_inference' of github.com:fkie-cad/cwe_checker into…
tbarabosch 7ebeeeb
Fixed more Core issues, all Map related.
tbarabosch 02725bf
Changed Map.add_exn to Map.set
Enkelmann 1ca6542
Added simple type inference recipe
Enkelmann 3f7d767
Added some commments
Enkelmann 209aa5f
Removed .Std from "open Core_kernel"
Enkelmann 211a46d
wrap functions that are only public for unit tests into a Test module
Enkelmann d76c2df
Better error handling
Enkelmann 0b8ad24
Prefix every plugin with cwe_checker
Enkelmann 3273539
added unit test plugin to make clean
Enkelmann f92572a
Merge branch 'master' into type_inference
Enkelmann File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,25 @@ | ||
.PHONY: all clean test uninstall | ||
all: | ||
cd src; bapbuild -r -Is checkers,utils -pkgs yojson,unix cwe_checker.plugin; bapbundle install cwe_checker.plugin; cd .. | ||
dune build --profile release | ||
dune install | ||
cd plugins/cwe_checker; make all; cd ../.. | ||
cd plugins/cwe_checker_type_inference; make all; cd ../.. | ||
cd plugins/cwe_checker_type_inference_print; make all; cd ../.. | ||
|
||
test: | ||
dune runtest --profile release # TODO: correct all dune linter warnings so that we can remove --profile release | ||
pytest -v | ||
|
||
clean: | ||
dune clean | ||
bapbuild -clean | ||
cd test/unit; make clean; cd ../.. | ||
cd plugins/cwe_checker; make clean; cd ../.. | ||
cd plugins/cwe_checker_type_inference; make clean; cd ../.. | ||
cd plugins/cwe_checker_type_inference_print; make clean; cd ../.. | ||
|
||
uninstall: | ||
bapbundle remove cwe_checker.plugin | ||
dune uninstall | ||
cd plugins/cwe_checker; make uninstall; cd ../.. | ||
cd plugins/cwe_checker_type_inference; make uninstall; cd ../.. | ||
cd plugins/cwe_checker_type_inference_print; make uninstall; cd ../.. |
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,2 @@ | ||
(lang dune 1.6) | ||
(name cwe_checker) |
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,9 @@ | ||
all: | ||
bapbuild -pkgs yojson,unix,ppx_jane,cwe_checker_core cwe_checker.plugin | ||
bapbundle install cwe_checker.plugin | ||
|
||
clean: | ||
bapbuild -clean | ||
|
||
uninstall: | ||
bapbundle remove cwe_checker.plugin |
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,9 @@ | ||
all: | ||
bapbuild -pkgs yojson,unix,ppx_jane,cwe_checker_core cwe_checker_type_inference.plugin | ||
bapbundle install cwe_checker_type_inference.plugin | ||
|
||
clean: | ||
bapbuild -clean | ||
|
||
uninstall: | ||
bapbundle remove cwe_checker_type_inference.plugin |
5 changes: 5 additions & 0 deletions
5
plugins/cwe_checker_type_inference/cwe_checker_type_inference.ml
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,5 @@ | ||
open Bap.Std | ||
open Core_kernel | ||
open Cwe_checker_core | ||
|
||
let () = Project.register_pass Type_inference.compute_pointer_register |
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,9 @@ | ||
all: | ||
bapbuild -pkgs yojson,unix,ppx_jane,cwe_checker_core cwe_checker_type_inference_print.plugin | ||
bapbundle install cwe_checker_type_inference_print.plugin | ||
|
||
clean: | ||
bapbuild -clean | ||
|
||
uninstall: | ||
bapbundle remove cwe_checker_type_inference_print.plugin |
14 changes: 14 additions & 0 deletions
14
plugins/cwe_checker_type_inference_print/cwe_checker_type_inference_print.ml
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,14 @@ | ||
open Bap.Std | ||
open Core_kernel | ||
open Cwe_checker_core | ||
|
||
let main project = | ||
Log_utils.set_log_level Log_utils.DEBUG; | ||
Log_utils.set_output stdout; | ||
Log_utils.color_on (); | ||
|
||
let program = Project.program project in | ||
let tid_map = Address_translation.generate_tid_map program in | ||
Type_inference.print_type_info_tags project tid_map | ||
|
||
let () = Project.register_pass' main ~deps:["cwe-checker-type-inference"] |
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 @@ | ||
Prints the results of the type inference pass of each block. |
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 @@ | ||
(option pass cwe-type-inference-print) |
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,164 @@ | ||
open Bap.Std | ||
open Core_kernel | ||
|
||
|
||
let (+), (-) = Bitvector.(+), Bitvector.(-) | ||
|
||
let (>) x y = Bitvector.(>) (Bitvector.signed x) (Bitvector.signed y) | ||
let (<) x y = Bitvector.(<) (Bitvector.signed x) (Bitvector.signed y) | ||
let (>=) x y = Bitvector.(>=) (Bitvector.signed x) (Bitvector.signed y) | ||
let (<=) x y = Bitvector.(<=) (Bitvector.signed x) (Bitvector.signed y) | ||
let (=) x y = Bitvector.(=) x y | ||
|
||
type 'a mem_node = { | ||
pos: Bitvector.t; (* address of the element *) | ||
size: Bitvector.t; (* size (in bytes) of the element *) | ||
data: ('a, unit) Result.t; | ||
} [@@deriving bin_io, compare, sexp] | ||
|
||
type 'a t = 'a mem_node list [@@deriving bin_io, compare, sexp] | ||
|
||
|
||
let empty () : 'a t = | ||
[] | ||
|
||
(** Return an error mem_node at the given position with the given size. *) | ||
let error_elem ~pos ~size = | ||
{ pos = pos; | ||
size = size; | ||
data = Error ();} | ||
|
||
|
||
let rec add mem_region elem ~pos ~size = | ||
let () = if pos + size < pos then failwith "[CWE-checker] element out of bounds for mem_region" in | ||
let new_node = { | ||
pos=pos; | ||
size=size; | ||
data=Ok(elem); | ||
} in | ||
match mem_region with | ||
| [] -> new_node :: [] | ||
| head :: tail -> | ||
if head.pos + head.size <= pos then | ||
head :: (add tail elem ~pos ~size) | ||
else if pos + size <= head.pos then | ||
new_node :: mem_region | ||
else begin (* head and new node intersect => at the intersection, head gets overwritten and the rest of head gets marked as error. *) | ||
let tail = if head.pos + head.size > pos + size then (* mark the right end of head as error *) | ||
let err = error_elem ~pos:(pos + size) ~size:(head.pos + head.size - (pos + size)) in | ||
err :: tail | ||
else | ||
tail in | ||
let tail = add tail elem ~pos ~size in (* add the new element*) | ||
let tail = if head.pos < pos then (* mark the left end of head as error *) | ||
let err = error_elem ~pos:(head.pos) ~size:(pos - head.pos) in | ||
err :: tail | ||
else | ||
tail in | ||
tail | ||
end | ||
|
||
|
||
let rec get mem_region pos = | ||
match mem_region with | ||
| [] -> None | ||
| head :: tail -> | ||
if head.pos > pos then | ||
None | ||
else if head.pos = pos then | ||
match head.data with | ||
| Ok(x) -> Some(Ok(x, head.size)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see this Some(Ok()) wrapping all the time. Is that really idiomatic OCaml? |
||
| Error(_) -> Some(Error(())) | ||
else if head.pos + head.size <= pos then | ||
get tail pos | ||
else | ||
Some(Error(())) (* pos intersects some data, but does not equal its starting address*) | ||
|
||
(* Helper function. Removes all elements with position <= pos. *) | ||
let rec remove_until mem_region pos = | ||
match mem_region with | ||
| [] -> [] | ||
| hd :: tl -> | ||
if hd.pos <= pos then | ||
remove_until tl pos | ||
else | ||
mem_region | ||
|
||
|
||
let rec remove mem_region ~pos ~size = | ||
let () = if pos + size < pos then failwith "[CWE-checker] element out of bounds for mem_region" in | ||
match mem_region with | ||
| [] -> [] | ||
| hd :: tl -> | ||
if hd.pos + hd.size <= pos then | ||
hd :: remove tl pos size | ||
else if pos + size <= hd.pos then | ||
mem_region | ||
else | ||
let mem_region = remove tl pos size in | ||
let mem_region = | ||
if hd.pos + hd.size > pos + size then | ||
error_elem ~pos:(pos + size) ~size:(hd.pos + hd.size - (pos + size)) :: mem_region | ||
else | ||
mem_region in | ||
let mem_region = | ||
if hd.pos < pos then | ||
error_elem ~pos:hd.pos ~size:(pos - hd.pos) :: mem_region | ||
else | ||
mem_region in | ||
mem_region | ||
|
||
let rec mark_error mem_region ~pos ~size = | ||
let () = if pos + size < pos then failwith "[CWE-checker] element out of bounds for mem_region" in | ||
match mem_region with | ||
| [] -> (error_elem pos size) :: [] | ||
| hd :: tl -> | ||
if hd.pos + hd.size <= pos then | ||
hd :: (mark_error tl pos size) | ||
else if pos + size <= hd.pos then | ||
(error_elem pos size) :: mem_region | ||
else | ||
let start_pos = min pos hd.pos in | ||
let end_pos_plus_one = max (pos + size) (hd.pos + hd.size) in | ||
mark_error tl ~pos:start_pos ~size:(end_pos_plus_one - start_pos) | ||
|
||
|
||
(* TODO: This is probably a very inefficient implementation in some cases. Write a faster implementation if necessary. *) | ||
let rec merge mem_region1 mem_region2 ~data_merge = | ||
match (mem_region1, mem_region2) with | ||
| (value, []) | ||
| ([], value) -> value | ||
| (hd1 :: tl1, hd2 :: tl2) -> | ||
if hd1.pos + hd1.size <= hd2.pos then | ||
hd1 :: merge tl1 mem_region2 data_merge | ||
else if hd2.pos + hd2.size <= hd1.pos then | ||
hd2 :: merge mem_region1 tl2 data_merge | ||
else if hd1.pos = hd2.pos && hd1.size = hd2.size then | ||
match (hd1.data, hd2.data) with | ||
| (Ok(data1), Ok(data2)) -> begin | ||
match data_merge data1 data2 with | ||
| Some(Ok(value)) -> { hd1 with data = Ok(value) } :: merge tl1 tl2 ~data_merge | ||
| Some(Error(_)) -> {hd1 with data = Error(())} :: merge tl1 tl2 ~data_merge | ||
| None -> merge tl1 tl2 data_merge | ||
end | ||
| _ -> { hd1 with data = Error(()) } :: merge tl1 tl2 ~data_merge | ||
else | ||
let start_pos = min hd1.pos hd2.pos in | ||
let end_pos_plus_one = max (hd1.pos + hd1.size) (hd2.pos + hd2.size) in | ||
let mem_region = merge tl1 tl2 data_merge in | ||
mark_error mem_region ~pos:start_pos ~size:(end_pos_plus_one - start_pos) | ||
|
||
|
||
let rec equal (mem_region1:'a t) (mem_region2:'a t) ~data_equal : bool = | ||
match (mem_region1, mem_region2) with | ||
| ([], []) -> true | ||
| (hd1 :: tl1, hd2 :: tl2) -> | ||
if hd1.pos = hd2.pos && hd1.size = hd2.size then | ||
match (hd1.data, hd2.data) with | ||
| (Ok(data1), Ok(data2)) when data_equal data1 data2 -> | ||
equal tl1 tl2 data_equal | ||
| (Error(()), Error(())) -> equal tl1 tl2 data_equal | ||
| _ -> false | ||
else | ||
false | ||
| _ -> false |
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,39 @@ | ||
(** contains an abstract memory region data type where you can assign arbitrary data to locations | ||
inside the memory regions. A memory region has no fixed size, so it can be used | ||
for memory regions of variable size like arrays or stacks. | ||
|
||
TODO: Right now this data structure is unsuited for elements that get only partially loaded. *) | ||
|
||
open Bap.Std | ||
open Core_kernel | ||
|
||
type 'a t [@@deriving bin_io, compare, sexp] | ||
|
||
|
||
(** Get an empty memory region- *) | ||
val empty: unit -> 'a t | ||
|
||
|
||
(** Add an element to the memory region. If the element intersects existing elements, | ||
the non-overwritten part gets marked as Error *) | ||
val add: 'a t -> 'a -> pos:Bitvector.t -> size:Bitvector.t -> 'a t | ||
|
||
(** Mark the memory region between pos (included) and pos+size (excluded) as empty. | ||
If elements get partially removed, mark the non-removed parts as Error *) | ||
val remove: 'a t -> pos:Bitvector.t -> size:Bitvector.t -> 'a t | ||
|
||
(** Returns the element and its size at position pos or None, when there is no element at that position. | ||
If pos intersects an element but does not match its starting position, it returns Some(Error(())). *) | ||
val get: 'a t -> Bitvector.t -> (('a * Bitvector.t), unit) Result.t Option.t | ||
|
||
(** Merge two memory regions. Elements with the same position and size get merged using | ||
data_merge, other intersecting elements get marked as Error. Note that data_merge | ||
may return None (to remove the elements from the memory region) or Some(Error(_)) to | ||
mark the merged element as error. *) | ||
val merge: 'a t -> 'a t -> data_merge:('a -> 'a -> ('a, 'b) result option) -> 'a t | ||
|
||
(** Check whether two memory regions are equal. *) | ||
val equal: 'a t -> 'a t -> data_equal:('a -> 'a -> bool) -> bool | ||
|
||
(** Mark an area in the mem_region as containing errors. *) | ||
val mark_error: 'a t -> pos:Bitvector.t -> size:Bitvector.t -> 'a t |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extract a function from the begin end block (line 46 - 59). This would make the function more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't think of a useful way to extract a function there. I added some comments to improve readability instead.