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
170f44b1
Unverified
Commit
170f44b1
authored
May 23, 2022
by
van den Bosch
Committed by
GitHub
May 23, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor runtime memory image (#324)
parent
576c3dd9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
110 additions
and
164 deletions
+110
-164
main.rs
src/caller/src/main.rs
+6
-7
id_manipulation.rs
...src/analysis/pointer_inference/context/id_manipulation.rs
+1
-1
mod.rs
...checker_lib/src/analysis/pointer_inference/context/mod.rs
+19
-17
trait_impls.rs
...lib/src/analysis/pointer_inference/context/trait_impls.rs
+5
-3
mod.rs
src/cwe_checker_lib/src/analysis/pointer_inference/mod.rs
+5
-1
cwe_helpers.rs
...src/analysis/pointer_inference/object_list/cwe_helpers.rs
+2
-0
mod.rs
...ker_lib/src/analysis/pointer_inference/object_list/mod.rs
+1
-1
access_handling.rs
...b/src/analysis/pointer_inference/state/access_handling.rs
+0
-2
mod.rs
...e_checker_lib/src/analysis/pointer_inference/state/mod.rs
+0
-1
tests.rs
...checker_lib/src/analysis/pointer_inference/state/tests.rs
+0
-1
vsa_result_impl.rs
...ker_lib/src/analysis/pointer_inference/vsa_result_impl.rs
+1
-1
mod.rs
...hecker_lib/src/analysis/string_abstraction/context/mod.rs
+0
-6
symbol_calls.rs
...b/src/analysis/string_abstraction/context/symbol_calls.rs
+3
-2
memcpy.rs
...nalysis/string_abstraction/context/symbol_calls/memcpy.rs
+2
-2
scanf.rs
...analysis/string_abstraction/context/symbol_calls/scanf.rs
+13
-10
sprintf.rs
...alysis/string_abstraction/context/symbol_calls/sprintf.rs
+3
-4
strcat.rs
...nalysis/string_abstraction/context/symbol_calls/strcat.rs
+3
-2
tests.rs
...analysis/string_abstraction/context/symbol_calls/tests.rs
+0
-1
tests.rs
...cker_lib/src/analysis/string_abstraction/context/tests.rs
+0
-2
trait_impls.rs
...ib/src/analysis/string_abstraction/context/trait_impls.rs
+3
-3
tests.rs
.../analysis/string_abstraction/context/trait_impls/tests.rs
+1
-3
mod.rs
src/cwe_checker_lib/src/analysis/string_abstraction/mod.rs
+3
-16
mod.rs
..._checker_lib/src/analysis/string_abstraction/state/mod.rs
+1
-2
cwe_134.rs
src/cwe_checker_lib/src/checkers/cwe_134.rs
+3
-4
cwe_467.rs
src/cwe_checker_lib/src/checkers/cwe_467.rs
+6
-17
cwe_476.rs
src/cwe_checker_lib/src/checkers/cwe_476.rs
+1
-6
context.rs
src/cwe_checker_lib/src/checkers/cwe_476/context.rs
+7
-18
cwe_560.rs
src/cwe_checker_lib/src/checkers/cwe_560.rs
+4
-11
cwe_78.rs
src/cwe_checker_lib/src/checkers/cwe_78.rs
+5
-2
mod.rs
src/cwe_checker_lib/src/intermediate_representation/mod.rs
+2
-0
project.rs
...we_checker_lib/src/intermediate_representation/project.rs
+5
-2
runtime_memory_image.rs
...b/src/intermediate_representation/runtime_memory_image.rs
+0
-0
lib.rs
src/cwe_checker_lib/src/lib.rs
+2
-10
term.rs
src/cwe_checker_lib/src/pcode/term.rs
+2
-0
arguments.rs
src/cwe_checker_lib/src/utils/arguments.rs
+1
-3
tests.rs
src/cwe_checker_lib/src/utils/arguments/tests.rs
+0
-3
binary.rs
src/cwe_checker_lib/src/utils/binary.rs
+0
-0
No files found.
src/caller/src/main.rs
View file @
170f44b1
...
...
@@ -4,7 +4,8 @@
extern
crate
cwe_checker_lib
;
// Needed for the docstring-link to work
use
cwe_checker_lib
::
analysis
::
graph
;
use
cwe_checker_lib
::
utils
::
binary
::{
BareMetalConfig
,
RuntimeMemoryImage
};
use
cwe_checker_lib
::
intermediate_representation
::
RuntimeMemoryImage
;
use
cwe_checker_lib
::
utils
::
binary
::
BareMetalConfig
;
use
cwe_checker_lib
::
utils
::
log
::{
print_all_messages
,
LogLevel
};
use
cwe_checker_lib
::
utils
::{
get_ghidra_plugin_path
,
read_config_file
};
use
cwe_checker_lib
::
AnalysisResults
;
...
...
@@ -159,6 +160,9 @@ fn run_with_ghidra(args: &CmdlineArgs) {
// so that other analyses do not have to adjust their addresses.
runtime_memory_image
.add_global_memory_offset
(
project
.program.term.address_base_offset
);
}
project
.runtime_memory_image
=
runtime_memory_image
;
// Generate the control flow graph of the program
let
extern_sub_tids
=
project
.program
...
...
@@ -169,12 +173,7 @@ fn run_with_ghidra(args: &CmdlineArgs) {
.collect
();
let
control_flow_graph
=
graph
::
get_program_cfg
(
&
project
.program
,
extern_sub_tids
);
let
analysis_results
=
AnalysisResults
::
new
(
&
binary
,
&
runtime_memory_image
,
&
control_flow_graph
,
&
project
,
);
let
analysis_results
=
AnalysisResults
::
new
(
&
binary
,
&
control_flow_graph
,
&
project
);
let
modules_depending_on_string_abstraction
=
BTreeSet
::
from_iter
([
"CWE78"
]);
let
modules_depending_on_pointer_inference
=
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/id_manipulation.rs
View file @
170f44b1
...
...
@@ -22,7 +22,7 @@ impl<'a> Context<'a> {
for
param
in
callee_fn_sig
.parameters
.keys
()
{
let
param_id
=
AbstractIdentifier
::
from_arg
(
callee_tid
,
param
);
if
let
Ok
(
param_value
)
=
state_before_call
.eval_parameter_arg
(
param
,
self
.runtime_memory_image
)
state_before_call
.eval_parameter_arg
(
param
,
&
self
.project
.runtime_memory_image
)
{
id_map
.insert
(
param_id
,
param_value
);
}
else
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/mod.rs
View file @
170f44b1
use
crate
::
abstract_domain
::
*
;
use
crate
::
analysis
::
function_signature
::
FunctionSignature
;
use
crate
::
analysis
::
graph
::
Graph
;
use
crate
::
intermediate_representation
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
log
::
*
;
use
crate
::{
abstract_domain
::
*
,
utils
::
binary
::
RuntimeMemoryImage
};
use
std
::
collections
::{
BTreeMap
,
BTreeSet
};
use
super
::
state
::
State
;
...
...
@@ -24,9 +24,6 @@ pub struct Context<'a> {
pub
graph
:
&
'a
Graph
<
'a
>
,
/// A reference to the `Project` object representing the binary
pub
project
:
&
'a
Project
,
/// The runtime memory image for reading global read-only variables.
/// Note that values of writeable global memory segments are not tracked.
pub
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
/// Maps the TIDs of functions that shall be treated as extern symbols to the `ExternSymbol` object representing it.
pub
extern_symbol_map
:
&
'a
BTreeMap
<
Tid
,
ExternSymbol
>
,
/// Maps the TIDs of internal functions to the function signatures computed for it.
...
...
@@ -54,7 +51,6 @@ impl<'a> Context<'a> {
Context
{
graph
:
analysis_results
.control_flow_graph
,
project
:
analysis_results
.project
,
runtime_memory_image
:
analysis_results
.runtime_memory_image
,
extern_symbol_map
:
&
analysis_results
.project.program.term.extern_symbols
,
fn_signatures
:
analysis_results
.function_signatures
.unwrap
(),
log_collector
,
...
...
@@ -73,7 +69,9 @@ impl<'a> Context<'a> {
address
:
&
Expression
,
)
->
bool
{
if
self
.project.cpu_architecture
.contains
(
"MIPS"
)
&&
var
.name
==
"gp"
{
if
let
Ok
(
gp_val
)
=
state
.load_value
(
address
,
var
.size
,
self
.runtime_memory_image
)
{
if
let
Ok
(
gp_val
)
=
state
.load_value
(
address
,
var
.size
,
&
self
.project.runtime_memory_image
)
{
gp_val
.is_top
()
}
else
{
true
...
...
@@ -137,23 +135,23 @@ impl<'a> Context<'a> {
"malloc"
=>
{
let
size_parameter
=
extern_symbol
.parameters
.get
(
0
)
.unwrap
();
state
.eval_parameter_arg
(
size_parameter
,
self
.runtime_memory_image
)
.eval_parameter_arg
(
size_parameter
,
&
self
.project
.runtime_memory_image
)
.unwrap_or_else
(|
_
|
Data
::
new_top
(
address_bytesize
))
}
"realloc"
=>
{
let
size_parameter
=
extern_symbol
.parameters
.get
(
1
)
.unwrap
();
state
.eval_parameter_arg
(
size_parameter
,
self
.runtime_memory_image
)
.eval_parameter_arg
(
size_parameter
,
&
self
.project
.runtime_memory_image
)
.unwrap_or_else
(|
_
|
Data
::
new_top
(
address_bytesize
))
}
"calloc"
=>
{
let
size_param1
=
extern_symbol
.parameters
.get
(
0
)
.unwrap
();
let
size_param2
=
extern_symbol
.parameters
.get
(
1
)
.unwrap
();
let
param1_value
=
state
.eval_parameter_arg
(
size_param1
,
self
.runtime_memory_image
)
.eval_parameter_arg
(
size_param1
,
&
self
.project
.runtime_memory_image
)
.unwrap_or_else
(|
_
|
Data
::
new_top
(
address_bytesize
));
let
param2_value
=
state
.eval_parameter_arg
(
size_param2
,
self
.runtime_memory_image
)
.eval_parameter_arg
(
size_param2
,
&
self
.project
.runtime_memory_image
)
.unwrap_or_else
(|
_
|
Data
::
new_top
(
address_bytesize
));
param1_value
.bin_op
(
BinOpType
::
IntMult
,
&
param2_value
)
}
...
...
@@ -225,7 +223,7 @@ impl<'a> Context<'a> {
match
extern_symbol
.get_unique_parameter
()
{
Ok
(
parameter
)
=>
{
let
parameter_value
=
state
.eval_parameter_arg
(
parameter
,
self
.runtime_memory_image
);
state
.eval_parameter_arg
(
parameter
,
&
self
.project
.runtime_memory_image
);
match
parameter_value
{
Ok
(
memory_object_pointer
)
=>
{
if
let
Err
(
possible_double_frees
)
=
...
...
@@ -275,7 +273,7 @@ impl<'a> Context<'a> {
I
:
Iterator
<
Item
=
&
'iter
Arg
>
,
{
for
parameter
in
parameters
{
match
state
.eval_parameter_arg
(
parameter
,
self
.runtime_memory_image
)
{
match
state
.eval_parameter_arg
(
parameter
,
&
self
.project
.runtime_memory_image
)
{
Ok
(
value
)
=>
{
if
state
.memory
.is_dangling_pointer
(
&
value
,
true
)
{
state
...
...
@@ -317,10 +315,12 @@ impl<'a> Context<'a> {
extern_symbol
:
&
ExternSymbol
,
)
{
for
parameter
in
extern_symbol
.parameters
.iter
()
{
match
state
.eval_parameter_arg
(
parameter
,
self
.runtime_memory_image
)
{
match
state
.eval_parameter_arg
(
parameter
,
&
self
.project
.runtime_memory_image
)
{
Ok
(
data
)
=>
{
if
state
.pointer_contains_out_of_bounds_target
(
&
data
,
self
.runtime_memory_image
)
{
if
state
.pointer_contains_out_of_bounds_target
(
&
data
,
&
self
.project.runtime_memory_image
,
)
{
let
warning
=
CweWarning
{
name
:
"CWE119"
.to_string
(),
version
:
VERSION
.to_string
(),
...
...
@@ -394,7 +394,7 @@ impl<'a> Context<'a> {
extern_symbol
:
&
ExternSymbol
,
)
->
State
{
self
.log_debug
(
new_state
.clear_stack_parameter
(
extern_symbol
,
self
.runtime_memory_image
),
new_state
.clear_stack_parameter
(
extern_symbol
,
&
self
.project
.runtime_memory_image
),
Some
(
&
call
.tid
),
);
let
calling_conv
=
self
.project
.get_calling_convention
(
extern_symbol
);
...
...
@@ -413,7 +413,9 @@ impl<'a> Context<'a> {
}
}
else
{
for
parameter
in
extern_symbol
.parameters
.iter
()
{
if
let
Ok
(
data
)
=
state
.eval_parameter_arg
(
parameter
,
self
.runtime_memory_image
)
{
if
let
Ok
(
data
)
=
state
.eval_parameter_arg
(
parameter
,
&
self
.project.runtime_memory_image
)
{
possible_referenced_ids
.extend
(
data
.referenced_ids
()
.cloned
());
}
}
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/trait_impls.rs
View file @
170f44b1
...
...
@@ -42,7 +42,9 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
Ok
(
false
)
=>
(),
// no null dereference detected
}
// check for out-of-bounds memory access
if
new_state
.contains_out_of_bounds_mem_access
(
&
def
.term
,
self
.runtime_memory_image
)
{
if
new_state
.contains_out_of_bounds_mem_access
(
&
def
.term
,
&
self
.project.runtime_memory_image
)
{
let
(
warning_name
,
warning_description
)
=
match
&
def
.term
{
Def
::
Load
{
..
}
=>
(
"CWE125"
,
...
...
@@ -75,7 +77,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
match
&
def
.term
{
Def
::
Store
{
address
,
value
}
=>
{
self
.log_debug
(
new_state
.handle_store
(
address
,
value
,
self
.runtime_memory_image
),
new_state
.handle_store
(
address
,
value
,
&
self
.project
.runtime_memory_image
),
Some
(
&
def
.tid
),
);
Some
(
new_state
)
...
...
@@ -87,7 +89,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
Def
::
Load
{
var
,
address
}
=>
{
if
!
self
.is_mips_gp_load_to_top_value
(
state
,
var
,
address
)
{
self
.log_debug
(
new_state
.handle_load
(
var
,
address
,
self
.runtime_memory_image
),
new_state
.handle_load
(
var
,
address
,
&
self
.project
.runtime_memory_image
),
Some
(
&
def
.tid
),
);
}
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/mod.rs
View file @
170f44b1
...
...
@@ -275,7 +275,11 @@ impl<'a> PointerInference<'a> {
}
Def
::
Load
{
var
,
address
}
=>
{
let
loaded_value
=
state
.load_value
(
address
,
var
.size
,
context
.runtime_memory_image
)
.load_value
(
address
,
var
.size
,
&
context
.project.runtime_memory_image
,
)
.unwrap_or_else
(|
_
|
Data
::
new_top
(
var
.size
));
self
.values_at_defs
.insert
(
def
.tid
.clone
(),
loaded_value
);
self
.addresses_at_defs
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/object_list/cwe_helpers.rs
View file @
170f44b1
...
...
@@ -2,6 +2,8 @@
//! or check whether they are violated.
//! E.g. checks for use-after-free or buffer overflow checks.
use
crate
::
intermediate_representation
::
RuntimeMemoryImage
;
use
super
::
*
;
impl
AbstractObjectList
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/object_list/mod.rs
View file @
170f44b1
use
super
::
object
::
*
;
use
super
::{
Data
,
ValueDomain
};
use
crate
::
abstract_domain
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::{
abstract_domain
::
*
,
utils
::
binary
::
RuntimeMemoryImage
};
use
serde
::{
Deserialize
,
Serialize
};
use
std
::
collections
::{
BTreeMap
,
BTreeSet
};
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/state/access_handling.rs
View file @
170f44b1
//! Methods of [`State`] for handling memory and register access operations.
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
super
::
*
;
impl
State
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/state/mod.rs
View file @
170f44b1
...
...
@@ -4,7 +4,6 @@ use crate::abstract_domain::*;
use
crate
::
analysis
::
function_signature
::
FunctionSignature
;
use
crate
::
intermediate_representation
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
std
::
collections
::{
BTreeMap
,
BTreeSet
};
mod
access_handling
;
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/state/tests.rs
View file @
170f44b1
use
super
::
super
::
ValueDomain
;
use
super
::
*
;
use
crate
::
analysis
::
pointer_inference
::
object
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
Expression
::
*
;
fn
bv
(
value
:
i64
)
->
ValueDomain
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/vsa_result_impl.rs
View file @
170f44b1
...
...
@@ -27,7 +27,7 @@ impl<'a> VsaResult for PointerInference<'a> {
let
state
=
self
.states_at_tids
.get
(
jmp_tid
)
?
;
let
context
=
self
.computation
.get_context
()
.get_context
();
state
.eval_parameter_arg
(
parameter
,
contex
t
.runtime_memory_image
)
.eval_parameter_arg
(
parameter
,
&
context
.projec
t.runtime_memory_image
)
.ok
()
}
}
src/cwe_checker_lib/src/analysis/string_abstraction/context/mod.rs
View file @
170f44b1
...
...
@@ -17,7 +17,6 @@ use crate::{
pointer_inference
::
State
as
PointerInferenceState
,
},
intermediate_representation
::{
Def
,
ExternSymbol
,
Project
,
Term
,
Tid
},
utils
::
binary
::
RuntimeMemoryImage
,
};
use
super
::{
state
::
State
,
Config
};
...
...
@@ -31,9 +30,6 @@ mod trait_impls;
pub
struct
Context
<
'a
,
T
:
AbstractDomain
+
DomainInsertion
+
HasTop
+
Eq
+
From
<
String
>>
{
/// A reference to the `Project` object representing the binary
pub
project
:
&
'a
Project
,
/// The runtime memory image for reading global read-only variables.
/// Note that values of writeable global memory segments are not tracked.
pub
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
/// A pointer to the results of the pointer inference analysis.
/// They are used to determine the targets of pointers to memory,
/// which in turn is used to keep track of taint on the stack or on the heap.
...
...
@@ -62,7 +58,6 @@ impl<'a, T: AbstractDomain + HasTop + Eq + From<String> + DomainInsertion> Conte
/// Create a new context object for a given project.
pub
fn
new
(
project
:
&
'a
Project
,
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
pointer_inference_results
:
&
'a
PointerInferenceComputation
<
'a
>
,
config
:
Config
,
)
->
Context
<
'a
,
T
>
{
...
...
@@ -95,7 +90,6 @@ impl<'a, T: AbstractDomain + HasTop + Eq + From<String> + DomainInsertion> Conte
Context
{
project
,
runtime_memory_image
,
pointer_inference_results
,
format_string_index_map
:
config
.format_string_index
.into_iter
()
.collect
(),
string_symbol_map
,
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/symbol_calls.rs
View file @
170f44b1
...
...
@@ -169,7 +169,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
/// Inserts a char constant into the format string.
pub
fn
get_constant_char_domain
(
&
self
,
constant
:
Bitvector
)
->
Option
<
T
>
{
if
let
Ok
(
Some
(
char_code
))
=
self
.runtime_memory_image
.read
(
if
let
Ok
(
Some
(
char_code
))
=
self
.
project.
runtime_memory_image
.read
(
&
constant
,
self
.project
.datatype_properties
...
...
@@ -199,6 +199,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
/// Inserts a string constant into the format string.
pub
fn
get_constant_string_domain
(
&
self
,
constant
:
Bitvector
)
->
Option
<
T
>
{
if
let
Ok
(
string
)
=
self
.project
.runtime_memory_image
.read_string_until_null_terminator
(
&
constant
)
{
...
...
@@ -218,7 +219,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
if
let
Some
(
dest_arg
)
=
extern_symbol
.parameters
.first
()
{
if
let
Some
(
pi_state
)
=
state
.get_pointer_inference_state
()
{
if
let
Ok
(
pointer
)
=
pi_state
.eval_parameter_arg
(
dest_arg
,
self
.runtime_memory_image
)
pi_state
.eval_parameter_arg
(
dest_arg
,
&
self
.project
.runtime_memory_image
)
{
let
heap_to_string_map
=
state
.get_heap_to_string_map
();
for
(
target
,
_
)
in
pointer
.get_relative_values
()
.iter
()
{
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/symbol_calls/memcpy.rs
View file @
170f44b1
...
...
@@ -44,7 +44,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
)
->
Result
<
DataDomain
<
IntervalDomain
>
,
Error
>
{
if
let
Some
(
return_arg
)
=
extern_symbol
.parameters
.first
()
{
if
let
Ok
(
return_data
)
=
pi_state
.eval_parameter_arg
(
return_arg
,
self
.runtime_memory_image
)
pi_state
.eval_parameter_arg
(
return_arg
,
&
self
.project
.runtime_memory_image
)
{
if
!
return_data
.get_relative_values
()
.is_empty
()
{
return
Ok
(
return_data
);
...
...
@@ -62,7 +62,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
pi_state
:
&
PointerInferenceState
,
)
->
Result
<
DataDomain
<
IntervalDomain
>
,
Error
>
{
if
let
Some
(
input_arg
)
=
extern_symbol
.parameters
.get
(
1
)
{
return
pi_state
.eval_parameter_arg
(
input_arg
,
self
.runtime_memory_image
);
return
pi_state
.eval_parameter_arg
(
input_arg
,
&
self
.project
.runtime_memory_image
);
}
Err
(
anyhow!
(
"No input values"
))
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/symbol_calls/scanf.rs
View file @
170f44b1
...
...
@@ -25,7 +25,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
pi_state
,
extern_symbol
,
&
self
.format_string_index_map
,
self
.runtime_memory_image
,
)
{
self
.create_abstract_domain_entries_for_function_return_values
(
pi_state
,
...
...
@@ -47,7 +46,8 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
)
{
for
(
argument
,
value
)
in
arg_to_value_map
.into_iter
()
{
if
argument
.get_data_type
()
.unwrap
()
==
Datatype
::
Pointer
{
if
let
Ok
(
data
)
=
pi_state
.eval_parameter_arg
(
&
argument
,
self
.runtime_memory_image
)
if
let
Ok
(
data
)
=
pi_state
.eval_parameter_arg
(
&
argument
,
&
self
.project.runtime_memory_image
)
{
if
!
data
.get_relative_values
()
.is_empty
()
{
Context
::
add_constant_or_top_value_to_return_locations
(
...
...
@@ -91,8 +91,8 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
let
mut
new_state
=
state
.clone
();
if
let
Some
(
pi_state
)
=
state
.get_pointer_inference_state
()
{
if
let
Some
(
source_string_arg
)
=
extern_symbol
.parameters
.first
()
{
if
let
Ok
(
source_string
)
=
pi_state
.eval_parameter_arg
(
source_string_arg
,
self
.runtime_memory_image
)
if
let
Ok
(
source_string
)
=
pi_state
.eval_parameter_arg
(
source_string_arg
,
&
self
.project
.runtime_memory_image
)
{
if
self
.source_string_mapped_to_return_locations
(
pi_state
,
...
...
@@ -120,11 +120,15 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
extern_symbol
:
&
ExternSymbol
,
)
->
bool
{
if
let
Some
(
global_address
)
=
source_string
.get_absolute_value
()
{
if
let
Ok
(
source_string
)
=
self
.runtime_memory_image
.read_string_until_null_terminator
(
&
global_address
.try_to_bitvec
()
.expect
(
"Could not translate interval address to bitvector."
),
)
{
if
let
Ok
(
source_string
)
=
self
.project
.runtime_memory_image
.read_string_until_null_terminator
(
&
global_address
.try_to_bitvec
()
.expect
(
"Could not translate interval address to bitvector."
),
)
{
if
let
Ok
(
source_return_string_map
)
=
self
.map_source_string_parameters_to_return_arguments
(
pi_state
,
...
...
@@ -158,7 +162,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
pi_state
,
extern_symbol
,
&
self
.format_string_index_map
,
self
.runtime_memory_image
,
)
{
let
return_values
:
Vec
<
String
>
=
source_string
.split
(
' '
)
.map
(|
s
|
s
.to_string
())
.collect
();
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/symbol_calls/sprintf.rs
View file @
170f44b1
...
...
@@ -25,7 +25,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
if
let
Some
(
return_arg
)
=
extern_symbol
.parameters
.first
()
{
if
let
Some
(
pi_state
)
=
state
.get_pointer_inference_state
()
{
if
let
Ok
(
return_pointer
)
=
pi_state
.eval_parameter_arg
(
return_arg
,
self
.runtime_memory_image
)
pi_state
.eval_parameter_arg
(
return_arg
,
&
self
.project
.runtime_memory_image
)
{
if
!
return_pointer
.get_relative_values
()
.is_empty
()
{
let
format_string_index
=
self
...
...
@@ -63,7 +63,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
pi_state
,
extern_symbol
,
format_string_index
,
self
.runtime_memory_image
,
&
self
.project
.runtime_memory_image
,
)
{
let
returned_abstract_domain
=
self
.create_string_domain_for_sprintf_snprintf
(
pi_state
,
...
...
@@ -105,7 +105,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
pi_state
,
extern_symbol
,
&
self
.format_string_index_map
,
self
.runtime_memory_image
,
)
{
Ok
(
var_args
)
=>
{
if
var_args
.is_empty
()
{
...
...
@@ -258,7 +257,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
pi_state
:
&
PointerInferenceState
,
state
:
&
State
<
T
>
,
)
->
T
{
if
let
Ok
(
data
)
=
pi_state
.eval_parameter_arg
(
arg
,
self
.runtime_memory_image
)
{
if
let
Ok
(
data
)
=
pi_state
.eval_parameter_arg
(
arg
,
&
self
.project
.runtime_memory_image
)
{
let
constant_domain
:
Option
<
T
>
=
self
.fetch_constant_domain_if_available
(
&
data
,
arg
);
if
let
Some
(
generated_domain
)
=
Context
::
<
T
>
::
fetch_subdomains_if_available
(
&
data
,
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/symbol_calls/strcat.rs
View file @
170f44b1
...
...
@@ -17,7 +17,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
if
let
Some
(
pi_state
)
=
state
.get_pointer_inference_state
()
{
if
let
Some
(
return_arg
)
=
extern_symbol
.parameters
.first
()
{
if
let
Ok
(
return_pointer
)
=
pi_state
.eval_parameter_arg
(
return_arg
,
self
.runtime_memory_image
)
pi_state
.eval_parameter_arg
(
return_arg
,
&
self
.project
.runtime_memory_image
)
{
if
!
return_pointer
.get_relative_values
()
.is_empty
()
{
let
target_domain
=
...
...
@@ -64,7 +64,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
let
mut
input_domain
=
T
::
create_top_value_domain
();
if
let
Some
(
input_arg
)
=
extern_symbol
.parameters
.get
(
1
)
{
if
let
Ok
(
input_value
)
=
pi_state
.eval_parameter_arg
(
input_arg
,
self
.runtime_memory_image
)
pi_state
.eval_parameter_arg
(
input_arg
,
&
self
.project
.runtime_memory_image
)
{
// Check whether the second input string is in read only memory or on stack/heap.
if
!
input_value
.get_relative_values
()
.is_empty
()
{
...
...
@@ -78,6 +78,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
if
let
Some
(
value
)
=
input_value
.get_absolute_value
()
{
if
let
Ok
(
global_address
)
=
value
.try_to_bitvec
()
{
if
let
Ok
(
input_string
)
=
self
.project
.runtime_memory_image
.read_string_until_null_terminator
(
&
global_address
)
{
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/symbol_calls/tests.rs
View file @
170f44b1
...
...
@@ -61,7 +61,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String> + Debu
mock_string_symbol_map
(
&
pi_context
.project
),
mock_format_index_map
(),
&
pi_results
,
&
pi_context
.runtime_memory_image
,
);
let
state_before_call
:
State
<
T
>
=
State
::
mock_with_given_pi_state
(
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/tests.rs
View file @
170f44b1
...
...
@@ -6,7 +6,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
string_symbols
:
HashMap
<
Tid
,
&
'a
ExternSymbol
>
,
format_string_index
:
HashMap
<
String
,
usize
>
,
pointer_inference_results
:
&
'a
PointerInferenceComputation
<
'a
>
,
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
)
->
Self
{
let
mut
extern_symbol_map
=
HashMap
::
new
();
for
(
tid
,
symbol
)
in
project
.program.term.extern_symbols
.iter
()
{
...
...
@@ -35,7 +34,6 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>> Conte
Context
{
project
,
runtime_memory_image
,
pointer_inference_results
,
string_symbol_map
:
string_symbols
,
extern_symbol_map
,
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/trait_impls.rs
View file @
170f44b1
...
...
@@ -46,7 +46,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
new_state
.handle_assign_and_load
(
output
,
input
,
self
.runtime_memory_image
,
&
self
.project
.runtime_memory_image
,
&
self
.block_first_def_set
,
true
,
);
...
...
@@ -58,7 +58,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
new_state
.handle_assign_and_load
(
output
,
input
,
self
.runtime_memory_image
,
&
self
.project
.runtime_memory_image
,
&
self
.block_first_def_set
,
false
,
);
...
...
@@ -66,7 +66,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
Def
::
Store
{
address
,
value
}
=>
new_state
.handle_store
(
address
,
value
,
self
.runtime_memory_image
,
&
self
.project
.runtime_memory_image
,
&
self
.block_first_def_set
,
),
}
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/trait_impls/tests.rs
View file @
170f44b1
...
...
@@ -13,7 +13,6 @@ use crate::{
},
},
intermediate_representation
::{
Bitvector
,
Blk
,
ByteSize
,
ExternSymbol
,
Jmp
,
Tid
,
Variable
},
utils
::
binary
::
RuntimeMemoryImage
,
};
#[test]
...
...
@@ -23,7 +22,6 @@ fn test_update_def() {
vec!
[(
memcpy_symbol
.clone
(),
vec!
[
true
])],
"func"
,
);
let
mem_image
=
RuntimeMemoryImage
::
mock
();
let
mut
pi_results
=
PointerInferenceComputation
::
mock
(
&
project
);
pi_results
.compute
(
false
);
...
...
@@ -62,7 +60,7 @@ fn test_update_def() {
let
_
=
setup
.pi_state_before_symbol_call
.store_value
(
&
pointer_to_pointer
,
&
loaded_pointer
,
&
mem
_image
,
&
project
.runtime_memory
_image
,
);
let
r2_reg
=
Variable
{
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/mod.rs
View file @
170f44b1
...
...
@@ -10,7 +10,6 @@ use crate::{
abstract_domain
::{
AbstractDomain
,
DomainInsertion
,
HasTop
},
intermediate_representation
::
Project
,
prelude
::
*
,
utils
::
binary
::
RuntimeMemoryImage
,
};
use
self
::
state
::
State
;
...
...
@@ -49,17 +48,11 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
/// Generate a new string abstraction computation for a project.
pub
fn
new
(
project
:
&
'a
Project
,
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
control_flow_graph
:
&
'a
Graph
<
'a
>
,
pointer_inference_results
:
&
'a
PointerInferenceComputation
<
'a
>
,
config
:
Config
,
)
->
StringAbstraction
<
'a
,
T
>
{
let
context
=
Context
::
new
(
project
,
runtime_memory_image
,
pointer_inference_results
,
config
,
);
let
context
=
Context
::
new
(
project
,
pointer_inference_results
,
config
);
let
mut
sub_to_entry_blocks_map
=
HashMap
::
new
();
for
sub
in
project
.program.term.subs
.values
()
{
...
...
@@ -132,18 +125,12 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
/// Compute the string abstraction and return its results.
pub
fn
run
<
'a
,
T
:
AbstractDomain
+
HasTop
+
Eq
+
From
<
String
>
+
DomainInsertion
>
(
project
:
&
'a
Project
,
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
control_flow_graph
:
&
'a
Graph
<
'a
>
,
pointer_inference
:
&
'a
PointerInferenceComputation
<
'a
>
,
config
:
Config
,
)
->
StringAbstraction
<
'a
,
T
>
{
let
mut
string_abstraction
=
StringAbstraction
::
new
(
project
,
runtime_memory_image
,
control_flow_graph
,
pointer_inference
,
config
,
);
let
mut
string_abstraction
=
StringAbstraction
::
new
(
project
,
control_flow_graph
,
pointer_inference
,
config
);
string_abstraction
.compute
();
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/state/mod.rs
View file @
170f44b1
...
...
@@ -9,14 +9,13 @@ use itertools::Itertools;
use
petgraph
::
graph
::
NodeIndex
;
use
crate
::
abstract_domain
::{
DataDomain
,
DomainInsertion
,
HasTop
,
TryToBitvec
};
use
crate
::
intermediate_representation
::{
ExternSymbol
,
Project
};
use
crate
::
intermediate_representation
::{
ExternSymbol
,
Project
,
RuntimeMemoryImage
};
use
crate
::{
abstract_domain
::
IntervalDomain
,
prelude
::
*
};
use
crate
::{
abstract_domain
::{
AbstractDomain
,
AbstractIdentifier
},
analysis
::
pointer_inference
::
PointerInference
as
PointerInferenceComputation
,
analysis
::
pointer_inference
::
State
as
PointerInferenceState
,
intermediate_representation
::{
Expression
,
Sub
,
Variable
},
utils
::
binary
::
RuntimeMemoryImage
,
};
/// Contains all information known about the state of a program at a specific point of time.
...
...
src/cwe_checker_lib/src/checkers/cwe_134.rs
View file @
170f44b1
...
...
@@ -31,8 +31,8 @@ use crate::analysis::interprocedural_fixpoint_generic::NodeValue;
use
crate
::
analysis
::
pointer_inference
::
PointerInference
;
use
crate
::
intermediate_representation
::
ExternSymbol
;
use
crate
::
intermediate_representation
::
Jmp
;
use
crate
::
intermediate_representation
::
RuntimeMemoryImage
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
crate
::
utils
::
log
::
CweWarning
;
use
crate
::
utils
::
log
::
LogMessage
;
use
crate
::
CweModule
;
...
...
@@ -91,7 +91,7 @@ pub fn check_cwe(
symbol
,
&
format_string_index
,
pointer_inference_results
,
analysis_results
.runtime_memory_image
,
&
analysis_results
.project
.runtime_memory_image
,
);
if
matches!
(
...
...
@@ -219,7 +219,6 @@ pub mod tests {
#[test]
fn
test_locate_format_string
()
{
let
sprintf_symbol
=
ExternSymbol
::
mock_string
();
let
runtime_memory_image
=
RuntimeMemoryImage
::
mock
();
let
project
=
mock_project
();
let
graph
=
crate
::
analysis
::
graph
::
get_program_cfg
(
&
project
.program
,
HashSet
::
new
());
let
mut
pi_results
=
PointerInferenceComputation
::
mock
(
&
project
);
...
...
@@ -241,7 +240,7 @@ pub mod tests {
&
sprintf_symbol
,
&
format_string_index
,
&
pi_results
,
&
runtime_memory_image
,
&
project
.
runtime_memory_image
,
),
StringLocation
::
GlobalReadable
);
...
...
src/cwe_checker_lib/src/checkers/cwe_467.rs
View file @
170f44b1
...
...
@@ -24,7 +24,6 @@ use crate::abstract_domain::TryToBitvec;
use
crate
::
analysis
::
pointer_inference
::
State
;
use
crate
::
intermediate_representation
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
crate
::
utils
::
log
::{
CweWarning
,
LogMessage
};
use
crate
::
utils
::
symbol_utils
::{
get_callsites
,
get_symbol_map
};
use
crate
::
CweModule
;
...
...
@@ -45,24 +44,20 @@ pub struct Config {
/// Compute the program state at the end of the given basic block
/// assuming nothing is known about the state at the start of the block.
fn
compute_block_end_state
(
project
:
&
Project
,
global_memory
:
&
RuntimeMemoryImage
,
block
:
&
Term
<
Blk
>
,
)
->
State
{
fn
compute_block_end_state
(
project
:
&
Project
,
block
:
&
Term
<
Blk
>
)
->
State
{
let
stack_register
=
&
project
.stack_pointer_register
;
let
mut
state
=
State
::
new
(
stack_register
,
block
.tid
.clone
());
for
def
in
block
.term.defs
.iter
()
{
match
&
def
.term
{
Def
::
Store
{
address
,
value
}
=>
{
let
_
=
state
.handle_store
(
address
,
value
,
global_memory
);
let
_
=
state
.handle_store
(
address
,
value
,
&
project
.runtime_memory_image
);
}
Def
::
Assign
{
var
,
value
}
=>
{
let
_
=
state
.handle_register_assign
(
var
,
value
);
}
Def
::
Load
{
var
,
address
}
=>
{
let
_
=
state
.handle_load
(
var
,
address
,
global_memory
);
let
_
=
state
.handle_load
(
var
,
address
,
&
project
.runtime_memory_image
);
}
}
}
...
...
@@ -72,14 +67,13 @@ fn compute_block_end_state(
/// Check whether a parameter value of the call to `symbol` has value `sizeof(void*)`.
fn
check_for_pointer_sized_arg
(
project
:
&
Project
,
global_memory
:
&
RuntimeMemoryImage
,
block
:
&
Term
<
Blk
>
,
symbol
:
&
ExternSymbol
,
)
->
bool
{
let
pointer_size
=
project
.stack_pointer_register.size
;
let
state
=
compute_block_end_state
(
project
,
global_memory
,
block
);
let
state
=
compute_block_end_state
(
project
,
block
);
for
parameter
in
symbol
.parameters
.iter
()
{
if
let
Ok
(
param
)
=
state
.eval_parameter_arg
(
parameter
,
global_memory
)
{
if
let
Ok
(
param
)
=
state
.eval_parameter_arg
(
parameter
,
&
project
.runtime_memory_image
)
{
if
let
Ok
(
param_value
)
=
param
.try_to_bitvec
()
{
if
Ok
(
u64
::
from
(
pointer_size
))
==
param_value
.try_to_u64
()
{
return
true
;
...
...
@@ -120,12 +114,7 @@ pub fn check_cwe(
let
symbol_map
=
get_symbol_map
(
project
,
&
config
.symbols
);
for
sub
in
project
.program.term.subs
.values
()
{
for
(
block
,
jmp
,
symbol
)
in
get_callsites
(
sub
,
&
symbol_map
)
{
if
check_for_pointer_sized_arg
(
project
,
analysis_results
.runtime_memory_image
,
block
,
symbol
,
)
{
if
check_for_pointer_sized_arg
(
project
,
block
,
symbol
)
{
cwe_warnings
.push
(
generate_cwe_warning
(
jmp
,
symbol
))
}
}
...
...
src/cwe_checker_lib/src/checkers/cwe_476.rs
View file @
170f44b1
...
...
@@ -85,12 +85,7 @@ pub fn check_cwe(
let
config
:
Config
=
serde_json
::
from_value
(
cwe_params
.clone
())
.unwrap
();
let
symbol_map
=
crate
::
utils
::
symbol_utils
::
get_symbol_map
(
project
,
&
config
.symbols
[
..
]);
let
general_context
=
Context
::
new
(
project
,
analysis_results
.runtime_memory_image
,
pointer_inference_results
,
cwe_sender
,
);
let
general_context
=
Context
::
new
(
project
,
pointer_inference_results
,
cwe_sender
);
for
edge
in
general_context
.get_graph
()
.edge_references
()
{
if
let
Edge
::
ExternCallStub
(
jmp
)
=
edge
.weight
()
{
...
...
src/cwe_checker_lib/src/checkers/cwe_476/context.rs
View file @
170f44b1
...
...
@@ -8,7 +8,6 @@ use crate::analysis::interprocedural_fixpoint_generic::NodeValue;
use
crate
::
analysis
::
pointer_inference
::
PointerInference
as
PointerInferenceComputation
;
use
crate
::
analysis
::
pointer_inference
::
State
as
PointerInferenceState
;
use
crate
::
intermediate_representation
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
crate
::
utils
::
log
::
CweWarning
;
use
petgraph
::
graph
::
NodeIndex
;
use
petgraph
::
visit
::
IntoNodeReferences
;
...
...
@@ -26,8 +25,6 @@ use std::sync::Arc;
pub
struct
Context
<
'a
>
{
/// A pointer to the corresponding project struct.
project
:
&
'a
Project
,
/// A pointer to the representation of the runtime memory image.
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
/// A pointer to the results of the pointer inference analysis.
/// They are used to determine the targets of pointers to memory,
/// which in turn is used to keep track of taint on the stack or on the heap.
...
...
@@ -64,7 +61,6 @@ impl<'a> Context<'a> {
/// since this function can be expensive!
pub
fn
new
(
project
:
&
'a
Project
,
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
pointer_inference_results
:
&
'a
PointerInferenceComputation
<
'a
>
,
cwe_collector
:
crossbeam_channel
::
Sender
<
CweWarning
>
,
)
->
Self
{
...
...
@@ -92,7 +88,6 @@ impl<'a> Context<'a> {
}
Context
{
project
,
runtime_memory_image
,
pointer_inference_results
,
block_start_node_map
:
Arc
::
new
(
block_start_node_map
),
extern_symbol_map
:
Arc
::
new
(
extern_symbol_map
),
...
...
@@ -203,8 +198,8 @@ impl<'a> Context<'a> {
{
return
true
;
}
if
let
Ok
(
stack_param
)
=
pi_state
.eval_parameter_arg
(
parameter
,
self
.runtime_memory_image
)
if
let
Ok
(
stack_param
)
=
pi_state
.eval_parameter_arg
(
parameter
,
&
self
.project
.runtime_memory_image
)
{
if
state
.check_if_address_points_to_taint
(
stack_param
,
pi_state
)
{
return
true
;
...
...
@@ -417,16 +412,14 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
#[cfg(test)]
mod
tests
{
use
super
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
impl
<
'a
>
Context
<
'a
>
{
pub
fn
mock
(
project
:
&
'a
Project
,
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
pi_results
:
&
'a
PointerInferenceComputation
<
'a
>
,
)
->
Context
<
'a
>
{
let
(
cwe_sender
,
_
)
=
crossbeam_channel
::
unbounded
();
let
mut
context
=
Context
::
new
(
project
,
runtime_memory_image
,
pi_results
,
cwe_sender
);
let
mut
context
=
Context
::
new
(
project
,
pi_results
,
cwe_sender
);
let
taint_source
=
Box
::
new
(
Term
{
tid
:
Tid
::
new
(
"taint_source"
),
term
:
Jmp
::
Call
{
...
...
@@ -445,9 +438,8 @@ mod tests {
#[test]
fn
check_parameter_arg_for_taint
()
{
let
project
=
Project
::
mock_x64
();
let
runtime_memory_image
=
RuntimeMemoryImage
::
mock
();
let
pi_results
=
PointerInferenceComputation
::
mock
(
&
project
);
let
context
=
Context
::
mock
(
&
project
,
&
runtime_memory_image
,
&
pi_results
);
let
context
=
Context
::
mock
(
&
project
,
&
pi_results
);
let
(
mut
state
,
_pi_state
)
=
State
::
mock_with_pi_state
();
assert_eq!
(
...
...
@@ -476,9 +468,8 @@ mod tests {
#[test]
fn
handle_generic_call
()
{
let
project
=
Project
::
mock_x64
();
let
runtime_memory_image
=
RuntimeMemoryImage
::
mock
();
let
pi_results
=
PointerInferenceComputation
::
mock
(
&
project
);
let
context
=
Context
::
mock
(
&
project
,
&
runtime_memory_image
,
&
pi_results
);
let
context
=
Context
::
mock
(
&
project
,
&
pi_results
);
let
mut
state
=
State
::
mock
();
assert
!
(
context
...
...
@@ -497,9 +488,8 @@ mod tests {
#[test]
fn
update_def
()
{
let
project
=
Project
::
mock_x64
();
let
runtime_memory_image
=
RuntimeMemoryImage
::
mock
();
let
pi_results
=
PointerInferenceComputation
::
mock
(
&
project
);
let
context
=
Context
::
mock
(
&
project
,
&
runtime_memory_image
,
&
pi_results
);
let
context
=
Context
::
mock
(
&
project
,
&
pi_results
);
let
(
mut
state
,
pi_state
)
=
State
::
mock_with_pi_state
();
state
.set_pointer_inference_state
(
Some
(
pi_state
));
...
...
@@ -550,9 +540,8 @@ mod tests {
#[test]
fn
update_jump
()
{
let
project
=
Project
::
mock_x64
();
let
runtime_memory_image
=
RuntimeMemoryImage
::
mock
();
let
pi_results
=
PointerInferenceComputation
::
mock
(
&
project
);
let
context
=
Context
::
mock
(
&
project
,
&
runtime_memory_image
,
&
pi_results
);
let
context
=
Context
::
mock
(
&
project
,
&
pi_results
);
let
(
state
,
_pi_state
)
=
State
::
mock_with_pi_state
();
let
jump
=
Term
{
...
...
src/cwe_checker_lib/src/checkers/cwe_560.rs
View file @
170f44b1
...
...
@@ -26,7 +26,6 @@ use crate::abstract_domain::TryToBitvec;
use
crate
::
analysis
::
pointer_inference
::
State
;
use
crate
::
intermediate_representation
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
crate
::
utils
::
log
::{
CweWarning
,
LogMessage
};
use
crate
::
utils
::
symbol_utils
::{
get_callsites
,
get_symbol_map
};
use
crate
::
CweModule
;
...
...
@@ -50,7 +49,6 @@ fn get_umask_permission_arg(
block
:
&
Term
<
Blk
>
,
umask_symbol
:
&
ExternSymbol
,
project
:
&
Project
,
global_memory
:
&
RuntimeMemoryImage
,
)
->
Result
<
u64
,
Error
>
{
let
stack_register
=
&
project
.stack_pointer_register
;
let
mut
state
=
State
::
new
(
stack_register
,
block
.tid
.clone
());
...
...
@@ -58,19 +56,19 @@ fn get_umask_permission_arg(
for
def
in
block
.term.defs
.iter
()
{
match
&
def
.term
{
Def
::
Store
{
address
,
value
}
=>
{
let
_
=
state
.handle_store
(
address
,
value
,
global_memory
);
let
_
=
state
.handle_store
(
address
,
value
,
&
project
.runtime_memory_image
);
}
Def
::
Assign
{
var
,
value
}
=>
{
let
_
=
state
.handle_register_assign
(
var
,
value
);
}
Def
::
Load
{
var
,
address
}
=>
{
let
_
=
state
.handle_load
(
var
,
address
,
global_memory
);
let
_
=
state
.handle_load
(
var
,
address
,
&
project
.runtime_memory_image
);
}
}
}
let
parameter
=
umask_symbol
.get_unique_parameter
()
?
;
let
param_value
=
state
.eval_parameter_arg
(
parameter
,
global_memory
)
?
;
let
param_value
=
state
.eval_parameter_arg
(
parameter
,
&
project
.runtime_memory_image
)
?
;
if
let
Ok
(
umask_arg
)
=
param_value
.try_to_bitvec
()
{
Ok
(
umask_arg
.try_to_u64
()
?
)
}
else
{
...
...
@@ -115,12 +113,7 @@ pub fn check_cwe(
if
!
umask_symbol_map
.is_empty
()
{
for
sub
in
project
.program.term.subs
.values
()
{
for
(
block
,
jmp
,
umask_symbol
)
in
get_callsites
(
sub
,
&
umask_symbol_map
)
{
match
get_umask_permission_arg
(
block
,
umask_symbol
,
project
,
analysis_results
.runtime_memory_image
,
)
{
match
get_umask_permission_arg
(
block
,
umask_symbol
,
project
)
{
Ok
(
permission_const
)
=>
{
if
is_chmod_style_arg
(
permission_const
)
{
cwes
.push
(
generate_cwe_warning
(
sub
,
jmp
,
permission_const
));
...
...
src/cwe_checker_lib/src/checkers/cwe_78.rs
View file @
170f44b1
...
...
@@ -45,9 +45,9 @@ use crate::intermediate_representation::Arg;
use
crate
::
intermediate_representation
::
Expression
;
use
crate
::
intermediate_representation
::
ExternSymbol
;
use
crate
::
intermediate_representation
::
Jmp
;
use
crate
::
intermediate_representation
::
RuntimeMemoryImage
;
use
crate
::
intermediate_representation
::
Sub
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
binary
::
RuntimeMemoryImage
;
use
crate
::
utils
::
log
::
CweWarning
;
use
crate
::
utils
::
log
::
LogMessage
;
...
...
@@ -117,7 +117,10 @@ pub fn check_cwe(
&
jmp
.tid
,
&
cwe_sender
,
&
log_sender
,
string_abstraction
.get_context
()
.runtime_memory_image
,
&
string_abstraction
.get_context
()
.project
.runtime_memory_image
,
)
}
}
...
...
src/cwe_checker_lib/src/intermediate_representation/mod.rs
View file @
170f44b1
...
...
@@ -30,6 +30,8 @@ mod program;
pub
use
program
::
*
;
mod
project
;
pub
use
project
::
*
;
mod
runtime_memory_image
;
pub
use
runtime_memory_image
::
*
;
/// An unsigned number of bytes.
///
...
...
src/cwe_checker_lib/src/intermediate_representation/project.rs
View file @
170f44b1
use
super
::
*
;
use
crate
::
utils
::
log
::
LogMessage
;
use
std
::
collections
::{
BTreeMap
,
BTreeSet
,
HashMap
,
HashSet
};
mod
block_duplication_normalization
;
use
crate
::
utils
::
log
::
LogMessage
;
use
block_duplication_normalization
::
*
;
/// The `Project` struct is the main data structure representing a binary.
...
...
@@ -24,6 +23,8 @@ pub struct Project {
pub
register_set
:
BTreeSet
<
Variable
>
,
/// Contains the properties of C data types. (e.g. size)
pub
datatype_properties
:
DatatypeProperties
,
/// Represents the memory after loading the binary.
pub
runtime_memory_image
:
RuntimeMemoryImage
,
}
impl
Project
{
...
...
@@ -319,6 +320,7 @@ mod tests {
calling_conventions
,
register_set
:
integer_register
.iter
()
.cloned
()
.collect
(),
datatype_properties
:
DatatypeProperties
::
mock_x64
(),
runtime_memory_image
:
RuntimeMemoryImage
::
mock
(),
}
}
...
...
@@ -357,6 +359,7 @@ mod tests {
)]),
register_set
:
integer_register
.collect
(),
datatype_properties
:
DatatypeProperties
::
mock_arm32
(),
runtime_memory_image
:
RuntimeMemoryImage
::
mock
(),
}
}
}
...
...
src/cwe_checker_lib/src/intermediate_representation/runtime_memory_image.rs
0 → 100644
View file @
170f44b1
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/lib.rs
View file @
170f44b1
...
...
@@ -74,8 +74,8 @@ use analysis::function_signature::FunctionSignature;
use
analysis
::
graph
::
Graph
;
use
analysis
::
pointer_inference
::
PointerInference
;
use
analysis
::
string_abstraction
::
StringAbstraction
;
use
intermediate_representation
::
Project
;
use
utils
::
binary
::
RuntimeMemoryImage
;
use
utils
::
log
::{
CweWarning
,
LogMessage
};
mod
prelude
{
...
...
@@ -140,8 +140,6 @@ pub fn get_modules() -> Vec<&'static CweModule> {
pub
struct
AnalysisResults
<
'a
>
{
/// The content of the binary file
pub
binary
:
&
'a
[
u8
],
/// A representation of the runtime memory image of the binary.
pub
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
/// The computed control flow graph of the program.
pub
control_flow_graph
:
&
'a
Graph
<
'a
>
,
/// A pointer to the project struct
...
...
@@ -158,13 +156,11 @@ impl<'a> AnalysisResults<'a> {
/// Create a new `AnalysisResults` struct with only the project itself known.
pub
fn
new
(
binary
:
&
'a
[
u8
],
runtime_memory_image
:
&
'a
RuntimeMemoryImage
,
control_flow_graph
:
&
'a
Graph
<
'a
>
,
project
:
&
'a
Project
,
)
->
AnalysisResults
<
'a
>
{
AnalysisResults
{
binary
,
runtime_memory_image
,
control_flow_graph
,
project
,
function_signatures
:
None
,
...
...
@@ -231,7 +227,6 @@ impl<'a> AnalysisResults<'a> {
)
->
StringAbstraction
<
BricksDomain
>
{
crate
::
analysis
::
string_abstraction
::
run
(
self
.project
,
self
.runtime_memory_image
,
self
.control_flow_graph
,
pi_results
.unwrap
(),
serde_json
::
from_value
(
config
.clone
())
.unwrap
(),
...
...
@@ -264,11 +259,8 @@ mod tests {
HashSet
::
from_iter
(
project
.program.term.extern_symbols
.keys
()
.cloned
());
let
graph
=
Box
::
new
(
get_program_cfg
(
&
project
.program
,
extern_subs
));
let
graph
:
&
'a
Graph
=
Box
::
leak
(
graph
);
let
runtime_mem_image
=
Box
::
new
(
RuntimeMemoryImage
::
mock
());
let
runtime_mem_image
:
&
'a
RuntimeMemoryImage
=
Box
::
leak
(
runtime_mem_image
);
let
binary
:
&
'a
Vec
<
u8
>
=
Box
::
leak
(
Box
::
new
(
Vec
::
new
()));
let
analysis_results
=
AnalysisResults
::
new
(
binary
,
runtime_mem_image
,
graph
,
project
);
let
analysis_results
=
AnalysisResults
::
new
(
binary
,
graph
,
project
);
let
(
fn_sigs
,
_
)
=
analysis_results
.compute_function_signatures
();
let
fn_sigs
:
&
'a
BTreeMap
<
_
,
_
>
=
Box
::
leak
(
Box
::
new
(
fn_sigs
));
let
analysis_results
=
analysis_results
.with_function_signatures
(
Some
(
fn_sigs
));
...
...
src/cwe_checker_lib/src/pcode/term.rs
View file @
170f44b1
...
...
@@ -13,6 +13,7 @@ use crate::intermediate_representation::ExternSymbol as IrExternSymbol;
use
crate
::
intermediate_representation
::
Jmp
as
IrJmp
;
use
crate
::
intermediate_representation
::
Program
as
IrProgram
;
use
crate
::
intermediate_representation
::
Project
as
IrProject
;
use
crate
::
intermediate_representation
::
RuntimeMemoryImage
;
use
crate
::
intermediate_representation
::
Sub
as
IrSub
;
use
crate
::
intermediate_representation
::
Variable
as
IrVariable
;
use
crate
::
prelude
::
*
;
...
...
@@ -870,6 +871,7 @@ impl Project {
calling_conventions
,
register_set
,
datatype_properties
:
self
.datatype_properties
.clone
(),
runtime_memory_image
:
RuntimeMemoryImage
::
empty
(
true
),
}
}
}
...
...
src/cwe_checker_lib/src/utils/arguments.rs
View file @
170f44b1
//! Handles argument detection by parsing format string arguments during a function call. (e.g. sprintf)
use
super
::
binary
::
RuntimeMemoryImage
;
use
crate
::
prelude
::
*
;
use
crate
::{
abstract_domain
::{
IntervalDomain
,
TryToBitvec
},
...
...
@@ -105,7 +104,6 @@ pub fn get_variable_parameters(
pi_state
:
&
PointerInferenceState
,
extern_symbol
:
&
ExternSymbol
,
format_string_index_map
:
&
HashMap
<
String
,
usize
>
,
runtime_memory_image
:
&
RuntimeMemoryImage
,
)
->
Result
<
Vec
<
Arg
>
,
Error
>
{
let
format_string_index
=
match
format_string_index_map
.get
(
&
extern_symbol
.name
)
{
Some
(
index
)
=>
*
index
,
...
...
@@ -116,7 +114,7 @@ pub fn get_variable_parameters(
pi_state
,
extern_symbol
,
format_string_index
,
runtime_memory_image
,
&
project
.
runtime_memory_image
,
);
if
let
Ok
(
format_string
)
=
format_string_results
.as_ref
()
{
...
...
src/cwe_checker_lib/src/utils/arguments/tests.rs
View file @
170f44b1
...
...
@@ -9,7 +9,6 @@ fn mock_pi_state() -> PointerInferenceState {
#[test]
/// Tests extraction of format string parameters '/dev/sd%c%d' and 'cat %s'.
fn
test_get_variable_parameters
()
{
let
mem_image
=
RuntimeMemoryImage
::
mock
();
let
mut
pi_state
=
mock_pi_state
();
let
sprintf_symbol
=
ExternSymbol
::
mock_string
();
let
mut
format_string_index_map
:
HashMap
<
String
,
usize
>
=
HashMap
::
new
();
...
...
@@ -38,7 +37,6 @@ fn test_get_variable_parameters() {
&
pi_state
,
&
sprintf_symbol
,
&
format_string_index_map
,
&
mem_image
,
)
.unwrap
()
);
...
...
@@ -61,7 +59,6 @@ fn test_get_variable_parameters() {
&
pi_state
,
&
sprintf_symbol
,
&
format_string_index_map
,
&
mem_image
,
)
.unwrap
()
);
...
...
src/cwe_checker_lib/src/utils/binary.rs
View file @
170f44b1
This diff is collapsed.
Click to expand it.
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