Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cwe_checker
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
cwe_checker
Commits
d1d04f32
Unverified
Commit
d1d04f32
authored
Mar 22, 2022
by
van den Bosch
Committed by
GitHub
Mar 22, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace old mocks in unit tests (#301)
parent
c7182ddb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
139 additions
and
262 deletions
+139
-262
conditional_specialization.rs
...ib/src/abstract_domain/data/conditional_specialization.rs
+12
-20
tests.rs
...hecker_lib/src/analysis/function_signature/state/tests.rs
+15
-12
tests.rs
...ecker_lib/src/analysis/pointer_inference/context/tests.rs
+9
-55
access_handling.rs
...b/src/analysis/pointer_inference/state/access_handling.rs
+1
-2
tests.rs
src/cwe_checker_lib/src/analysis/string_abstraction/tests.rs
+58
-128
program.rs
...we_checker_lib/src/intermediate_representation/program.rs
+8
-44
project.rs
...we_checker_lib/src/intermediate_representation/project.rs
+1
-1
sub.rs
src/cwe_checker_lib/src/intermediate_representation/sub.rs
+35
-0
No files found.
src/cwe_checker_lib/src/abstract_domain/data/conditional_specialization.rs
View file @
d1d04f32
...
@@ -8,16 +8,13 @@ fn intersect_relative_values<T: SpecializeByConditional + RegisterDomain>(
...
@@ -8,16 +8,13 @@ fn intersect_relative_values<T: SpecializeByConditional + RegisterDomain>(
values_left
values_left
.iter
()
.iter
()
.filter_map
(|(
id
,
offset
)|
{
.filter_map
(|(
id
,
offset
)|
{
values_right
values_right
.get
(
id
)
.and_then
(|
other_offset
|
{
.get
(
id
)
if
let
Ok
(
intersected_offset
)
=
offset
.clone
()
.intersect
(
other_offset
)
{
.map
(|
other_offset
|
{
Some
((
id
.clone
(),
intersected_offset
))
if
let
Ok
(
intersected_offset
)
=
offset
.clone
()
.intersect
(
other_offset
)
{
}
else
{
Some
((
id
.clone
(),
intersected_offset
))
None
}
else
{
}
None
})
}
})
.flatten
()
})
})
.collect
()
.collect
()
}
}
...
@@ -26,8 +23,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
...
@@ -26,8 +23,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_signed_less_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
fn
add_signed_less_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
self
.absolute_value
=
self
.absolute_value
.absolute_value
.map
(|
value
|
value
.add_signed_less_equal_bound
(
bound
)
.ok
())
.and_then
(|
value
|
value
.add_signed_less_equal_bound
(
bound
)
.ok
());
.flatten
();
if
self
.is_empty
()
{
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
Err
(
anyhow!
(
"Empty value"
))
}
else
{
}
else
{
...
@@ -38,8 +34,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
...
@@ -38,8 +34,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_unsigned_less_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
fn
add_unsigned_less_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
self
.absolute_value
=
self
.absolute_value
.absolute_value
.map
(|
value
|
value
.add_unsigned_less_equal_bound
(
bound
)
.ok
())
.and_then
(|
value
|
value
.add_unsigned_less_equal_bound
(
bound
)
.ok
());
.flatten
();
if
self
.is_empty
()
{
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
Err
(
anyhow!
(
"Empty value"
))
}
else
{
}
else
{
...
@@ -50,8 +45,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
...
@@ -50,8 +45,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_signed_greater_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
fn
add_signed_greater_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
self
.absolute_value
=
self
.absolute_value
.absolute_value
.map
(|
value
|
value
.add_signed_greater_equal_bound
(
bound
)
.ok
())
.and_then
(|
value
|
value
.add_signed_greater_equal_bound
(
bound
)
.ok
());
.flatten
();
if
self
.is_empty
()
{
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
Err
(
anyhow!
(
"Empty value"
))
}
else
{
}
else
{
...
@@ -62,8 +56,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
...
@@ -62,8 +56,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_unsigned_greater_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
fn
add_unsigned_greater_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
self
.absolute_value
=
self
.absolute_value
.absolute_value
.map
(|
value
|
value
.add_unsigned_greater_equal_bound
(
bound
)
.ok
())
.and_then
(|
value
|
value
.add_unsigned_greater_equal_bound
(
bound
)
.ok
());
.flatten
();
if
self
.is_empty
()
{
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
Err
(
anyhow!
(
"Empty value"
))
}
else
{
}
else
{
...
@@ -74,8 +67,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
...
@@ -74,8 +67,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_not_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
fn
add_not_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
self
.absolute_value
=
self
.absolute_value
.absolute_value
.map
(|
value
|
value
.add_not_equal_bound
(
bound
)
.ok
())
.and_then
(|
value
|
value
.add_not_equal_bound
(
bound
)
.ok
());
.flatten
();
if
self
.is_empty
()
{
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
Err
(
anyhow!
(
"Empty value"
))
}
else
{
}
else
{
...
...
src/cwe_checker_lib/src/analysis/function_signature/state/tests.rs
View file @
d1d04f32
...
@@ -2,11 +2,11 @@ use super::*;
...
@@ -2,11 +2,11 @@ use super::*;
impl
State
{
impl
State
{
/// Generate a mock state for an ARM-32 state.
/// Generate a mock state for an ARM-32 state.
pub
fn
mock
()
->
State
{
pub
fn
mock
_arm32
()
->
State
{
State
::
new
(
State
::
new
(
&
Tid
::
new
(
"mock_fn"
),
&
Tid
::
new
(
"mock_fn"
),
&
Variable
::
mock
(
"sp"
,
4
),
&
Variable
::
mock
(
"sp"
,
4
),
&
CallingConvention
::
mock_
standard_arm_
32
(),
&
CallingConvention
::
mock_
arm
32
(),
)
)
}
}
...
@@ -39,12 +39,12 @@ fn mock_stack_param_id(offset: i64, size: u64) -> AbstractIdentifier {
...
@@ -39,12 +39,12 @@ fn mock_stack_param_id(offset: i64, size: u64) -> AbstractIdentifier {
#[test]
#[test]
fn
test_new
()
{
fn
test_new
()
{
let
state
=
State
::
mock
();
let
state
=
State
::
mock
_arm32
();
// Test the generated stack
// Test the generated stack
assert_eq!
(
&
state
.stack_id
,
&
mock_stack_id
());
assert_eq!
(
&
state
.stack_id
,
&
mock_stack_id
());
assert_eq!
(
state
.stack
.iter
()
.len
(),
0
);
assert_eq!
(
state
.stack
.iter
()
.len
(),
0
);
// Assert that the register values are as expected
// Assert that the register values are as expected
assert_eq!
(
state
.register
.len
(),
9
);
// 8 parameters
plus stack pointer
assert_eq!
(
state
.register
.len
(),
7
);
// 6 parameter register
plus stack pointer
assert_eq!
(
assert_eq!
(
state
.get_register
(
&
Variable
::
mock
(
"sp"
,
4
)),
state
.get_register
(
&
Variable
::
mock
(
"sp"
,
4
)),
DataDomain
::
from_target
(
DataDomain
::
from_target
(
...
@@ -53,11 +53,14 @@ fn test_new() {
...
@@ -53,11 +53,14 @@ fn test_new() {
)
)
);
);
// Check the generated tracked IDs
// Check the generated tracked IDs
assert_eq!
(
state
.tracked_ids
.len
(),
8
);
assert_eq!
(
state
.tracked_ids
.len
(),
6
);
for
(
id
,
access_pattern
)
in
state
.tracked_ids
.iter
()
{
for
(
id
,
access_pattern
)
in
state
.tracked_ids
.iter
()
{
assert_eq!
(
assert_eq!
(
state
.get_register
(
id
.unwrap_register
()),
state
.get_register
(
id
.unwrap_register
()),
DataDomain
::
from_target
(
id
.clone
(),
Bitvector
::
zero
(
ByteSize
::
new
(
4
)
.into
())
.into
())
DataDomain
::
from_target
(
id
.clone
(),
Bitvector
::
zero
(
id
.unwrap_register
()
.size
.into
())
.into
()
)
);
);
assert_eq!
(
access_pattern
,
&
AccessPattern
::
new
());
assert_eq!
(
access_pattern
,
&
AccessPattern
::
new
());
}
}
...
@@ -65,7 +68,7 @@ fn test_new() {
...
@@ -65,7 +68,7 @@ fn test_new() {
#[test]
#[test]
fn
test_store_and_load_from_stack
()
{
fn
test_store_and_load_from_stack
()
{
let
mut
state
=
State
::
mock
();
let
mut
state
=
State
::
mock
_arm32
();
let
address
=
DataDomain
::
from_target
(
mock_stack_id
(),
Bitvector
::
from_i32
(
-
4
)
.into
());
let
address
=
DataDomain
::
from_target
(
mock_stack_id
(),
Bitvector
::
from_i32
(
-
4
)
.into
());
let
value
:
DataDomain
<
BitvectorDomain
>
=
Bitvector
::
from_i32
(
0
)
.into
();
let
value
:
DataDomain
<
BitvectorDomain
>
=
Bitvector
::
from_i32
(
0
)
.into
();
// write and load a value to the current stack frame
// write and load a value to the current stack frame
...
@@ -81,12 +84,12 @@ fn test_store_and_load_from_stack() {
...
@@ -81,12 +84,12 @@ fn test_store_and_load_from_stack() {
let
stack_param_id
=
mock_stack_param_id
(
4
,
4
);
let
stack_param_id
=
mock_stack_param_id
(
4
,
4
);
let
stack_param
=
let
stack_param
=
DataDomain
::
from_target
(
stack_param_id
.clone
(),
Bitvector
::
from_i32
(
0
)
.into
());
DataDomain
::
from_target
(
stack_param_id
.clone
(),
Bitvector
::
from_i32
(
0
)
.into
());
assert_eq!
(
state
.tracked_ids
.iter
()
.len
(),
8
);
assert_eq!
(
state
.tracked_ids
.iter
()
.len
(),
6
);
assert_eq!
(
assert_eq!
(
state
.load_value
(
address
.clone
(),
ByteSize
::
new
(
4
)),
state
.load_value
(
address
.clone
(),
ByteSize
::
new
(
4
)),
stack_param
stack_param
);
);
assert_eq!
(
state
.tracked_ids
.iter
()
.len
(),
9
);
assert_eq!
(
state
.tracked_ids
.iter
()
.len
(),
7
);
assert_eq!
(
assert_eq!
(
state
state
.tracked_ids
.tracked_ids
...
@@ -99,7 +102,7 @@ fn test_store_and_load_from_stack() {
...
@@ -99,7 +102,7 @@ fn test_store_and_load_from_stack() {
#[test]
#[test]
fn
test_load_unsized_from_stack
()
{
fn
test_load_unsized_from_stack
()
{
let
mut
state
=
State
::
mock
();
let
mut
state
=
State
::
mock
_arm32
();
// Load an existing stack param (generated by a sized load at the same address)
// Load an existing stack param (generated by a sized load at the same address)
let
address
=
DataDomain
::
from_target
(
mock_stack_id
(),
Bitvector
::
from_i32
(
0
)
.into
());
let
address
=
DataDomain
::
from_target
(
mock_stack_id
(),
Bitvector
::
from_i32
(
0
)
.into
());
let
stack_param_id
=
mock_stack_param_id
(
0
,
4
);
let
stack_param_id
=
mock_stack_param_id
(
0
,
4
);
...
@@ -122,7 +125,7 @@ fn test_load_unsized_from_stack() {
...
@@ -122,7 +125,7 @@ fn test_load_unsized_from_stack() {
#[test]
#[test]
fn
test_eval
()
{
fn
test_eval
()
{
let
mut
state
=
State
::
mock
();
let
mut
state
=
State
::
mock
_arm32
();
// Test the eval method
// Test the eval method
let
expr
=
Expression
::
Var
(
Variable
::
mock
(
"sp"
,
4
))
.plus_const
(
42
);
let
expr
=
Expression
::
Var
(
Variable
::
mock
(
"sp"
,
4
))
.plus_const
(
42
);
assert_eq!
(
assert_eq!
(
...
@@ -139,7 +142,7 @@ fn test_eval() {
...
@@ -139,7 +142,7 @@ fn test_eval() {
#[test]
#[test]
fn
test_extern_symbol_handling
()
{
fn
test_extern_symbol_handling
()
{
let
mut
state
=
State
::
mock
();
let
mut
state
=
State
::
mock
_arm32
();
let
extern_symbol
=
ExternSymbol
::
mock_arm32
();
let
extern_symbol
=
ExternSymbol
::
mock_arm32
();
let
cconv
=
CallingConvention
::
mock_arm32
();
let
cconv
=
CallingConvention
::
mock_arm32
();
let
call
=
Term
{
let
call
=
Term
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/tests.rs
View file @
d1d04f32
use
super
::
*
;
use
super
::
*
;
use
crate
::
intermediate_representation
::
DatatypeProperties
;
fn
bv
(
value
:
i64
)
->
ValueDomain
{
fn
bv
(
value
:
i64
)
->
ValueDomain
{
ValueDomain
::
from
(
Bitvector
::
from_i64
(
value
))
ValueDomain
::
from
(
Bitvector
::
from_i64
(
value
))
...
@@ -12,24 +11,6 @@ fn new_id(time: &str, reg_name: &str) -> AbstractIdentifier {
...
@@ -12,24 +11,6 @@ fn new_id(time: &str, reg_name: &str) -> AbstractIdentifier {
)
)
}
}
fn
mock_extern_symbol
(
name
:
&
str
)
->
(
Tid
,
ExternSymbol
)
{
let
arg
=
Arg
::
from_var
(
register
(
"RDX"
),
None
);
let
tid
=
Tid
::
new
(
"extern_"
.to_string
()
+
name
);
(
tid
.clone
(),
ExternSymbol
{
tid
,
addresses
:
vec!
[],
name
:
name
.into
(),
calling_convention
:
None
,
parameters
:
vec!
[
arg
.clone
()],
return_values
:
vec!
[
arg
],
no_return
:
false
,
has_var_args
:
false
,
},
)
}
fn
register
(
name
:
&
str
)
->
Variable
{
fn
register
(
name
:
&
str
)
->
Variable
{
Variable
{
Variable
{
name
:
name
.into
(),
name
:
name
.into
(),
...
@@ -70,36 +51,9 @@ fn return_term(target_name: &str) -> Term<Jmp> {
...
@@ -70,36 +51,9 @@ fn return_term(target_name: &str) -> Term<Jmp> {
}
}
fn
mock_project
()
->
(
Project
,
Config
)
{
fn
mock_project
()
->
(
Project
,
Config
)
{
let
program
=
Program
{
let
project
=
Project
::
mock_x64
();
subs
:
BTreeMap
::
new
(),
extern_symbols
:
vec!
[
mock_extern_symbol
(
"malloc"
),
mock_extern_symbol
(
"free"
),
mock_extern_symbol
(
"other"
),
]
.into_iter
()
.collect
(),
entry_points
:
BTreeSet
::
new
(),
address_base_offset
:
0
,
};
let
program_term
=
Term
{
tid
:
Tid
::
new
(
"program"
),
term
:
program
,
};
let
cconv
=
CallingConvention
::
mock_x64
();
let
register_set
=
vec!
[
"RAX"
,
"RCX"
,
"RDX"
,
"RBX"
,
"RSP"
,
"RBP"
,
"RSI"
,
"RDI"
]
.into_iter
()
.map
(|
name
|
Variable
::
mock
(
name
,
ByteSize
::
new
(
8
)))
.collect
();
(
(
Project
{
project
,
program
:
program_term
,
cpu_architecture
:
"x86_64"
.to_string
(),
stack_pointer_register
:
register
(
"RSP"
),
calling_conventions
:
BTreeMap
::
from_iter
([(
cconv
.name
.clone
(),
cconv
)]),
register_set
,
datatype_properties
:
DatatypeProperties
::
mock
(),
},
Config
{
Config
{
allocation_symbols
:
vec!
[
"malloc"
.into
()],
allocation_symbols
:
vec!
[
"malloc"
.into
()],
deallocation_symbols
:
vec!
[
"free"
.into
()],
deallocation_symbols
:
vec!
[
"free"
.into
()],
...
@@ -160,11 +114,11 @@ fn context_problem_implementation() {
...
@@ -160,11 +114,11 @@ fn context_problem_implementation() {
state
.set_register
(
&
register
(
"RBP"
),
bv
(
13
)
.into
());
state
.set_register
(
&
register
(
"RBP"
),
bv
(
13
)
.into
());
state
.set_register
(
&
register
(
"RSI"
),
bv
(
14
)
.into
());
state
.set_register
(
&
register
(
"RSI"
),
bv
(
14
)
.into
());
let
malloc
=
call_term
(
"
extern_
malloc"
);
let
malloc
=
call_term
(
"malloc"
);
let
mut
state_after_malloc
=
context
.update_call_stub
(
&
state
,
&
malloc
)
.unwrap
();
let
mut
state_after_malloc
=
context
.update_call_stub
(
&
state
,
&
malloc
)
.unwrap
();
assert_eq!
(
assert_eq!
(
state_after_malloc
.get_register
(
&
register
(
"R
D
X"
)),
state_after_malloc
.get_register
(
&
register
(
"R
A
X"
)),
Data
::
from_target
(
new_id
(
"call_
extern_malloc"
,
"RD
X"
),
bv
(
0
))
Data
::
from_target
(
new_id
(
"call_
malloc"
,
"RA
X"
),
bv
(
0
))
);
);
assert_eq!
(
state_after_malloc
.memory
.get_num_objects
(),
2
);
assert_eq!
(
state_after_malloc
.memory
.get_num_objects
(),
2
);
assert_eq!
(
assert_eq!
(
...
@@ -181,9 +135,9 @@ fn context_problem_implementation() {
...
@@ -181,9 +135,9 @@ fn context_problem_implementation() {
state_after_malloc
.set_register
(
state_after_malloc
.set_register
(
&
register
(
"RBP"
),
&
register
(
"RBP"
),
Data
::
from_target
(
new_id
(
"call_
extern_malloc"
,
"RD
X"
),
bv
(
0
)),
Data
::
from_target
(
new_id
(
"call_
malloc"
,
"RA
X"
),
bv
(
0
)),
);
);
let
free
=
call_term
(
"
extern_
free"
);
let
free
=
call_term
(
"free"
);
let
state_after_free
=
context
let
state_after_free
=
context
.update_call_stub
(
&
state_after_malloc
,
&
free
)
.update_call_stub
(
&
state_after_malloc
,
&
free
)
.unwrap
();
.unwrap
();
...
@@ -191,10 +145,10 @@ fn context_problem_implementation() {
...
@@ -191,10 +145,10 @@ fn context_problem_implementation() {
assert_eq!
(
state_after_free
.memory
.get_num_objects
(),
2
);
assert_eq!
(
state_after_free
.memory
.get_num_objects
(),
2
);
assert_eq!
(
assert_eq!
(
state_after_free
.get_register
(
&
register
(
"RBP"
)),
state_after_free
.get_register
(
&
register
(
"RBP"
)),
Data
::
from_target
(
new_id
(
"call_
extern_malloc"
,
"RD
X"
),
bv
(
0
))
Data
::
from_target
(
new_id
(
"call_
malloc"
,
"RA
X"
),
bv
(
0
))
);
);
let
other_extern_fn
=
call_term
(
"
extern_other
"
);
let
other_extern_fn
=
call_term
(
"
other_function
"
);
let
state_after_other_fn
=
context
.update_call_stub
(
&
state
,
&
other_extern_fn
)
.unwrap
();
let
state_after_other_fn
=
context
.update_call_stub
(
&
state
,
&
other_extern_fn
)
.unwrap
();
assert_eq!
(
assert_eq!
(
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/state/access_handling.rs
View file @
d1d04f32
...
@@ -245,8 +245,7 @@ impl State {
...
@@ -245,8 +245,7 @@ impl State {
let
mut
address_val
=
self
.eval
(
address_expr
);
let
mut
address_val
=
self
.eval
(
address_expr
);
if
let
Some
((
start_index
,
end_index
))
=
address_val
if
let
Some
((
start_index
,
end_index
))
=
address_val
.get_absolute_value
()
.get_absolute_value
()
.map
(|
val
|
val
.try_to_offset_interval
()
.ok
())
.and_then
(|
val
|
val
.try_to_offset_interval
()
.ok
())
.flatten
()
{
{
if
(
start_index
>
-
1024
&&
start_index
<
1024
)
if
(
start_index
>
-
1024
&&
start_index
<
1024
)
||
(
end_index
>
-
1024
&&
end_index
<
1024
)
||
(
end_index
>
-
1024
&&
end_index
<
1024
)
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/tests.rs
View file @
d1d04f32
use
crate
::
intermediate_representation
::
*
;
use
crate
::
intermediate_representation
::
*
;
use
std
::{
collections
::
BTreeMap
,
iter
::
FromIterator
};
pub
struct
Setup
;
pub
struct
Setup
;
...
@@ -394,133 +393,78 @@ fn mock_defs_for_memcpy(copy_from_global: bool, blk_num: usize) -> Vec<Term<Def>
...
@@ -394,133 +393,78 @@ fn mock_defs_for_memcpy(copy_from_global: bool, blk_num: usize) -> Vec<Term<Def>
impl
ExternSymbol
{
impl
ExternSymbol
{
pub
fn
mock_memcpy_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_memcpy_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"memcpy"
),
"memcpy"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"memcpy"
.to_string
(),
None
,
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
None
,
parameters
:
vec!
[
);
Arg
::
mock_register
(
"r0"
,
4
),
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r1"
,
4
),
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r2"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
),
],
Arg
::
mock_register
(
"r2"
,
4
),
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
];
no_return
:
false
,
ex
has_var_args
:
true
,
}
}
}
pub
fn
mock_sprintf_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_sprintf_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"sprintf"
),
"sprintf"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"sprintf"
.to_string
(),
None
,
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
None
,
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)],
);
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)];
no_return
:
false
,
ex
has_var_args
:
true
,
}
}
}
pub
fn
mock_scanf_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_scanf_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"scanf"
),
"scanf"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"scanf"
.to_string
(),
Some
(
Datatype
::
Pointer
),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
Some
(
Datatype
::
Integer
),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
)
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
true
,
}
}
}
pub
fn
mock_sscanf_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_sscanf_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"sscanf"
),
"sscanf"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"sscanf"
.to_string
(),
None
,
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
None
,
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)],
);
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)];
no_return
:
false
,
ex
has_var_args
:
true
,
}
}
}
pub
fn
mock_strcat_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_strcat_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"strcat"
),
"strcat"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"strcat"
.to_string
(),
None
,
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
None
,
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)],
);
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)];
no_return
:
false
,
ex
has_var_args
:
false
,
}
}
}
pub
fn
mock_free_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_free_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"free"
),
"free"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"free"
.to_string
(),
Some
(
Datatype
::
Pointer
),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
None
,
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
)
return_values
:
vec!
[],
no_return
:
false
,
has_var_args
:
false
,
}
}
}
pub
fn
mock_malloc_symbol_arm
()
->
ExternSymbol
{
pub
fn
mock_malloc_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
ExternSymbol
::
create_extern_symbol
(
tid
:
Tid
::
new
(
"malloc"
),
"malloc"
,
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
CallingConvention
::
mock_arm32
(),
name
:
"malloc"
.to_string
(),
Some
(
Datatype
::
Integer
),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
Some
(
Datatype
::
Pointer
),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
)
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
false
,
}
}
}
impl
CallingConvention
{
pub
fn
mock_standard_arm_32
()
->
CallingConvention
{
CallingConvention
{
name
:
"__stdcall"
.to_string
(),
// so that the mock is useable as standard calling convention in tests
integer_parameter_register
:
[
"r0"
,
"r1"
,
"r2"
,
"r3"
]
.iter
()
.map
(|
s
|
Variable
::
mock
(
s
,
4
))
.collect
(),
float_parameter_register
:
[
"s0"
,
"s1"
,
"s2"
,
"s3"
]
.iter
()
.map
(|
s
|
Expression
::
Var
(
Variable
::
mock
(
s
,
4
)))
.collect
(),
integer_return_register
:
vec!
[
Variable
::
mock
(
"r0"
,
4
)],
float_return_register
:
vec!
[],
callee_saved_register
:
vec!
[
Variable
::
mock
(
"r11"
,
4
)],
}
}
}
impl
DatatypeProperties
{
pub
fn
mock_standard_arm_32
()
->
DatatypeProperties
{
DatatypeProperties
{
char_size
:
ByteSize
::
new
(
1
),
double_size
:
ByteSize
::
new
(
8
),
float_size
:
ByteSize
::
new
(
4
),
integer_size
:
ByteSize
::
new
(
4
),
long_double_size
:
ByteSize
::
new
(
8
),
long_long_size
:
ByteSize
::
new
(
8
),
long_size
:
ByteSize
::
new
(
4
),
pointer_size
:
ByteSize
::
new
(
4
),
short_size
:
ByteSize
::
new
(
2
),
}
}
}
}
}
...
@@ -591,7 +535,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
...
@@ -591,7 +535,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
symbol_call_config
:
Vec
<
(
ExternSymbol
,
Vec
<
bool
>
)
>
,
symbol_call_config
:
Vec
<
(
ExternSymbol
,
Vec
<
bool
>
)
>
,
sub_name
:
&
str
,
sub_name
:
&
str
,
)
->
Project
{
)
->
Project
{
let
mut
program
=
Program
::
mock_
x64
();
let
mut
program
=
Program
::
mock_
arm32
();
let
mocked_sub
=
mock_sub_with_name_and_symbol_calls
(
sub_name
,
symbol_call_config
);
let
mocked_sub
=
mock_sub_with_name_and_symbol_calls
(
sub_name
,
symbol_call_config
);
program
.subs
.insert
(
mocked_sub
.tid
.clone
(),
mocked_sub
);
program
.subs
.insert
(
mocked_sub
.tid
.clone
(),
mocked_sub
);
...
@@ -611,21 +555,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
...
@@ -611,21 +555,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
program
.extern_symbols
.insert
(
malloc
.tid
.clone
(),
malloc
);
program
.extern_symbols
.insert
(
malloc
.tid
.clone
(),
malloc
);
program
.entry_points
.insert
(
Tid
::
new
(
sub_name
));
program
.entry_points
.insert
(
Tid
::
new
(
sub_name
));
let
register_set
=
[
"r0"
,
"r1"
,
"r2"
,
"r3"
,
"r11"
,
"sp"
]
let
mut
project
=
Project
::
mock_arm32
();
.iter
()
project
.program.term
=
program
;
.map
(|
name
|
Variable
::
mock
(
name
,
ByteSize
::
new
(
4
)))
project
.collect
();
let
cconv
=
CallingConvention
::
mock_standard_arm_32
();
Project
{
program
:
Term
{
tid
:
Tid
::
new
(
"program"
),
term
:
program
,
},
cpu_architecture
:
"arm_32"
.to_string
(),
stack_pointer_register
:
Variable
::
mock
(
"sp"
,
4u64
),
calling_conventions
:
BTreeMap
::
from_iter
([(
cconv
.name
.clone
(),
cconv
)]),
register_set
,
datatype_properties
:
DatatypeProperties
::
mock_standard_arm_32
(),
}
}
}
src/cwe_checker_lib/src/intermediate_representation/program.rs
View file @
d1d04f32
...
@@ -29,54 +29,18 @@ impl Program {
...
@@ -29,54 +29,18 @@ impl Program {
pub
fn
find_block
(
&
self
,
tid
:
&
Tid
)
->
Option
<&
Term
<
Blk
>>
{
pub
fn
find_block
(
&
self
,
tid
:
&
Tid
)
->
Option
<&
Term
<
Blk
>>
{
self
.subs
self
.subs
.iter
()
.iter
()
.map
(|(
_
,
sub
)|
sub
.term.blocks
.iter
())
.flat_map
(|(
_
,
sub
)|
sub
.term.blocks
.iter
())
.flatten
()
.find
(|
block
|
block
.tid
==
*
tid
)
.find
(|
block
|
block
.tid
==
*
tid
)
}
}
}
}
#[cfg(test)]
#[cfg(test)]
mod
tests
{
mod
tests
{
use
crate
::
intermediate_representation
::{
Arg
,
CallingConvention
,
Datatype
};
use
crate
::
intermediate_representation
::{
CallingConvention
,
Datatype
};
use
super
::
*
;
use
super
::
*
;
impl
Program
{
impl
Program
{
/// Returns extern symbol with argument/return register according to calling convention
fn
create_extern_symbol
(
name
:
&
str
,
cconv
:
CallingConvention
,
arg_type
:
Option
<
Datatype
>
,
return_type
:
Option
<
Datatype
>
,
)
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
name
),
addresses
:
vec!
[],
name
:
name
.to_string
(),
calling_convention
:
Some
(
cconv
.name
),
parameters
:
match
arg_type
{
Some
(
data_type
)
=>
{
vec!
[
Arg
::
from_var
(
cconv
.integer_parameter_register
[
0
]
.clone
(),
Some
(
data_type
),
)]
}
None
=>
vec!
[],
},
return_values
:
match
return_type
{
Some
(
data_type
)
=>
{
vec!
[
Arg
::
from_var
(
cconv
.integer_return_register
[
0
]
.clone
(),
Some
(
data_type
),
)]
}
None
=>
vec!
[],
},
no_return
:
false
,
has_var_args
:
false
,
}
}
fn
add_extern_symbols_to_program
(
a
:
Vec
<
(
Tid
,
ExternSymbol
)
>
)
->
Program
{
fn
add_extern_symbols_to_program
(
a
:
Vec
<
(
Tid
,
ExternSymbol
)
>
)
->
Program
{
Program
{
Program
{
subs
:
BTreeMap
::
new
(),
subs
:
BTreeMap
::
new
(),
...
@@ -87,19 +51,19 @@ mod tests {
...
@@ -87,19 +51,19 @@ mod tests {
}
}
/// Returns Program with malloc, free and other_function
/// Returns Program with malloc, free and other_function
pub
fn
mock_x64
()
->
Program
{
pub
fn
mock_x64
()
->
Program
{
let
malloc
=
Program
::
create_extern_symbol
(
let
malloc
=
ExternSymbol
::
create_extern_symbol
(
"malloc"
,
"malloc"
,
CallingConvention
::
mock_x64
(),
CallingConvention
::
mock_x64
(),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Pointer
),
Some
(
Datatype
::
Pointer
),
);
);
let
free
=
Program
::
create_extern_symbol
(
let
free
=
ExternSymbol
::
create_extern_symbol
(
"free"
,
"free"
,
CallingConvention
::
mock_x64
(),
CallingConvention
::
mock_x64
(),
Some
(
Datatype
::
Pointer
),
Some
(
Datatype
::
Pointer
),
None
,
None
,
);
);
let
other_function
=
Program
::
create_extern_symbol
(
let
other_function
=
ExternSymbol
::
create_extern_symbol
(
"other_function"
,
"other_function"
,
CallingConvention
::
mock_x64
(),
CallingConvention
::
mock_x64
(),
None
,
None
,
...
@@ -114,19 +78,19 @@ mod tests {
...
@@ -114,19 +78,19 @@ mod tests {
}
}
/// Returns Program with malloc, free and other_function
/// Returns Program with malloc, free and other_function
pub
fn
mock_arm32
()
->
Program
{
pub
fn
mock_arm32
()
->
Program
{
let
malloc
=
Program
::
create_extern_symbol
(
let
malloc
=
ExternSymbol
::
create_extern_symbol
(
"malloc"
,
"malloc"
,
CallingConvention
::
mock_arm32
(),
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Pointer
),
Some
(
Datatype
::
Pointer
),
);
);
let
free
=
Program
::
create_extern_symbol
(
let
free
=
ExternSymbol
::
create_extern_symbol
(
"free"
,
"free"
,
CallingConvention
::
mock_arm32
(),
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Pointer
),
Some
(
Datatype
::
Pointer
),
None
,
None
,
);
);
let
other_function
=
Program
::
create_extern_symbol
(
let
other_function
=
ExternSymbol
::
create_extern_symbol
(
"other_function"
,
"other_function"
,
CallingConvention
::
mock_arm32
(),
CallingConvention
::
mock_arm32
(),
None
,
None
,
...
...
src/cwe_checker_lib/src/intermediate_representation/project.rs
View file @
d1d04f32
...
@@ -301,7 +301,7 @@ mod tests {
...
@@ -301,7 +301,7 @@ mod tests {
Project
{
Project
{
program
:
Term
{
program
:
Term
{
tid
:
Tid
::
new
(
"program_tid"
),
tid
:
Tid
::
new
(
"program_tid"
),
term
:
Program
::
mock_
x64
(),
term
:
Program
::
mock_
arm32
(),
},
},
cpu_architecture
:
"arm32"
.to_string
(),
cpu_architecture
:
"arm32"
.to_string
(),
stack_pointer_register
:
Variable
::
mock
(
"sp"
,
4u64
),
stack_pointer_register
:
Variable
::
mock
(
"sp"
,
4u64
),
...
...
src/cwe_checker_lib/src/intermediate_representation/sub.rs
View file @
d1d04f32
...
@@ -387,5 +387,40 @@ mod tests {
...
@@ -387,5 +387,40 @@ mod tests {
has_var_args
:
true
,
has_var_args
:
true
,
}
}
}
}
/// Returns extern symbol with argument/return register according to calling convention
pub
fn
create_extern_symbol
(
name
:
&
str
,
cconv
:
CallingConvention
,
arg_type
:
Option
<
Datatype
>
,
return_type
:
Option
<
Datatype
>
,
)
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
name
),
addresses
:
vec!
[],
name
:
name
.to_string
(),
calling_convention
:
Some
(
cconv
.name
),
parameters
:
match
arg_type
{
Some
(
data_type
)
=>
{
vec!
[
Arg
::
from_var
(
cconv
.integer_parameter_register
[
0
]
.clone
(),
Some
(
data_type
),
)]
}
None
=>
vec!
[],
},
return_values
:
match
return_type
{
Some
(
data_type
)
=>
{
vec!
[
Arg
::
from_var
(
cconv
.integer_return_register
[
0
]
.clone
(),
Some
(
data_type
),
)]
}
None
=>
vec!
[],
},
no_return
:
false
,
has_var_args
:
false
,
}
}
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment