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
9fa65999
Unverified
Commit
9fa65999
authored
4 years ago
by
Melvin Klimke
Committed by
GitHub
4 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better parameter parsing for external Symbols (#176)
parent
275c13aa
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
121 additions
and
51 deletions
+121
-51
mod.rs
...checker_lib/src/analysis/pointer_inference/context/mod.rs
+10
-2
tests.rs
...ecker_lib/src/analysis/pointer_inference/context/tests.rs
+2
-1
state.rs
src/cwe_checker_lib/src/checkers/cwe_476/state.rs
+3
-4
mod.rs
src/cwe_checker_lib/src/checkers/cwe_78/state/mod.rs
+6
-2
term.rs
src/cwe_checker_lib/src/intermediate_representation/term.rs
+6
-3
term.rs
src/cwe_checker_lib/src/pcode/term.rs
+6
-3
tests.rs
src/cwe_checker_lib/src/pcode/term/tests.rs
+2
-1
PcodeExtractor.java
src/ghidra/p_code_extractor/PcodeExtractor.java
+0
-18
ParseCspecContent.java
src/ghidra/p_code_extractor/internal/ParseCspecContent.java
+58
-7
RegisterConvention.java
src/ghidra/p_code_extractor/internal/RegisterConvention.java
+28
-10
No files found.
src/cwe_checker_lib/src/analysis/pointer_inference/context/mod.rs
View file @
9fa65999
...
@@ -428,7 +428,11 @@ impl<'a> Context<'a> {
...
@@ -428,7 +428,11 @@ impl<'a> Context<'a> {
// We assume here that we do not know the parameters and approximate them by all possible parameter registers.
// We assume here that we do not know the parameters and approximate them by all possible parameter registers.
// This approximation is wrong if the function is known but has neither parameters nor return values.
// This approximation is wrong if the function is known but has neither parameters nor return values.
// We cannot distinguish these two cases yet.
// We cannot distinguish these two cases yet.
for
parameter_register_name
in
calling_conv
.parameter_register
.iter
()
{
for
parameter_register_name
in
calling_conv
.integer_parameter_register
.iter
()
.chain
(
calling_conv
.float_parameter_register
.iter
())
{
if
let
Some
(
register_value
)
=
state
.get_register_by_name
(
parameter_register_name
)
{
if
let
Some
(
register_value
)
=
state
.get_register_by_name
(
parameter_register_name
)
{
possible_referenced_ids
.append
(
&
mut
register_value
.referenced_ids
());
possible_referenced_ids
.append
(
&
mut
register_value
.referenced_ids
());
}
}
...
@@ -469,7 +473,11 @@ impl<'a> Context<'a> {
...
@@ -469,7 +473,11 @@ impl<'a> Context<'a> {
self
.adjust_stack_register_on_extern_call
(
state_before_call
,
&
mut
new_state
);
self
.adjust_stack_register_on_extern_call
(
state_before_call
,
&
mut
new_state
);
let
mut
possible_referenced_ids
=
BTreeSet
::
new
();
let
mut
possible_referenced_ids
=
BTreeSet
::
new
();
for
parameter_register_name
in
calling_conv
.parameter_register
.iter
()
{
for
parameter_register_name
in
calling_conv
.integer_parameter_register
.iter
()
.chain
(
calling_conv
.float_parameter_register
.iter
())
{
if
let
Some
(
register_value
)
=
if
let
Some
(
register_value
)
=
state_before_call
.get_register_by_name
(
parameter_register_name
)
state_before_call
.get_register_by_name
(
parameter_register_name
)
{
{
...
...
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/analysis/pointer_inference/context/tests.rs
View file @
9fa65999
...
@@ -84,7 +84,8 @@ fn mock_project() -> (Project, Config) {
...
@@ -84,7 +84,8 @@ fn mock_project() -> (Project, Config) {
};
};
let
cconv
=
CallingConvention
{
let
cconv
=
CallingConvention
{
name
:
"default"
.to_string
(),
name
:
"default"
.to_string
(),
parameter_register
:
vec!
[
"RDX"
.to_string
()],
integer_parameter_register
:
vec!
[
"RDX"
.to_string
()],
float_parameter_register
:
vec!
[
"XMM0"
.to_string
()],
return_register
:
vec!
[
"RDX"
.to_string
()],
return_register
:
vec!
[
"RDX"
.to_string
()],
callee_saved_register
:
vec!
[
"callee_saved_reg"
.to_string
()],
callee_saved_register
:
vec!
[
"callee_saved_reg"
.to_string
()],
};
};
...
...
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/checkers/cwe_476/state.rs
View file @
9fa65999
...
@@ -297,10 +297,9 @@ impl State {
...
@@ -297,10 +297,9 @@ impl State {
pi_state_option
:
Option
<&
PointerInferenceState
>
,
pi_state_option
:
Option
<&
PointerInferenceState
>
,
)
->
bool
{
)
->
bool
{
if
let
Some
(
calling_conv
)
=
project
.get_standard_calling_convention
()
{
if
let
Some
(
calling_conv
)
=
project
.get_standard_calling_convention
()
{
self
.check_register_list_for_taint
(
let
mut
all_parameters
=
calling_conv
.integer_parameter_register
.clone
();
&
calling_conv
.parameter_register
[
..
],
all_parameters
.append
(
&
mut
calling_conv
.float_parameter_register
.clone
());
pi_state_option
,
self
.check_register_list_for_taint
(
&
all_parameters
,
pi_state_option
)
)
}
else
{
}
else
{
// No standard calling convention found. Assume everything may be parameters or referenced by parameters.
// No standard calling convention found. Assume everything may be parameters or referenced by parameters.
!
self
.is_empty
()
!
self
.is_empty
()
...
...
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/checkers/cwe_78/state/mod.rs
View file @
9fa65999
...
@@ -385,8 +385,12 @@ impl State {
...
@@ -385,8 +385,12 @@ impl State {
/// we approximate the parameters with all parameter registers of the standard calling convention of the project.
/// we approximate the parameters with all parameter registers of the standard calling convention of the project.
pub
fn
remove_non_parameter_taints_for_generic_function
(
&
mut
self
,
project
:
&
Project
)
{
pub
fn
remove_non_parameter_taints_for_generic_function
(
&
mut
self
,
project
:
&
Project
)
{
if
let
Some
(
calling_conv
)
=
project
.get_standard_calling_convention
()
{
if
let
Some
(
calling_conv
)
=
project
.get_standard_calling_convention
()
{
let
register_names
:
HashSet
<
String
>
=
let
register_names
:
HashSet
<
String
>
=
calling_conv
calling_conv
.parameter_register
.iter
()
.cloned
()
.collect
();
.integer_parameter_register
.iter
()
.chain
(
calling_conv
.float_parameter_register
.iter
())
.cloned
()
.collect
();
let
taints
=
self
.register_taint
.clone
();
let
taints
=
self
.register_taint
.clone
();
for
(
register
,
_
)
in
taints
.iter
()
{
for
(
register
,
_
)
in
taints
.iter
()
{
if
register_names
.get
(
&
register
.name
)
.is_none
()
{
if
register_names
.get
(
&
register
.name
)
.is_none
()
{
...
...
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/intermediate_representation/term.rs
View file @
9fa65999
...
@@ -423,8 +423,10 @@ pub struct CallingConvention {
...
@@ -423,8 +423,10 @@ pub struct CallingConvention {
/// The name of the calling convention
/// The name of the calling convention
#[serde(rename
=
"calling_convention"
)]
#[serde(rename
=
"calling_convention"
)]
pub
name
:
String
,
pub
name
:
String
,
/// A list of possible parameter register
/// Possible integer parameter registers.
pub
parameter_register
:
Vec
<
String
>
,
pub
integer_parameter_register
:
Vec
<
String
>
,
/// Possible float parameter registers.
pub
float_parameter_register
:
Vec
<
String
>
,
/// A list of possible return register
/// A list of possible return register
pub
return_register
:
Vec
<
String
>
,
pub
return_register
:
Vec
<
String
>
,
/// A list of callee-saved register,
/// A list of callee-saved register,
...
@@ -616,7 +618,8 @@ mod tests {
...
@@ -616,7 +618,8 @@ mod tests {
pub
fn
mock
()
->
CallingConvention
{
pub
fn
mock
()
->
CallingConvention
{
CallingConvention
{
CallingConvention
{
name
:
"__stdcall"
.to_string
(),
// so that the mock is useable as standard calling convention in tests
name
:
"__stdcall"
.to_string
(),
// so that the mock is useable as standard calling convention in tests
parameter_register
:
vec!
[
"RDI"
.to_string
()],
integer_parameter_register
:
vec!
[
"RDI"
.to_string
()],
float_parameter_register
:
vec!
[
"XMMO"
.to_string
()],
return_register
:
vec!
[
"RAX"
.to_string
()],
return_register
:
vec!
[
"RAX"
.to_string
()],
callee_saved_register
:
vec!
[
"RBP"
.to_string
()],
callee_saved_register
:
vec!
[
"RBP"
.to_string
()],
}
}
...
...
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/pcode/term.rs
View file @
9fa65999
...
@@ -495,8 +495,10 @@ pub struct CallingConvention {
...
@@ -495,8 +495,10 @@ pub struct CallingConvention {
/// The name of the calling convention.
/// The name of the calling convention.
#[serde(rename
=
"calling_convention"
)]
#[serde(rename
=
"calling_convention"
)]
pub
name
:
String
,
pub
name
:
String
,
/// Possible parameter registers.
/// Possible integer parameter registers.
parameter_register
:
Vec
<
String
>
,
integer_parameter_register
:
Vec
<
String
>
,
/// Possible float parameter registers.
float_parameter_register
:
Vec
<
String
>
,
/// Possible return registers.
/// Possible return registers.
return_register
:
Vec
<
String
>
,
return_register
:
Vec
<
String
>
,
/// Callee-saved registers.
/// Callee-saved registers.
...
@@ -509,7 +511,8 @@ impl From<CallingConvention> for IrCallingConvention {
...
@@ -509,7 +511,8 @@ impl From<CallingConvention> for IrCallingConvention {
fn
from
(
cconv
:
CallingConvention
)
->
IrCallingConvention
{
fn
from
(
cconv
:
CallingConvention
)
->
IrCallingConvention
{
IrCallingConvention
{
IrCallingConvention
{
name
:
cconv
.name
,
name
:
cconv
.name
,
parameter_register
:
cconv
.parameter_register
,
integer_parameter_register
:
cconv
.integer_parameter_register
,
float_parameter_register
:
cconv
.float_parameter_register
,
return_register
:
cconv
.return_register
,
return_register
:
cconv
.return_register
,
callee_saved_register
:
cconv
.unaffected_register
,
callee_saved_register
:
cconv
.unaffected_register
,
}
}
...
...
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/pcode/term/tests.rs
View file @
9fa65999
...
@@ -85,7 +85,8 @@ impl Setup {
...
@@ -85,7 +85,8 @@ impl Setup {
"
register_calling_convention
": [
"
register_calling_convention
": [
{
{
"
calling_convention
": "
default
",
"
calling_convention
": "
default
",
"
parameter_register
": [],
"
integer_parameter_register
": [],
"
float_parameter_register
": [],
"
return_register
": [],
"
return_register
": [],
"
unaffected_register
": [],
"
unaffected_register
": [],
"
killed_by_call_register
": []
"
killed_by_call_register
": []
...
...
This diff is collapsed.
Click to expand it.
src/ghidra/p_code_extractor/PcodeExtractor.java
View file @
9fa65999
...
@@ -254,7 +254,6 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -254,7 +254,6 @@ public class PcodeExtractor extends GhidraScript {
try
{
try
{
HashMap
<
String
,
RegisterConvention
>
conventions
=
new
HashMap
<
String
,
RegisterConvention
>();
HashMap
<
String
,
RegisterConvention
>
conventions
=
new
HashMap
<
String
,
RegisterConvention
>();
ParseCspecContent
.
parseSpecs
(
currentProgram
,
conventions
);
ParseCspecContent
.
parseSpecs
(
currentProgram
,
conventions
);
addParameterRegister
(
conventions
);
project
.
setRegisterConvention
(
new
ArrayList
<
RegisterConvention
>(
conventions
.
values
()));
project
.
setRegisterConvention
(
new
ArrayList
<
RegisterConvention
>(
conventions
.
values
()));
}
catch
(
FileNotFoundException
e
)
{
}
catch
(
FileNotFoundException
e
)
{
System
.
out
.
println
(
e
);
System
.
out
.
println
(
e
);
...
@@ -267,23 +266,6 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -267,23 +266,6 @@ public class PcodeExtractor extends GhidraScript {
/**
/**
* Adds parameter register to the RegisterCallingConvention object
*/
protected
void
addParameterRegister
(
HashMap
<
String
,
RegisterConvention
>
conventions
)
{
PrototypeModel
[]
models
=
currentProgram
.
getCompilerSpec
().
getCallingConventions
();
for
(
PrototypeModel
model
:
models
)
{
String
cconv
=
model
.
getName
();
if
(
conventions
.
get
(
cconv
)
!=
null
)
{
ArrayList
<
String
>
parameters
=
conventions
.
get
(
cconv
).
getParameter
();
for
(
VariableStorage
storage
:
model
.
getPotentialInputRegisterStorage
(
currentProgram
))
{
parameters
.
add
(
storage
.
getRegister
().
getName
());
}
}
}
}
/**
* Adds all entry points of internal and external function to a global hash map
* Adds all entry points of internal and external function to a global hash map
* This will later speed up the cast of indirect Calls.
* This will later speed up the cast of indirect Calls.
*/
*/
...
...
This diff is collapsed.
Click to expand it.
src/ghidra/p_code_extractor/internal/ParseCspecContent.java
View file @
9fa65999
...
@@ -267,10 +267,10 @@ public class ParseCspecContent {
...
@@ -267,10 +267,10 @@ public class ParseCspecContent {
RegisterConvention
convention
=
new
RegisterConvention
();
RegisterConvention
convention
=
new
RegisterConvention
();
if
(
name
.
equals
(
"default_proto"
))
{
if
(
name
.
equals
(
"default_proto"
))
{
parser
.
start
();
parser
.
start
();
get
UnaffectedKilledByCallAndOutput
(
parser
,
convention
);
get
CconvRegister
(
parser
,
convention
);
parser
.
end
();
parser
.
end
();
}
else
if
(
name
.
equals
(
"prototype"
))
{
}
else
if
(
name
.
equals
(
"prototype"
))
{
get
UnaffectedKilledByCallAndOutput
(
parser
,
convention
);
get
CconvRegister
(
parser
,
convention
);
}
}
// Using the hashmap this way will simplify the addition of parameter registers which are not parsed here
// Using the hashmap this way will simplify the addition of parameter registers which are not parsed here
...
@@ -286,17 +286,19 @@ public class ParseCspecContent {
...
@@ -286,17 +286,19 @@ public class ParseCspecContent {
*
*
* Sets the convention's unaffected, killed by call and return registers as well as the calling convention
* Sets the convention's unaffected, killed by call and return registers as well as the calling convention
*/
*/
public
static
void
get
UnaffectedKilledByCallAndOutput
(
XmlPullParser
parser
,
RegisterConvention
convention
)
{
public
static
void
get
CconvRegister
(
XmlPullParser
parser
,
RegisterConvention
convention
)
{
XmlElement
protoElement
=
parser
.
start
();
XmlElement
protoElement
=
parser
.
start
();
String
cconv
=
protoElement
.
getAttribute
(
"name"
);
String
cconv
=
protoElement
.
getAttribute
(
"name"
);
convention
.
setCconv
(
cconv
);
convention
.
setCconv
(
cconv
);
while
(
parser
.
peek
().
isStart
())
{
while
(
parser
.
peek
().
isStart
())
{
XmlElement
registers
=
parser
.
peek
();
XmlElement
entries
=
parser
.
peek
();
if
(
registers
.
getName
().
equals
(
"unaffected"
))
{
if
(
entries
.
getName
().
equals
(
"input"
))
{
parseInput
(
parser
,
convention
);
}
else
if
(
entries
.
getName
().
equals
(
"unaffected"
))
{
convention
.
setUnaffected
(
getRegisters
(
parser
));
convention
.
setUnaffected
(
getRegisters
(
parser
));
}
else
if
(
register
s
.
getName
().
equals
(
"killedbycall"
))
{
}
else
if
(
entrie
s
.
getName
().
equals
(
"killedbycall"
))
{
convention
.
setKilledByCall
(
getRegisters
(
parser
));
convention
.
setKilledByCall
(
getRegisters
(
parser
));
}
else
if
(
register
s
.
getName
().
equals
(
"output"
))
{
}
else
if
(
entrie
s
.
getName
().
equals
(
"output"
))
{
convention
.
setReturn
(
parseOutput
(
parser
));
convention
.
setReturn
(
parseOutput
(
parser
));
}
else
{
}
else
{
discardSubTree
(
parser
);
discardSubTree
(
parser
);
...
@@ -305,6 +307,55 @@ public class ParseCspecContent {
...
@@ -305,6 +307,55 @@ public class ParseCspecContent {
parser
.
end
(
protoElement
);
parser
.
end
(
protoElement
);
}
}
/**
*
* @param parser: parser for .cspec file
* @param convention: convention object for later serialization
*
* Parses the parameter registers for an external symbol.
* Differentiates between integer and float registers.
*/
public
static
void
parseInput
(
XmlPullParser
parser
,
RegisterConvention
convention
)
{
ArrayList
<
String
>
integerRegisters
=
new
ArrayList
<
String
>();
ArrayList
<
String
>
floatRegisters
=
new
ArrayList
<
String
>();
parser
.
start
(
"input"
);
while
(
parser
.
peek
().
isStart
())
{
XmlElement
pentry
=
parser
.
peek
();
parser
.
start
(
"pentry"
);
XmlElement
entry
=
parser
.
peek
();
if
(
entry
.
getName
().
equals
(
"register"
))
{
parser
.
start
(
"register"
);
if
(
isFloatRegister
(
pentry
))
{
floatRegisters
.
add
(
entry
.
getAttribute
(
"name"
));
}
else
{
integerRegisters
.
add
(
entry
.
getAttribute
(
"name"
));
}
parser
.
end
();
}
else
{
discardSubTree
(
parser
);
}
parser
.
end
();
}
parser
.
end
();
convention
.
setFloatParameter
(
floatRegisters
);
convention
.
setIntegerParameter
(
integerRegisters
);
}
/**
*
* @param pentry: Parameter register entry
* @return: indicates whether the current entry is a float register.
*/
public
static
Boolean
isFloatRegister
(
XmlElement
pentry
)
{
if
(
pentry
.
hasAttribute
(
"metatype"
))
{
if
(
pentry
.
getAttribute
(
"metatype"
).
equals
(
"float"
))
{
return
true
;
}
}
return
false
;
}
/**
/**
*
*
...
...
This diff is collapsed.
Click to expand it.
src/ghidra/p_code_extractor/internal/RegisterConvention.java
View file @
9fa65999
package
internal
;
package
internal
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
...
@@ -9,8 +8,10 @@ public class RegisterConvention {
...
@@ -9,8 +8,10 @@ public class RegisterConvention {
@SerializedName
(
"calling_convention"
)
@SerializedName
(
"calling_convention"
)
private
String
cconv
;
private
String
cconv
;
@SerializedName
(
"parameter_register"
)
@SerializedName
(
"integer_parameter_register"
)
private
ArrayList
<
String
>
parameter
;
private
ArrayList
<
String
>
integerParameter
;
@SerializedName
(
"float_parameter_register"
)
private
ArrayList
<
String
>
floatParameter
;
@SerializedName
(
"return_register"
)
@SerializedName
(
"return_register"
)
private
ArrayList
<
String
>
return_
;
private
ArrayList
<
String
>
return_
;
@SerializedName
(
"unaffected_register"
)
@SerializedName
(
"unaffected_register"
)
...
@@ -19,15 +20,24 @@ public class RegisterConvention {
...
@@ -19,15 +20,24 @@ public class RegisterConvention {
private
ArrayList
<
String
>
killedByCall
;
private
ArrayList
<
String
>
killedByCall
;
public
RegisterConvention
()
{
public
RegisterConvention
()
{
this
.
setParameter
(
new
ArrayList
<
String
>());
this
.
setIntegerParameter
(
new
ArrayList
<
String
>());
this
.
setFloatParameter
(
new
ArrayList
<
String
>());
this
.
setReturn
(
new
ArrayList
<
String
>());
this
.
setReturn
(
new
ArrayList
<
String
>());
this
.
setUnaffected
(
new
ArrayList
<
String
>());
this
.
setUnaffected
(
new
ArrayList
<
String
>());
this
.
setKilledByCall
(
new
ArrayList
<
String
>());
this
.
setKilledByCall
(
new
ArrayList
<
String
>());
}
}
public
RegisterConvention
(
String
cconv
,
ArrayList
<
String
>
parameter
,
ArrayList
<
String
>
return_
,
ArrayList
<
String
>
unaffected
,
ArrayList
<
String
>
killedByCall
)
{
public
RegisterConvention
(
String
cconv
,
ArrayList
<
String
>
integerParameter
,
ArrayList
<
String
>
floatParameter
,
ArrayList
<
String
>
return_
,
ArrayList
<
String
>
unaffected
,
ArrayList
<
String
>
killedByCall
)
{
this
.
setCconv
(
cconv
);
this
.
setCconv
(
cconv
);
this
.
setParameter
(
parameter
);
this
.
setIntegerParameter
(
integerParameter
);
this
.
setFloatParameter
(
floatParameter
);
this
.
setReturn
(
return_
);
this
.
setReturn
(
return_
);
this
.
setUnaffected
(
unaffected
);
this
.
setUnaffected
(
unaffected
);
this
.
setKilledByCall
(
killedByCall
);
this
.
setKilledByCall
(
killedByCall
);
...
@@ -41,12 +51,20 @@ public class RegisterConvention {
...
@@ -41,12 +51,20 @@ public class RegisterConvention {
this
.
cconv
=
cconv
;
this
.
cconv
=
cconv
;
}
}
public
ArrayList
<
String
>
getParameter
()
{
public
ArrayList
<
String
>
getIntegerParameter
()
{
return
parameter
;
return
integerParameter
;
}
public
void
setIntegerParameter
(
ArrayList
<
String
>
integerParameter
)
{
this
.
integerParameter
=
integerParameter
;
}
public
ArrayList
<
String
>
getFloatParameter
()
{
return
floatParameter
;
}
}
public
void
set
Parameter
(
ArrayList
<
String
>
p
arameter
)
{
public
void
set
FloatParameter
(
ArrayList
<
String
>
floatP
arameter
)
{
this
.
parameter
=
p
arameter
;
this
.
floatParameter
=
floatP
arameter
;
}
}
public
ArrayList
<
String
>
getReturn
()
{
public
ArrayList
<
String
>
getReturn
()
{
...
...
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