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
933a929c
Unverified
Commit
933a929c
authored
Dec 21, 2021
by
James Shaker
Committed by
GitHub
Dec 21, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed issue #250 by using correct calling convention. (#269)
parent
74976f0d
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
88 additions
and
12 deletions
+88
-12
Makefile
Makefile
+1
-1
tests.rs
...b/src/analysis/backward_interprocedural_fixpoint/tests.rs
+2
-0
mod.rs
...checker_lib/src/analysis/dead_variable_elimination/mod.rs
+1
-0
forward_interprocedural_fixpoint.rs
...cker_lib/src/analysis/forward_interprocedural_fixpoint.rs
+12
-4
context.rs
...we_checker_lib/src/analysis/function_signature/context.rs
+2
-0
graph.rs
src/cwe_checker_lib/src/analysis/graph.rs
+3
-0
tests.rs
...ecker_lib/src/analysis/pointer_inference/context/tests.rs
+6
-1
trait_impls.rs
...lib/src/analysis/pointer_inference/context/trait_impls.rs
+10
-2
trait_impls.rs
...ib/src/analysis/string_abstraction/context/trait_impls.rs
+2
-0
tests.rs
.../analysis/string_abstraction/context/trait_impls/tests.rs
+2
-0
context.rs
src/cwe_checker_lib/src/checkers/cwe_476/context.rs
+8
-1
project.rs
...we_checker_lib/src/intermediate_representation/project.rs
+14
-0
block_duplication_normalization.rs
...representation/project/block_duplication_normalization.rs
+1
-0
sub.rs
src/cwe_checker_lib/src/intermediate_representation/sub.rs
+3
-0
term.rs
src/cwe_checker_lib/src/pcode/term.rs
+4
-0
TermCreator.java
src/ghidra/p_code_extractor/internal/TermCreator.java
+5
-1
Sub.java
src/ghidra/p_code_extractor/term/Sub.java
+10
-0
lib.rs
test/src/lib.rs
+2
-2
No files found.
Makefile
View file @
933a929c
...
@@ -21,7 +21,7 @@ test:
...
@@ -21,7 +21,7 @@ test:
echo
"Acceptance test binaries not found. Please see test/artificial_samples/Readme.md for build instructions."
;
\
echo
"Acceptance test binaries not found. Please see test/artificial_samples/Readme.md for build instructions."
;
\
exit
-1
;
\
exit
-1
;
\
fi
fi
cargo
test
--no-fail-fast
-p
acceptance_tests_ghidra
--
--show-output
--ignored
cargo
test
--no-fail-fast
-p
acceptance_tests_ghidra
--
--show-output
--ignored
--test-threads
1
compile_test_files
:
compile_test_files
:
cd test
/artificial_samples
\
cd test
/artificial_samples
\
...
...
src/cwe_checker_lib/src/analysis/backward_interprocedural_fixpoint/tests.rs
View file @
933a929c
...
@@ -89,6 +89,7 @@ fn mock_program() -> Term<Program> {
...
@@ -89,6 +89,7 @@ fn mock_program() -> Term<Program> {
term
:
Sub
{
term
:
Sub
{
name
:
"sub1"
.to_string
(),
name
:
"sub1"
.to_string
(),
blocks
:
vec!
[
sub1_blk1
,
sub1_blk2
],
blocks
:
vec!
[
sub1_blk1
,
sub1_blk2
],
calling_convention
:
None
,
},
},
};
};
let
cond_jump
=
Jmp
::
CBranch
{
let
cond_jump
=
Jmp
::
CBranch
{
...
@@ -124,6 +125,7 @@ fn mock_program() -> Term<Program> {
...
@@ -124,6 +125,7 @@ fn mock_program() -> Term<Program> {
term
:
Sub
{
term
:
Sub
{
name
:
"sub2"
.to_string
(),
name
:
"sub2"
.to_string
(),
blocks
:
vec!
[
sub2_blk1
,
sub2_blk2
],
blocks
:
vec!
[
sub2_blk1
,
sub2_blk2
],
calling_convention
:
None
,
},
},
};
};
let
program
=
Term
{
let
program
=
Term
{
...
...
src/cwe_checker_lib/src/analysis/dead_variable_elimination/mod.rs
View file @
933a929c
...
@@ -160,6 +160,7 @@ mod tests {
...
@@ -160,6 +160,7 @@ mod tests {
term
:
Sub
{
term
:
Sub
{
name
:
"sub"
.to_string
(),
name
:
"sub"
.to_string
(),
blocks
:
vec!
[
block
],
blocks
:
vec!
[
block
],
calling_convention
:
None
,
},
},
};
};
let
mut
project
=
Project
::
mock_empty
();
let
mut
project
=
Project
::
mock_empty
();
...
...
src/cwe_checker_lib/src/analysis/forward_interprocedural_fixpoint.rs
View file @
933a929c
...
@@ -57,6 +57,7 @@ pub trait Context<'a> {
...
@@ -57,6 +57,7 @@ pub trait Context<'a> {
value
:
&
Self
::
Value
,
value
:
&
Self
::
Value
,
call
:
&
Term
<
Jmp
>
,
call
:
&
Term
<
Jmp
>
,
target
:
&
Node
,
target
:
&
Node
,
calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
Self
::
Value
>
;
)
->
Option
<
Self
::
Value
>
;
/// Transition function for return instructions.
/// Transition function for return instructions.
...
@@ -68,6 +69,7 @@ pub trait Context<'a> {
...
@@ -68,6 +69,7 @@ pub trait Context<'a> {
value_before_call
:
Option
<&
Self
::
Value
>
,
value_before_call
:
Option
<&
Self
::
Value
>
,
call_term
:
&
Term
<
Jmp
>
,
call_term
:
&
Term
<
Jmp
>
,
return_term
:
&
Term
<
Jmp
>
,
return_term
:
&
Term
<
Jmp
>
,
calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
Self
::
Value
>
;
)
->
Option
<
Self
::
Value
>
;
/// Transition function for calls to functions not contained in the binary.
/// Transition function for calls to functions not contained in the binary.
...
@@ -163,7 +165,12 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
...
@@ -163,7 +165,12 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
Edge
::
CallCombine
(
_
)
=>
Some
(
Self
::
NodeValue
::
Value
(
node_value
.unwrap_value
()
.clone
())),
Edge
::
CallCombine
(
_
)
=>
Some
(
Self
::
NodeValue
::
Value
(
node_value
.unwrap_value
()
.clone
())),
Edge
::
Call
(
call
)
=>
self
Edge
::
Call
(
call
)
=>
self
.context
.context
.update_call
(
node_value
.unwrap_value
(),
call
,
&
graph
[
end_node
])
.update_call
(
node_value
.unwrap_value
(),
call
,
&
graph
[
end_node
],
&
graph
[
end_node
]
.get_sub
()
.term.calling_convention
,
)
.map
(
NodeValue
::
Value
),
.map
(
NodeValue
::
Value
),
Edge
::
CrCallStub
=>
Some
(
NodeValue
::
CallFlowCombinator
{
Edge
::
CrCallStub
=>
Some
(
NodeValue
::
CallFlowCombinator
{
call_stub
:
Some
(
node_value
.unwrap_value
()
.clone
()),
call_stub
:
Some
(
node_value
.unwrap_value
()
.clone
()),
...
@@ -179,11 +186,11 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
...
@@ -179,11 +186,11 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
call_stub
,
call_stub
,
interprocedural_flow
,
interprocedural_flow
,
}
=>
{
}
=>
{
let
return_from_block
=
match
graph
.node_weight
(
start_node
)
{
let
(
return_from_block
,
return_from_sub
)
=
match
graph
.node_weight
(
start_node
)
{
Some
(
Node
::
CallReturn
{
Some
(
Node
::
CallReturn
{
call
:
_
,
call
:
_
,
return_
:
(
return_from_block
,
_
),
return_
:
(
return_from_block
,
return_from_sub
),
})
=>
return_from_block
,
})
=>
(
return_from_block
,
return_from_sub
)
,
_
=>
panic!
(
"Malformed Control flow graph"
),
_
=>
panic!
(
"Malformed Control flow graph"
),
};
};
let
return_from_jmp
=
&
return_from_block
.term.jmps
[
0
];
let
return_from_jmp
=
&
return_from_block
.term.jmps
[
0
];
...
@@ -193,6 +200,7 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
...
@@ -193,6 +200,7 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
call_stub
.as_ref
(),
call_stub
.as_ref
(),
call_term
,
call_term
,
return_from_jmp
,
return_from_jmp
,
&
return_from_sub
.term.calling_convention
,
)
)
.map
(
NodeValue
::
Value
)
.map
(
NodeValue
::
Value
)
}
}
...
...
src/cwe_checker_lib/src/analysis/function_signature/context.rs
View file @
933a929c
...
@@ -176,6 +176,7 @@ impl<'a> forward_interprocedural_fixpoint::Context<'a> for Context<'a> {
...
@@ -176,6 +176,7 @@ impl<'a> forward_interprocedural_fixpoint::Context<'a> for Context<'a> {
_state
:
&
State
,
_state
:
&
State
,
_call
:
&
Term
<
Jmp
>
,
_call
:
&
Term
<
Jmp
>
,
_target
:
&
crate
::
analysis
::
graph
::
Node
,
_target
:
&
crate
::
analysis
::
graph
::
Node
,
_calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
>
{
)
->
Option
<
State
>
{
// No knowledge is transferred from the caller to the callee.
// No knowledge is transferred from the caller to the callee.
None
None
...
@@ -215,6 +216,7 @@ impl<'a> forward_interprocedural_fixpoint::Context<'a> for Context<'a> {
...
@@ -215,6 +216,7 @@ impl<'a> forward_interprocedural_fixpoint::Context<'a> for Context<'a> {
state_before_call
:
Option
<&
State
>
,
state_before_call
:
Option
<&
State
>
,
call_term
:
&
Term
<
Jmp
>
,
call_term
:
&
Term
<
Jmp
>
,
_return_term
:
&
Term
<
Jmp
>
,
_return_term
:
&
Term
<
Jmp
>
,
_calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
>
{
)
->
Option
<
State
>
{
if
state
.is_none
()
||
state_before_call
.is_none
()
{
if
state
.is_none
()
||
state_before_call
.is_none
()
{
return
None
;
return
None
;
...
...
src/cwe_checker_lib/src/analysis/graph.rs
View file @
933a929c
...
@@ -538,6 +538,7 @@ mod tests {
...
@@ -538,6 +538,7 @@ mod tests {
term
:
Sub
{
term
:
Sub
{
name
:
"sub1"
.to_string
(),
name
:
"sub1"
.to_string
(),
blocks
:
vec!
[
sub1_blk1
,
sub1_blk2
],
blocks
:
vec!
[
sub1_blk1
,
sub1_blk2
],
calling_convention
:
None
,
},
},
};
};
let
cond_jump
=
Jmp
::
CBranch
{
let
cond_jump
=
Jmp
::
CBranch
{
...
@@ -573,6 +574,7 @@ mod tests {
...
@@ -573,6 +574,7 @@ mod tests {
term
:
Sub
{
term
:
Sub
{
name
:
"sub2"
.to_string
(),
name
:
"sub2"
.to_string
(),
blocks
:
vec!
[
sub2_blk1
,
sub2_blk2
],
blocks
:
vec!
[
sub2_blk1
,
sub2_blk2
],
calling_convention
:
None
,
},
},
};
};
let
program
=
Term
{
let
program
=
Term
{
...
@@ -617,6 +619,7 @@ mod tests {
...
@@ -617,6 +619,7 @@ mod tests {
term
:
Sub
{
term
:
Sub
{
name
:
"sub"
.to_string
(),
name
:
"sub"
.to_string
(),
blocks
:
vec!
[
blk_term
],
blocks
:
vec!
[
blk_term
],
calling_convention
:
None
,
},
},
};
};
let
mut
program
=
Program
::
mock_empty
();
let
mut
program
=
Program
::
mock_empty
();
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/tests.rs
View file @
933a929c
...
@@ -167,11 +167,14 @@ fn context_problem_implementation() {
...
@@ -167,11 +167,14 @@ fn context_problem_implementation() {
term
:
Sub
{
term
:
Sub
{
name
:
"caller_sub"
.into
(),
name
:
"caller_sub"
.into
(),
blocks
:
vec!
[
target_block
.clone
()],
blocks
:
vec!
[
target_block
.clone
()],
calling_convention
:
None
,
},
},
};
};
let
target_node
=
crate
::
analysis
::
graph
::
Node
::
BlkStart
(
&
target_block
,
&
sub
);
let
target_node
=
crate
::
analysis
::
graph
::
Node
::
BlkStart
(
&
target_block
,
&
sub
);
let
call
=
call_term
(
"func"
);
let
call
=
call_term
(
"func"
);
let
mut
callee_state
=
context
.update_call
(
&
state
,
&
call
,
&
target_node
)
.unwrap
();
let
mut
callee_state
=
context
.update_call
(
&
state
,
&
call
,
&
target_node
,
&
None
)
.unwrap
();
assert_eq!
(
callee_state
.stack_id
,
new_id
(
"func"
,
"RSP"
));
assert_eq!
(
callee_state
.stack_id
,
new_id
(
"func"
,
"RSP"
));
assert_eq!
(
callee_state
.caller_stack_ids
.len
(),
1
);
assert_eq!
(
callee_state
.caller_stack_ids
.len
(),
1
);
assert_eq!
(
assert_eq!
(
...
@@ -208,6 +211,7 @@ fn context_problem_implementation() {
...
@@ -208,6 +211,7 @@ fn context_problem_implementation() {
Some
(
&
state
),
Some
(
&
state
),
&
call
,
&
call
,
&
return_term
(
"return_target"
),
&
return_term
(
"return_target"
),
&
None
,
)
)
.unwrap
();
.unwrap
();
assert_eq!
(
return_state
.stack_id
,
new_id
(
"main"
,
"RSP"
));
assert_eq!
(
return_state
.stack_id
,
new_id
(
"main"
,
"RSP"
));
...
@@ -354,6 +358,7 @@ fn update_return() {
...
@@ -354,6 +358,7 @@ fn update_return() {
Some
(
&
state_before_call
),
Some
(
&
state_before_call
),
&
call_term
(
"callee"
),
&
call_term
(
"callee"
),
&
return_term
(
"return_target"
),
&
return_term
(
"return_target"
),
&
None
,
)
)
.unwrap
();
.unwrap
();
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/trait_impls.rs
View file @
933a929c
...
@@ -120,6 +120,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
...
@@ -120,6 +120,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
state
:
&
State
,
state
:
&
State
,
call_term
:
&
Term
<
Jmp
>
,
call_term
:
&
Term
<
Jmp
>
,
_target_node
:
&
crate
::
analysis
::
graph
::
Node
,
_target_node
:
&
crate
::
analysis
::
graph
::
Node
,
calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
>
{
)
->
Option
<
State
>
{
if
let
Jmp
::
Call
{
if
let
Jmp
::
Call
{
target
:
ref
callee_tid
,
target
:
ref
callee_tid
,
...
@@ -143,7 +144,10 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
...
@@ -143,7 +144,10 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
// Remove callee-saved register, since the callee should not use their values anyway.
// Remove callee-saved register, since the callee should not use their values anyway.
// This should prevent recursive references to all stack frames in the call tree
// This should prevent recursive references to all stack frames in the call tree
// since the source for it, the stack frame base pointer, is callee-saved.
// since the source for it, the stack frame base pointer, is callee-saved.
if
let
Some
(
cconv
)
=
self
.project
.get_standard_calling_convention
()
{
if
let
Some
(
cconv
)
=
self
.project
.get_specific_calling_convention
(
calling_convention
)
{
// Note that this may lead to analysis errors if the function uses another calling convention.
// Note that this may lead to analysis errors if the function uses another calling convention.
callee_state
.remove_callee_saved_register
(
cconv
);
callee_state
.remove_callee_saved_register
(
cconv
);
}
}
...
@@ -209,6 +213,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
...
@@ -209,6 +213,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
state_before_call
:
Option
<&
State
>
,
state_before_call
:
Option
<&
State
>
,
call_term
:
&
Term
<
Jmp
>
,
call_term
:
&
Term
<
Jmp
>
,
return_term
:
&
Term
<
Jmp
>
,
return_term
:
&
Term
<
Jmp
>
,
calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
>
{
)
->
Option
<
State
>
{
// TODO: For the long term we may have to replace the IDs representing callers with something
// TODO: For the long term we may have to replace the IDs representing callers with something
// that identifies the edge of the call and not just the callsite.
// that identifies the edge of the call and not just the callsite.
...
@@ -280,7 +285,10 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
...
@@ -280,7 +285,10 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
state_after_return
.readd_caller_objects
(
state_before_call
);
state_after_return
.readd_caller_objects
(
state_before_call
);
if
let
Some
(
cconv
)
=
self
.project
.get_standard_calling_convention
()
{
if
let
Some
(
cconv
)
=
self
.project
.get_specific_calling_convention
(
calling_convention
)
{
// Restore information about callee-saved register from the caller state.
// Restore information about callee-saved register from the caller state.
// TODO: Implement some kind of check to ensure that the callee adheres to the given calling convention!
// TODO: Implement some kind of check to ensure that the callee adheres to the given calling convention!
// The current workaround should be reasonably exact for programs written in C,
// The current workaround should be reasonably exact for programs written in C,
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/trait_impls.rs
View file @
933a929c
...
@@ -91,6 +91,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
...
@@ -91,6 +91,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
_state
:
&
State
<
T
>
,
_state
:
&
State
<
T
>
,
_call
:
&
Term
<
Jmp
>
,
_call
:
&
Term
<
Jmp
>
,
_target
:
&
crate
::
analysis
::
graph
::
Node
,
_target
:
&
crate
::
analysis
::
graph
::
Node
,
_calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
<
T
>>
{
)
->
Option
<
State
<
T
>>
{
None
None
}
}
...
@@ -101,6 +102,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
...
@@ -101,6 +102,7 @@ impl<'a, T: AbstractDomain + DomainInsertion + HasTop + Eq + From<String>>
state_before_call
:
Option
<&
State
<
T
>>
,
state_before_call
:
Option
<&
State
<
T
>>
,
_call_term
:
&
Term
<
Jmp
>
,
_call_term
:
&
Term
<
Jmp
>
,
_return_term
:
&
Term
<
Jmp
>
,
_return_term
:
&
Term
<
Jmp
>
,
_calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
<
T
>>
{
)
->
Option
<
State
<
T
>>
{
if
let
Some
(
state
)
=
state_before_call
{
if
let
Some
(
state
)
=
state_before_call
{
let
mut
new_state
=
state
.clone
();
let
mut
new_state
=
state
.clone
();
...
...
src/cwe_checker_lib/src/analysis/string_abstraction/context/trait_impls/tests.rs
View file @
933a929c
...
@@ -189,6 +189,7 @@ fn test_update_return() {
...
@@ -189,6 +189,7 @@ fn test_update_return() {
None
,
None
,
&
Jmp
::
branch
(
"start1"
,
"end1"
),
&
Jmp
::
branch
(
"start1"
,
"end1"
),
&
Jmp
::
branch
(
"start2"
,
"end2"
),
&
Jmp
::
branch
(
"start2"
,
"end2"
),
&
None
,
);
);
assert_eq!
(
None
,
new_state
);
assert_eq!
(
None
,
new_state
);
...
@@ -200,6 +201,7 @@ fn test_update_return() {
...
@@ -200,6 +201,7 @@ fn test_update_return() {
Some
(
&
setup
.state_before_call
),
Some
(
&
setup
.state_before_call
),
&
Jmp
::
branch
(
"start1"
,
"end1"
),
&
Jmp
::
branch
(
"start1"
,
"end1"
),
&
Jmp
::
branch
(
"start2"
,
"end2"
),
&
Jmp
::
branch
(
"start2"
,
"end2"
),
&
None
,
)
)
.unwrap
();
.unwrap
();
...
...
src/cwe_checker_lib/src/checkers/cwe_476/context.rs
View file @
933a929c
...
@@ -260,7 +260,13 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
...
@@ -260,7 +260,13 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
/// Generate a CWE warning if taint may be contained in the function parameters.
/// Generate a CWE warning if taint may be contained in the function parameters.
/// Always returns `None` so that the analysis stays intraprocedural.
/// Always returns `None` so that the analysis stays intraprocedural.
fn
update_call
(
&
self
,
state
:
&
State
,
call
:
&
Term
<
Jmp
>
,
_target
:
&
Node
)
->
Option
<
Self
::
Value
>
{
fn
update_call
(
&
self
,
state
:
&
State
,
call
:
&
Term
<
Jmp
>
,
_target
:
&
Node
,
_calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
Self
::
Value
>
{
let
pi_state_option
=
self
.get_current_pointer_inference_state
(
state
,
&
call
.tid
);
let
pi_state_option
=
self
.get_current_pointer_inference_state
(
state
,
&
call
.tid
);
if
state
.check_generic_function_params_for_taint
(
self
.project
,
pi_state_option
.as_ref
())
{
if
state
.check_generic_function_params_for_taint
(
self
.project
,
pi_state_option
.as_ref
())
{
self
.generate_cwe_warning
(
&
call
.tid
);
self
.generate_cwe_warning
(
&
call
.tid
);
...
@@ -390,6 +396,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
...
@@ -390,6 +396,7 @@ impl<'a> crate::analysis::forward_interprocedural_fixpoint::Context<'a> for Cont
state_before_call
:
Option
<&
State
>
,
state_before_call
:
Option
<&
State
>
,
call_term
:
&
Term
<
Jmp
>
,
call_term
:
&
Term
<
Jmp
>
,
return_term
:
&
Term
<
Jmp
>
,
return_term
:
&
Term
<
Jmp
>
,
_calling_convention
:
&
Option
<
String
>
,
)
->
Option
<
State
>
{
)
->
Option
<
State
>
{
if
let
Some
(
state
)
=
state_before_return
{
if
let
Some
(
state
)
=
state_before_return
{
// If taint is returned, generate a CWE warning
// If taint is returned, generate a CWE warning
...
...
src/cwe_checker_lib/src/intermediate_representation/project.rs
View file @
933a929c
...
@@ -39,6 +39,19 @@ impl Project {
...
@@ -39,6 +39,19 @@ impl Project {
.or_else
(||
self
.calling_conventions
.get
(
"__cdecl"
))
.or_else
(||
self
.calling_conventions
.get
(
"__cdecl"
))
}
}
/// Try to find a specific calling convention in the list of calling conventions in the project.
/// If not given a calling convention (i.e. given `None`) then falls back to `get_standard_calling_convention`
pub
fn
get_specific_calling_convention
(
&
self
,
cconv_name_opt
:
&
Option
<
String
>
,
)
->
Option
<&
CallingConvention
>
{
if
let
Some
(
cconv_name
)
=
cconv_name_opt
{
self
.calling_conventions
.get
(
cconv_name
)
}
else
{
self
.get_standard_calling_convention
()
}
}
/// Return the calling convention associated to the given extern symbol.
/// Return the calling convention associated to the given extern symbol.
/// If the extern symbol has no annotated calling convention
/// If the extern symbol has no annotated calling convention
/// then return the standard calling convention of the project instead.
/// then return the standard calling convention of the project instead.
...
@@ -140,6 +153,7 @@ impl Project {
...
@@ -140,6 +153,7 @@ impl Project {
indirect_jmp_targets
:
Vec
::
new
(),
indirect_jmp_targets
:
Vec
::
new
(),
},
},
}],
}],
calling_convention
:
None
,
},
},
};
};
self
.program
self
.program
...
...
src/cwe_checker_lib/src/intermediate_representation/project/block_duplication_normalization.rs
View file @
933a929c
...
@@ -232,6 +232,7 @@ mod tests {
...
@@ -232,6 +232,7 @@ mod tests {
term
:
Sub
{
term
:
Sub
{
name
:
sub_name
.to_string
(),
name
:
sub_name
.to_string
(),
blocks
,
blocks
,
calling_convention
:
None
,
},
},
}
}
}
}
...
...
src/cwe_checker_lib/src/intermediate_representation/sub.rs
View file @
933a929c
...
@@ -13,6 +13,8 @@ pub struct Sub {
...
@@ -13,6 +13,8 @@ pub struct Sub {
/// The basic blocks belonging to the subroutine.
/// The basic blocks belonging to the subroutine.
/// The first block is also the entry point of the subroutine.
/// The first block is also the entry point of the subroutine.
pub
blocks
:
Vec
<
Term
<
Blk
>>
,
pub
blocks
:
Vec
<
Term
<
Blk
>>
,
/// The calling convention used to call if known
pub
calling_convention
:
Option
<
String
>
,
}
}
/// A parameter or return argument of a function.
/// A parameter or return argument of a function.
...
@@ -206,6 +208,7 @@ mod tests {
...
@@ -206,6 +208,7 @@ mod tests {
term
:
Sub
{
term
:
Sub
{
name
:
name
.to_string
(),
name
:
name
.to_string
(),
blocks
:
Vec
::
new
(),
blocks
:
Vec
::
new
(),
calling_convention
:
None
,
},
},
}
}
}
}
...
...
src/cwe_checker_lib/src/pcode/term.rs
View file @
933a929c
...
@@ -337,6 +337,9 @@ pub struct Sub {
...
@@ -337,6 +337,9 @@ pub struct Sub {
///
///
/// Note that the first block of the array may *not* be the function entry point!
/// Note that the first block of the array may *not* be the function entry point!
pub
blocks
:
Vec
<
Term
<
Blk
>>
,
pub
blocks
:
Vec
<
Term
<
Blk
>>
,
/// The calling convention used (as reported by Ghidra, i.e. this may not be correct).
pub
calling_convention
:
Option
<
String
>
,
}
}
impl
Term
<
Sub
>
{
impl
Term
<
Sub
>
{
...
@@ -376,6 +379,7 @@ impl Term<Sub> {
...
@@ -376,6 +379,7 @@ impl Term<Sub> {
term
:
IrSub
{
term
:
IrSub
{
name
:
self
.term.name
,
name
:
self
.term.name
,
blocks
,
blocks
,
calling_convention
:
self
.term.calling_convention
,
},
},
}
}
}
}
...
...
src/ghidra/p_code_extractor/internal/TermCreator.java
View file @
933a929c
...
@@ -43,7 +43,11 @@ public class TermCreator {
...
@@ -43,7 +43,11 @@ public class TermCreator {
* Creates a Sub Term with an unique TID consisting of the prefix sub and its entry address.
* Creates a Sub Term with an unique TID consisting of the prefix sub and its entry address.
*/
*/
public
static
Term
<
Sub
>
createSubTerm
(
Function
func
)
{
public
static
Term
<
Sub
>
createSubTerm
(
Function
func
)
{
return
new
Term
<
Sub
>(
HelperFunctions
.
functionEntryPoints
.
get
(
func
.
getEntryPoint
().
toString
()),
new
Sub
(
func
.
getName
(),
func
.
getBody
()));
Sub
subInTerm
=
new
Sub
(
func
.
getName
(),
func
.
getBody
());
if
(
func
.
getCallingConvention
()
!=
null
)
{
subInTerm
.
setCallingConvention
(
func
.
getCallingConvention
().
toString
());
}
return
new
Term
<
Sub
>(
HelperFunctions
.
functionEntryPoints
.
get
(
func
.
getEntryPoint
().
toString
()),
subInTerm
);
}
}
...
...
src/ghidra/p_code_extractor/term/Sub.java
View file @
933a929c
...
@@ -12,6 +12,8 @@ public class Sub {
...
@@ -12,6 +12,8 @@ public class Sub {
private
AddressSetView
addresses
;
private
AddressSetView
addresses
;
@SerializedName
(
"blocks"
)
@SerializedName
(
"blocks"
)
private
ArrayList
<
Term
<
Blk
>>
blocks
;
private
ArrayList
<
Term
<
Blk
>>
blocks
;
@SerializedName
(
"calling_convention"
)
private
String
callingConvention
;
public
Sub
()
{
public
Sub
()
{
}
}
...
@@ -54,4 +56,12 @@ public class Sub {
...
@@ -54,4 +56,12 @@ public class Sub {
public
void
setAddresses
(
AddressSetView
addresses
)
{
public
void
setAddresses
(
AddressSetView
addresses
)
{
this
.
addresses
=
addresses
;
this
.
addresses
=
addresses
;
}
}
public
String
getCallingConvention
()
{
return
this
.
callingConvention
;
}
public
void
setCallingConvention
(
String
callingConvention
)
{
this
.
callingConvention
=
callingConvention
;
}
}
}
test/src/lib.rs
View file @
933a929c
...
@@ -434,7 +434,7 @@ mod tests {
...
@@ -434,7 +434,7 @@ mod tests {
// We would need knowledge about alignment guarantees for the stack pointer at the start of main() to fix this.
// We would need knowledge about alignment guarantees for the stack pointer at the start of main() to fix this.
mark_skipped
(
&
mut
tests
,
"x86"
,
"gcc"
);
mark_skipped
(
&
mut
tests
,
"x86"
,
"gcc"
);
mark_
compiler_skipped
(
&
mut
tests
,
"mingw32-gcc"
);
// TODO: Check reason for failure!
mark_
skipped
(
&
mut
tests
,
"x86"
,
"mingw32-gcc"
);
// TODO: Check reason for failure! Probably same as above?
for
test_case
in
tests
{
for
test_case
in
tests
{
let
num_expected_occurences
=
2
;
let
num_expected_occurences
=
2
;
...
@@ -462,7 +462,7 @@ mod tests {
...
@@ -462,7 +462,7 @@ mod tests {
// We would need knowledge about alignment guarantees for the stack pointer at the start of main() to fix this.
// We would need knowledge about alignment guarantees for the stack pointer at the start of main() to fix this.
mark_skipped
(
&
mut
tests
,
"x86"
,
"gcc"
);
mark_skipped
(
&
mut
tests
,
"x86"
,
"gcc"
);
mark_
compiler_skipped
(
&
mut
tests
,
"mingw32-gcc"
);
// TODO: Check reason for failure!
mark_
skipped
(
&
mut
tests
,
"x86"
,
"mingw32-gcc"
);
// TODO: Check reason for failure! Probably same as above?
for
test_case
in
tests
{
for
test_case
in
tests
{
let
num_expected_occurences
=
1
;
let
num_expected_occurences
=
1
;
...
...
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