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>(
values_left
.iter
()
.filter_map
(|(
id
,
offset
)|
{
values_right
.get
(
id
)
.map
(|
other_offset
|
{
if
let
Ok
(
intersected_offset
)
=
offset
.clone
()
.intersect
(
other_offset
)
{
Some
((
id
.clone
(),
intersected_offset
))
}
else
{
None
}
})
.flatten
()
values_right
.get
(
id
)
.and_then
(|
other_offset
|
{
if
let
Ok
(
intersected_offset
)
=
offset
.clone
()
.intersect
(
other_offset
)
{
Some
((
id
.clone
(),
intersected_offset
))
}
else
{
None
}
})
})
.collect
()
}
...
...
@@ -26,8 +23,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_signed_less_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
.absolute_value
.map
(|
value
|
value
.add_signed_less_equal_bound
(
bound
)
.ok
())
.flatten
();
.and_then
(|
value
|
value
.add_signed_less_equal_bound
(
bound
)
.ok
());
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
}
else
{
...
...
@@ -38,8 +34,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_unsigned_less_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
.absolute_value
.map
(|
value
|
value
.add_unsigned_less_equal_bound
(
bound
)
.ok
())
.flatten
();
.and_then
(|
value
|
value
.add_unsigned_less_equal_bound
(
bound
)
.ok
());
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
}
else
{
...
...
@@ -50,8 +45,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_signed_greater_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
.absolute_value
.map
(|
value
|
value
.add_signed_greater_equal_bound
(
bound
)
.ok
())
.flatten
();
.and_then
(|
value
|
value
.add_signed_greater_equal_bound
(
bound
)
.ok
());
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
}
else
{
...
...
@@ -62,8 +56,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_unsigned_greater_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
.absolute_value
.map
(|
value
|
value
.add_unsigned_greater_equal_bound
(
bound
)
.ok
())
.flatten
();
.and_then
(|
value
|
value
.add_unsigned_greater_equal_bound
(
bound
)
.ok
());
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
}
else
{
...
...
@@ -74,8 +67,7 @@ impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for Da
fn
add_not_equal_bound
(
mut
self
,
bound
:
&
Bitvector
)
->
Result
<
Self
,
Error
>
{
self
.absolute_value
=
self
.absolute_value
.map
(|
value
|
value
.add_not_equal_bound
(
bound
)
.ok
())
.flatten
();
.and_then
(|
value
|
value
.add_not_equal_bound
(
bound
)
.ok
());
if
self
.is_empty
()
{
Err
(
anyhow!
(
"Empty value"
))
}
else
{
...
...
src/cwe_checker_lib/src/analysis/function_signature/state/tests.rs
View file @
d1d04f32
...
...
@@ -2,11 +2,11 @@ use super::*;
impl
State
{
/// Generate a mock state for an ARM-32 state.
pub
fn
mock
()
->
State
{
pub
fn
mock
_arm32
()
->
State
{
State
::
new
(
&
Tid
::
new
(
"mock_fn"
),
&
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 {
#[test]
fn
test_new
()
{
let
state
=
State
::
mock
();
let
state
=
State
::
mock
_arm32
();
// Test the generated stack
assert_eq!
(
&
state
.stack_id
,
&
mock_stack_id
());
assert_eq!
(
state
.stack
.iter
()
.len
(),
0
);
// 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!
(
state
.get_register
(
&
Variable
::
mock
(
"sp"
,
4
)),
DataDomain
::
from_target
(
...
...
@@ -53,11 +53,14 @@ fn test_new() {
)
);
// 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
()
{
assert_eq!
(
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
());
}
...
...
@@ -65,7 +68,7 @@ fn test_new() {
#[test]
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
value
:
DataDomain
<
BitvectorDomain
>
=
Bitvector
::
from_i32
(
0
)
.into
();
// write and load a value to the current stack frame
...
...
@@ -81,12 +84,12 @@ fn test_store_and_load_from_stack() {
let
stack_param_id
=
mock_stack_param_id
(
4
,
4
);
let
stack_param
=
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!
(
state
.load_value
(
address
.clone
(),
ByteSize
::
new
(
4
)),
stack_param
);
assert_eq!
(
state
.tracked_ids
.iter
()
.len
(),
9
);
assert_eq!
(
state
.tracked_ids
.iter
()
.len
(),
7
);
assert_eq!
(
state
.tracked_ids
...
...
@@ -99,7 +102,7 @@ fn test_store_and_load_from_stack() {
#[test]
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)
let
address
=
DataDomain
::
from_target
(
mock_stack_id
(),
Bitvector
::
from_i32
(
0
)
.into
());
let
stack_param_id
=
mock_stack_param_id
(
0
,
4
);
...
...
@@ -122,7 +125,7 @@ fn test_load_unsized_from_stack() {
#[test]
fn
test_eval
()
{
let
mut
state
=
State
::
mock
();
let
mut
state
=
State
::
mock
_arm32
();
// Test the eval method
let
expr
=
Expression
::
Var
(
Variable
::
mock
(
"sp"
,
4
))
.plus_const
(
42
);
assert_eq!
(
...
...
@@ -139,7 +142,7 @@ fn test_eval() {
#[test]
fn
test_extern_symbol_handling
()
{
let
mut
state
=
State
::
mock
();
let
mut
state
=
State
::
mock
_arm32
();
let
extern_symbol
=
ExternSymbol
::
mock_arm32
();
let
cconv
=
CallingConvention
::
mock_arm32
();
let
call
=
Term
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/tests.rs
View file @
d1d04f32
use
super
::
*
;
use
crate
::
intermediate_representation
::
DatatypeProperties
;
fn
bv
(
value
:
i64
)
->
ValueDomain
{
ValueDomain
::
from
(
Bitvector
::
from_i64
(
value
))
...
...
@@ -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
{
Variable
{
name
:
name
.into
(),
...
...
@@ -70,36 +51,9 @@ fn return_term(target_name: &str) -> Term<Jmp> {
}
fn
mock_project
()
->
(
Project
,
Config
)
{
let
program
=
Program
{
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
();
let
project
=
Project
::
mock_x64
();
(
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
(),
},
project
,
Config
{
allocation_symbols
:
vec!
[
"malloc"
.into
()],
deallocation_symbols
:
vec!
[
"free"
.into
()],
...
...
@@ -160,11 +114,11 @@ fn context_problem_implementation() {
state
.set_register
(
&
register
(
"RBP"
),
bv
(
13
)
.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
();
assert_eq!
(
state_after_malloc
.get_register
(
&
register
(
"R
D
X"
)),
Data
::
from_target
(
new_id
(
"call_
extern_malloc"
,
"RD
X"
),
bv
(
0
))
state_after_malloc
.get_register
(
&
register
(
"R
A
X"
)),
Data
::
from_target
(
new_id
(
"call_
malloc"
,
"RA
X"
),
bv
(
0
))
);
assert_eq!
(
state_after_malloc
.memory
.get_num_objects
(),
2
);
assert_eq!
(
...
...
@@ -181,9 +135,9 @@ fn context_problem_implementation() {
state_after_malloc
.set_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
free
=
call_term
(
"
extern_
free"
);
let
free
=
call_term
(
"free"
);
let
state_after_free
=
context
.update_call_stub
(
&
state_after_malloc
,
&
free
)
.unwrap
();
...
...
@@ -191,10 +145,10 @@ fn context_problem_implementation() {
assert_eq!
(
state_after_free
.memory
.get_num_objects
(),
2
);
assert_eq!
(
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
();
assert_eq!
(
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/state/access_handling.rs
View file @
d1d04f32
...
...
@@ -245,8 +245,7 @@ impl State {
let
mut
address_val
=
self
.eval
(
address_expr
);
if
let
Some
((
start_index
,
end_index
))
=
address_val
.get_absolute_value
()
.map
(|
val
|
val
.try_to_offset_interval
()
.ok
())
.flatten
()
.and_then
(|
val
|
val
.try_to_offset_interval
()
.ok
())
{
if
(
start_index
>
-
1024
&&
start_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
std
::{
collections
::
BTreeMap
,
iter
::
FromIterator
};
pub
struct
Setup
;
...
...
@@ -394,133 +393,78 @@ fn mock_defs_for_memcpy(copy_from_global: bool, blk_num: usize) -> Vec<Term<Def>
impl
ExternSymbol
{
pub
fn
mock_memcpy_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"memcpy"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"memcpy"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
),
Arg
::
mock_register
(
"r2"
,
4
),
],
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
true
,
}
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
"memcpy"
,
CallingConvention
::
mock_arm32
(),
None
,
None
,
);
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
),
Arg
::
mock_register
(
"r2"
,
4
),
];
ex
}
pub
fn
mock_sprintf_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"sprintf"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"sprintf"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)],
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
true
,
}
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
"sprintf"
,
CallingConvention
::
mock_arm32
(),
None
,
None
,
);
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)];
ex
}
pub
fn
mock_scanf_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"scanf"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"scanf"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
true
,
}
ExternSymbol
::
create_extern_symbol
(
"scanf"
,
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Pointer
),
Some
(
Datatype
::
Integer
),
)
}
pub
fn
mock_sscanf_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"sscanf"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"sscanf"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)],
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
true
,
}
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
"sscanf"
,
CallingConvention
::
mock_arm32
(),
None
,
None
,
);
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)];
ex
}
pub
fn
mock_strcat_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"strcat"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"strcat"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)],
return_values
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
no_return
:
false
,
has_var_args
:
false
,
}
let
mut
ex
=
ExternSymbol
::
create_extern_symbol
(
"strcat"
,
CallingConvention
::
mock_arm32
(),
None
,
None
,
);
ex
.parameters
=
vec!
[
Arg
::
mock_register
(
"r0"
,
4
),
Arg
::
mock_register
(
"r1"
,
4
)];
ex
}
pub
fn
mock_free_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"free"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"free"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
parameters
:
vec!
[
Arg
::
mock_register
(
"r0"
,
4
)],
return_values
:
vec!
[],
no_return
:
false
,
has_var_args
:
false
,
}
ExternSymbol
::
create_extern_symbol
(
"free"
,
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Pointer
),
None
,
)
}
pub
fn
mock_malloc_symbol_arm
()
->
ExternSymbol
{
ExternSymbol
{
tid
:
Tid
::
new
(
"malloc"
),
addresses
:
vec!
[
"UNKNOWN"
.to_string
()],
name
:
"malloc"
.to_string
(),
calling_convention
:
Some
(
"__stdcall"
.to_string
()),
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
),
}
ExternSymbol
::
create_extern_symbol
(
"malloc"
,
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Pointer
),
)
}
}
...
...
@@ -591,7 +535,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
symbol_call_config
:
Vec
<
(
ExternSymbol
,
Vec
<
bool
>
)
>
,
sub_name
:
&
str
,
)
->
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
);
program
.subs
.insert
(
mocked_sub
.tid
.clone
(),
mocked_sub
);
...
...
@@ -611,21 +555,7 @@ pub fn mock_project_with_intraprocedural_control_flow(
program
.extern_symbols
.insert
(
malloc
.tid
.clone
(),
malloc
);
program
.entry_points
.insert
(
Tid
::
new
(
sub_name
));
let
register_set
=
[
"r0"
,
"r1"
,
"r2"
,
"r3"
,
"r11"
,
"sp"
]
.iter
()
.map
(|
name
|
Variable
::
mock
(
name
,
ByteSize
::
new
(
4
)))
.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
(),
}
let
mut
project
=
Project
::
mock_arm32
();
project
.program.term
=
program
;
project
}
src/cwe_checker_lib/src/intermediate_representation/program.rs
View file @
d1d04f32
...
...
@@ -29,54 +29,18 @@ impl Program {
pub
fn
find_block
(
&
self
,
tid
:
&
Tid
)
->
Option
<&
Term
<
Blk
>>
{
self
.subs
.iter
()
.map
(|(
_
,
sub
)|
sub
.term.blocks
.iter
())
.flatten
()
.flat_map
(|(
_
,
sub
)|
sub
.term.blocks
.iter
())
.find
(|
block
|
block
.tid
==
*
tid
)
}
}
#[cfg(test)]
mod
tests
{
use
crate
::
intermediate_representation
::{
Arg
,
CallingConvention
,
Datatype
};
use
crate
::
intermediate_representation
::{
CallingConvention
,
Datatype
};
use
super
::
*
;
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
{
Program
{
subs
:
BTreeMap
::
new
(),
...
...
@@ -87,19 +51,19 @@ mod tests {
}
/// Returns Program with malloc, free and other_function
pub
fn
mock_x64
()
->
Program
{
let
malloc
=
Program
::
create_extern_symbol
(
let
malloc
=
ExternSymbol
::
create_extern_symbol
(
"malloc"
,
CallingConvention
::
mock_x64
(),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Pointer
),
);
let
free
=
Program
::
create_extern_symbol
(
let
free
=
ExternSymbol
::
create_extern_symbol
(
"free"
,
CallingConvention
::
mock_x64
(),
Some
(
Datatype
::
Pointer
),
None
,
);
let
other_function
=
Program
::
create_extern_symbol
(
let
other_function
=
ExternSymbol
::
create_extern_symbol
(
"other_function"
,
CallingConvention
::
mock_x64
(),
None
,
...
...
@@ -114,19 +78,19 @@ mod tests {
}
/// Returns Program with malloc, free and other_function
pub
fn
mock_arm32
()
->
Program
{
let
malloc
=
Program
::
create_extern_symbol
(
let
malloc
=
ExternSymbol
::
create_extern_symbol
(
"malloc"
,
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Integer
),
Some
(
Datatype
::
Pointer
),
);
let
free
=
Program
::
create_extern_symbol
(
let
free
=
ExternSymbol
::
create_extern_symbol
(
"free"
,
CallingConvention
::
mock_arm32
(),
Some
(
Datatype
::
Pointer
),
None
,
);
let
other_function
=
Program
::
create_extern_symbol
(
let
other_function
=
ExternSymbol
::
create_extern_symbol
(
"other_function"
,
CallingConvention
::
mock_arm32
(),
None
,
...
...
src/cwe_checker_lib/src/intermediate_representation/project.rs
View file @
d1d04f32
...
...
@@ -301,7 +301,7 @@ mod tests {
Project
{
program
:
Term
{
tid
:
Tid
::
new
(
"program_tid"
),
term
:
Program
::
mock_
x64
(),
term
:
Program
::
mock_
arm32
(),
},
cpu_architecture
:
"arm32"
.to_string
(),
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 {
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