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
May 05, 2021
by
Melvin Klimke
Committed by
GitHub
May 05, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better parameter parsing for external Symbols (#176)
parent
275c13aa
Hide 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> {
// 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.
// 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
)
{
possible_referenced_ids
.append
(
&
mut
register_value
.referenced_ids
());
}
...
...
@@ -469,7 +473,11 @@ impl<'a> Context<'a> {
self
.adjust_stack_register_on_extern_call
(
state_before_call
,
&
mut
new_state
);
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
)
=
state_before_call
.get_register_by_name
(
parameter_register_name
)
{
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/context/tests.rs
View file @
9fa65999
...
...
@@ -84,7 +84,8 @@ fn mock_project() -> (Project, Config) {
};
let
cconv
=
CallingConvention
{
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
()],
callee_saved_register
:
vec!
[
"callee_saved_reg"
.to_string
()],
};
...
...
src/cwe_checker_lib/src/checkers/cwe_476/state.rs
View file @
9fa65999
...
...
@@ -297,10 +297,9 @@ impl State {
pi_state_option
:
Option
<&
PointerInferenceState
>
,
)
->
bool
{
if
let
Some
(
calling_conv
)
=
project
.get_standard_calling_convention
()
{
self
.check_register_list_for_taint
(
&
calling_conv
.parameter_register
[
..
],
pi_state_option
,
)
let
mut
all_parameters
=
calling_conv
.integer_parameter_register
.clone
();
all_parameters
.append
(
&
mut
calling_conv
.float_parameter_register
.clone
());
self
.check_register_list_for_taint
(
&
all_parameters
,
pi_state_option
)
}
else
{
// No standard calling convention found. Assume everything may be parameters or referenced by parameters.
!
self
.is_empty
()
...
...
src/cwe_checker_lib/src/checkers/cwe_78/state/mod.rs
View file @
9fa65999
...
...
@@ -385,8 +385,12 @@ impl State {
/// 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
)
{
if
let
Some
(
calling_conv
)
=
project
.get_standard_calling_convention
()
{
let
register_names
:
HashSet
<
String
>
=
calling_conv
.parameter_register
.iter
()
.cloned
()
.collect
();
let
register_names
:
HashSet
<
String
>
=
calling_conv
.integer_parameter_register
.iter
()
.chain
(
calling_conv
.float_parameter_register
.iter
())
.cloned
()
.collect
();
let
taints
=
self
.register_taint
.clone
();
for
(
register
,
_
)
in
taints
.iter
()
{
if
register_names
.get
(
&
register
.name
)
.is_none
()
{
...
...
src/cwe_checker_lib/src/intermediate_representation/term.rs
View file @
9fa65999
...
...
@@ -423,8 +423,10 @@ pub struct CallingConvention {
/// The name of the calling convention
#[serde(rename
=
"calling_convention"
)]
pub
name
:
String
,
/// A list of possible parameter register
pub
parameter_register
:
Vec
<
String
>
,
/// Possible integer parameter registers.
pub
integer_parameter_register
:
Vec
<
String
>
,
/// Possible float parameter registers.
pub
float_parameter_register
:
Vec
<
String
>
,
/// A list of possible return register
pub
return_register
:
Vec
<
String
>
,
/// A list of callee-saved register,
...
...
@@ -616,7 +618,8 @@ mod tests {
pub
fn
mock
()
->
CallingConvention
{
CallingConvention
{
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
()],
callee_saved_register
:
vec!
[
"RBP"
.to_string
()],
}
...
...
src/cwe_checker_lib/src/pcode/term.rs
View file @
9fa65999
...
...
@@ -495,8 +495,10 @@ pub struct CallingConvention {
/// The name of the calling convention.
#[serde(rename
=
"calling_convention"
)]
pub
name
:
String
,
/// Possible parameter registers.
parameter_register
:
Vec
<
String
>
,
/// Possible integer parameter registers.
integer_parameter_register
:
Vec
<
String
>
,
/// Possible float parameter registers.
float_parameter_register
:
Vec
<
String
>
,
/// Possible return registers.
return_register
:
Vec
<
String
>
,
/// Callee-saved registers.
...
...
@@ -509,7 +511,8 @@ impl From<CallingConvention> for IrCallingConvention {
fn
from
(
cconv
:
CallingConvention
)
->
IrCallingConvention
{
IrCallingConvention
{
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
,
callee_saved_register
:
cconv
.unaffected_register
,
}
...
...
src/cwe_checker_lib/src/pcode/term/tests.rs
View file @
9fa65999
...
...
@@ -85,7 +85,8 @@ impl Setup {
"
register_calling_convention
": [
{
"
calling_convention
": "
default
",
"
parameter_register
": [],
"
integer_parameter_register
": [],
"
float_parameter_register
": [],
"
return_register
": [],
"
unaffected_register
": [],
"
killed_by_call_register
": []
...
...
src/ghidra/p_code_extractor/PcodeExtractor.java
View file @
9fa65999
...
...
@@ -254,7 +254,6 @@ public class PcodeExtractor extends GhidraScript {
try
{
HashMap
<
String
,
RegisterConvention
>
conventions
=
new
HashMap
<
String
,
RegisterConvention
>();
ParseCspecContent
.
parseSpecs
(
currentProgram
,
conventions
);
addParameterRegister
(
conventions
);
project
.
setRegisterConvention
(
new
ArrayList
<
RegisterConvention
>(
conventions
.
values
()));
}
catch
(
FileNotFoundException
e
)
{
System
.
out
.
println
(
e
);
...
...
@@ -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
* This will later speed up the cast of indirect Calls.
*/
...
...
src/ghidra/p_code_extractor/internal/ParseCspecContent.java
View file @
9fa65999
...
...
@@ -267,10 +267,10 @@ public class ParseCspecContent {
RegisterConvention
convention
=
new
RegisterConvention
();
if
(
name
.
equals
(
"default_proto"
))
{
parser
.
start
();
get
UnaffectedKilledByCallAndOutput
(
parser
,
convention
);
get
CconvRegister
(
parser
,
convention
);
parser
.
end
();
}
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
...
...
@@ -286,17 +286,19 @@ public class ParseCspecContent {
*
* 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
();
String
cconv
=
protoElement
.
getAttribute
(
"name"
);
convention
.
setCconv
(
cconv
);
while
(
parser
.
peek
().
isStart
())
{
XmlElement
registers
=
parser
.
peek
();
if
(
registers
.
getName
().
equals
(
"unaffected"
))
{
XmlElement
entries
=
parser
.
peek
();
if
(
entries
.
getName
().
equals
(
"input"
))
{
parseInput
(
parser
,
convention
);
}
else
if
(
entries
.
getName
().
equals
(
"unaffected"
))
{
convention
.
setUnaffected
(
getRegisters
(
parser
));
}
else
if
(
register
s
.
getName
().
equals
(
"killedbycall"
))
{
}
else
if
(
entrie
s
.
getName
().
equals
(
"killedbycall"
))
{
convention
.
setKilledByCall
(
getRegisters
(
parser
));
}
else
if
(
register
s
.
getName
().
equals
(
"output"
))
{
}
else
if
(
entrie
s
.
getName
().
equals
(
"output"
))
{
convention
.
setReturn
(
parseOutput
(
parser
));
}
else
{
discardSubTree
(
parser
);
...
...
@@ -305,6 +307,55 @@ public class ParseCspecContent {
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
;
}
/**
*
...
...
src/ghidra/p_code_extractor/internal/RegisterConvention.java
View file @
9fa65999
package
internal
;
import
java.util.ArrayList
;
...
...
@@ -9,8 +8,10 @@ public class RegisterConvention {
@SerializedName
(
"calling_convention"
)
private
String
cconv
;
@SerializedName
(
"parameter_register"
)
private
ArrayList
<
String
>
parameter
;
@SerializedName
(
"integer_parameter_register"
)
private
ArrayList
<
String
>
integerParameter
;
@SerializedName
(
"float_parameter_register"
)
private
ArrayList
<
String
>
floatParameter
;
@SerializedName
(
"return_register"
)
private
ArrayList
<
String
>
return_
;
@SerializedName
(
"unaffected_register"
)
...
...
@@ -19,15 +20,24 @@ public class RegisterConvention {
private
ArrayList
<
String
>
killedByCall
;
public
RegisterConvention
()
{
this
.
setParameter
(
new
ArrayList
<
String
>());
this
.
setIntegerParameter
(
new
ArrayList
<
String
>());
this
.
setFloatParameter
(
new
ArrayList
<
String
>());
this
.
setReturn
(
new
ArrayList
<
String
>());
this
.
setUnaffected
(
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
.
setParameter
(
parameter
);
this
.
setIntegerParameter
(
integerParameter
);
this
.
setFloatParameter
(
floatParameter
);
this
.
setReturn
(
return_
);
this
.
setUnaffected
(
unaffected
);
this
.
setKilledByCall
(
killedByCall
);
...
...
@@ -41,12 +51,20 @@ public class RegisterConvention {
this
.
cconv
=
cconv
;
}
public
ArrayList
<
String
>
getParameter
()
{
return
parameter
;
public
ArrayList
<
String
>
getIntegerParameter
()
{
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
)
{
this
.
parameter
=
p
arameter
;
public
void
set
FloatParameter
(
ArrayList
<
String
>
floatP
arameter
)
{
this
.
floatParameter
=
floatP
arameter
;
}
public
ArrayList
<
String
>
getReturn
()
{
...
...
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