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
17022fdb
Unverified
Commit
17022fdb
authored
Nov 11, 2020
by
Melvin Klimke
Committed by
GitHub
Nov 11, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix pointer to external function (#101)
parent
a3a73e8d
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
171 additions
and
79 deletions
+171
-79
tests.rs
...hecker_rs/src/analysis/pointer_inference/context/tests.rs
+1
-0
tests.rs
cwe_checker_rs/src/analysis/pointer_inference/state/tests.rs
+1
-0
term.rs
cwe_checker_rs/src/intermediate_representation/term.rs
+2
-0
term.rs
cwe_checker_rs/src/pcode/term.rs
+5
-2
symbol.rs
cwe_checker_rs/src/term/symbol.rs
+1
-0
PcodeExtractor.java
ghidra/p_code_extractor/PcodeExtractor.java
+151
-67
ExternSymbol.java
ghidra/p_code_extractor/symbol/ExternSymbol.java
+9
-8
Program.java
ghidra/p_code_extractor/term/Program.java
+1
-2
No files found.
cwe_checker_rs/src/analysis/pointer_inference/context/tests.rs
View file @
17022fdb
...
...
@@ -15,6 +15,7 @@ fn mock_extern_symbol(name: &str) -> ExternSymbol {
let
arg
=
Arg
::
Register
(
register
(
"RDX"
));
ExternSymbol
{
tid
:
Tid
::
new
(
"extern_"
.to_string
()
+
name
),
addresses
:
vec!
[],
name
:
name
.into
(),
calling_convention
:
None
,
parameters
:
vec!
[
arg
.clone
()],
...
...
cwe_checker_rs/src/analysis/pointer_inference/state/tests.rs
View file @
17022fdb
...
...
@@ -276,6 +276,7 @@ fn clear_parameters_on_the_stack_on_extern_calls() {
};
let
extern_symbol
=
ExternSymbol
{
tid
:
Tid
::
new
(
"symbol"
),
addresses
:
vec!
[],
name
:
"my_extern_symbol"
.into
(),
calling_convention
:
None
,
parameters
:
vec!
[
stack_param
],
...
...
cwe_checker_rs/src/intermediate_representation/term.rs
View file @
17022fdb
...
...
@@ -217,6 +217,8 @@ pub enum Arg {
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
ExternSymbol
{
pub
tid
:
Tid
,
/// Addresses of possibly multiple locations of the same extern symbol
pub
addresses
:
Vec
<
String
>
,
/// The name of the extern symbol
pub
name
:
String
,
/// The calling convention used for the extern symbol if known
...
...
cwe_checker_rs/src/pcode/term.rs
View file @
17022fdb
...
...
@@ -294,7 +294,7 @@ impl From<Sub> for IrSub {
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
pub
struct
ExternSymbol
{
pub
tid
:
Tid
,
pub
address
:
String
,
pub
address
es
:
Vec
<
String
>
,
pub
name
:
String
,
pub
calling_convention
:
Option
<
String
>
,
pub
arguments
:
Vec
<
Arg
>
,
...
...
@@ -337,6 +337,7 @@ impl From<ExternSymbol> for IrExternSymbol {
}
IrExternSymbol
{
tid
:
symbol
.tid
,
addresses
:
symbol
.addresses
,
name
:
symbol
.name
,
calling_convention
:
symbol
.calling_convention
,
parameters
,
...
...
@@ -655,7 +656,9 @@ mod tests {
"
id
": "
sub_08048410
",
"
address
": "
08048410
"
},
"
address
": "
08048410
",
"
addresses
": [
"
08048410
"
],
"
name
": "
atoi
",
"
calling_convention
": "
__cdecl
",
"
arguments
": [
...
...
cwe_checker_rs/src/term/symbol.rs
View file @
17022fdb
...
...
@@ -76,6 +76,7 @@ impl From<ExternSymbol> for IrExternSymbol {
}
IrExternSymbol
{
tid
:
symbol
.tid
,
addresses
:
vec!
[
symbol
.address
],
name
:
symbol
.name
,
calling_convention
:
None
,
// We do not parse more than one calling convention from BAP at the moment. So we assume everything uses the standard one.
parameters
,
...
...
ghidra/p_code_extractor/PcodeExtractor.java
View file @
17022fdb
import
java.io.FileNotFoundException
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.regex.Matcher
;
...
...
@@ -56,7 +57,9 @@ public class PcodeExtractor extends GhidraScript {
Term
<
Program
>
program
=
null
;
FunctionManager
funcMan
;
HashMap
<
String
,
Integer
>
functionEntryPoints
;
SymbolTable
symTab
;
HashMap
<
String
,
Tid
>
functionEntryPoints
;
HashMap
<
String
,
ExternSymbol
>
externalSymbolMap
;
ghidra
.
program
.
model
.
listing
.
Program
ghidraProgram
;
VarnodeContext
context
;
String
cpuArch
;
...
...
@@ -79,11 +82,15 @@ public class PcodeExtractor extends GhidraScript {
context
=
new
VarnodeContext
(
ghidraProgram
,
ghidraProgram
.
getProgramContext
(),
ghidraProgram
.
getProgramContext
());
cpuArch
=
getCpuArchitecture
();
symTab
=
ghidraProgram
.
getSymbolTable
();
externalSymbolMap
=
new
HashMap
<
String
,
ExternSymbol
>();
createExternalSymbolMap
(
symTab
);
program
=
createProgramTerm
();
functionEntryPoints
=
new
HashMap
<
String
,
Integer
>();
functionEntryPoints
=
new
HashMap
<
String
,
Tid
>();
setFunctionEntryPoints
();
Project
project
=
createProject
();
program
=
iterateFunctions
(
simpleBM
,
listing
);
program
.
getTerm
().
setExternSymbols
(
new
ArrayList
<
ExternSymbol
>(
externalSymbolMap
.
values
()));
String
jsonPath
=
getScriptArgs
()[
0
];
Serializer
ser
=
new
Serializer
(
project
,
jsonPath
);
...
...
@@ -98,15 +105,21 @@ public class PcodeExtractor extends GhidraScript {
* This will later speed up the cast of indirect Calls.
*/
protected
void
setFunctionEntryPoints
()
{
// Add
external symbols and internal function addresses to hash map
int
funcCounter
=
0
;
for
(
ExternSymbol
sym
:
program
.
getTerm
().
getExternSymbols
())
{
functionEntryPoints
.
put
(
sym
.
getAddress
(),
funcCounter
);
funcCounter
++;
// Add
thunk addresses for external functions
for
(
ExternSymbol
sym
:
externalSymbolMap
.
values
()){
for
(
String
address
:
sym
.
getAddresses
())
{
functionEntryPoints
.
put
(
address
,
sym
.
getTid
()
);
}
}
// Add internal function addresses
for
(
Function
func
:
funcMan
.
getFunctionsNoStubs
(
true
))
{
functionEntryPoints
.
put
(
func
.
getEntryPoint
().
toString
(),
funcCounter
);
funcCounter
++;
String
address
=
func
.
getEntryPoint
().
toString
();
functionEntryPoints
.
put
(
address
,
new
Tid
(
String
.
format
(
"sub_%s"
,
address
),
address
));
}
// Add external addresses
for
(
Function
ext
:
funcMan
.
getExternalFunctions
())
{
String
address
=
ext
.
getEntryPoint
().
toString
();
functionEntryPoints
.
put
(
address
,
new
Tid
(
String
.
format
(
"sub_%s"
,
address
),
address
));
}
}
...
...
@@ -625,8 +638,7 @@ public class PcodeExtractor extends GhidraScript {
*/
protected
Term
<
Program
>
createProgramTerm
()
{
Tid
progTid
=
new
Tid
(
String
.
format
(
"prog_%s"
,
ghidraProgram
.
getMinAddress
().
toString
()),
ghidraProgram
.
getMinAddress
().
toString
());
SymbolTable
symTab
=
ghidraProgram
.
getSymbolTable
();
return
new
Term
<
Program
>(
progTid
,
new
Program
(
new
ArrayList
<
Term
<
Sub
>>(),
addExternalSymbols
(
symTab
),
addEntryPoints
(
symTab
)));
return
new
Term
<
Program
>(
progTid
,
new
Program
(
new
ArrayList
<
Term
<
Sub
>>(),
addEntryPoints
(
symTab
)));
}
...
...
@@ -652,32 +664,65 @@ public class PcodeExtractor extends GhidraScript {
/**
*
* @param symTab: symbol table
* @return: list of external symbols
*
* Creates a
list
of external symbols to add to the program term
* Creates a
map
of external symbols to add to the program term
*/
protected
ArrayList
<
ExternSymbol
>
addExternalSymbols
(
SymbolTable
symTab
)
{
ArrayList
<
ExternSymbol
>
extSym
=
new
ArrayList
<
ExternSymbol
>();
ArrayList
<
Symbol
>
externalSymbols
=
new
ArrayList
<
Symbol
>();
ArrayList
<
Symbol
>
definedSymbols
=
new
ArrayList
<
Symbol
>();
symTab
.
getExternalSymbols
().
forEachRemaining
(
externalSymbols:
:
add
);
symTab
.
getDefinedSymbols
().
forEachRemaining
(
definedSymbols:
:
add
);
for
(
Symbol
def
:
definedSymbols
)
{
for
(
Symbol
ext
:
externalSymbols
)
{
if
(
def
.
getName
().
equals
(
ext
.
getName
())
&&
!
def
.
getAddress
().
toString
().
startsWith
(
"EXTERNAL:"
)
&&
def
.
getSymbolType
()
==
SymbolType
.
FUNCTION
&&
notInReferences
(
def
))
{
extSym
.
add
(
createExternSymbol
(
def
));
break
;
protected
void
createExternalSymbolMap
(
SymbolTable
symTab
)
{
HashMap
<
String
,
ArrayList
<
Function
>>
symbolMap
=
new
HashMap
<
String
,
ArrayList
<
Function
>>();
funcMan
.
getExternalFunctions
().
forEach
(
func
->
{
ArrayList
<
Function
>
thunkFuncs
=
new
ArrayList
<
Function
>();
getThunkFunctions
(
func
,
thunkFuncs
);
if
(
thunkFuncs
.
size
()
>
0
)
{
for
(
Function
thunk
:
thunkFuncs
)
{
addToSymbolMap
(
symbolMap
,
thunk
);
}
}
else
{
addToSymbolMap
(
symbolMap
,
func
);
}
});
createExternalSymbols
(
symbolMap
);
}
/**
*
* @param func: Function for which thunk functions are to be found
* @param thunkFuncs: List of found thunk functions
*
* Recursively find thunk functions in symbol chain
*/
protected
void
getThunkFunctions
(
Function
func
,
ArrayList
<
Function
>
thunkFuncs
)
{
Address
[]
thunks
=
func
.
getFunctionThunkAddresses
();
if
(
thunks
!=
null
)
{
for
(
Address
thunkAddr
:
thunks
)
{
Function
thunkFunction
=
getFunctionAt
(
thunkAddr
);
thunkFuncs
.
add
(
funcMan
.
getFunctionAt
(
thunkAddr
));
getThunkFunctions
(
thunkFunction
,
thunkFuncs
);
}
}
}
return
extSym
;
/**
*
* @param symbolMap: Maps symbol names to multiple function declarations
* @param func: Function to be added to symbol map
*
* Either adds a function to a given symbol name or creates a new entry in the symbol map
*/
protected
void
addToSymbolMap
(
HashMap
<
String
,
ArrayList
<
Function
>>
symbolMap
,
Function
func
)
{
if
(
symbolMap
.
containsKey
(
func
.
getName
()))
{
symbolMap
.
get
(
func
.
getName
()).
add
(
func
);
}
else
{
symbolMap
.
put
(
func
.
getName
(),
new
ArrayList
<
Function
>(){{
add
(
func
);}});
}
}
/**
*
* @param
sym: external symbol
* @param
func: function to get arguments
* @return: if same symbol name in references
*
* Checks whether the same symbol name is in the references of the current symbol.
...
...
@@ -692,12 +737,10 @@ public class PcodeExtractor extends GhidraScript {
* by some_function().
*
*/
protected
Boolean
notInReferences
(
Symbol
sym
)
{
for
(
Reference
ref
:
sym
.
getReferences
())
{
if
(
funcMan
.
getFunctionContaining
(
ref
.
getFromAddress
())
!=
null
)
{
if
(
funcMan
.
getFunctionContaining
(
ref
.
getFromAddress
()).
getName
().
equals
(
sym
.
getName
()))
{
return
false
;
}
protected
Boolean
notInReferences
(
Function
func
)
{
for
(
Function
calling
:
func
.
getCallingFunctions
(
getMonitor
()))
{
if
(
calling
.
getName
().
equals
(
func
.
getName
()))
{
return
false
;
}
}
...
...
@@ -706,34 +749,28 @@ public class PcodeExtractor extends GhidraScript {
/**
* @param symbol: External symbol
* @return: new ExternSymbol
* @param symbolMap: External symbol map
*
* Creates
an external symbol
with an unique TID, a calling convention and argument objects.
* Creates
external symbol map
with an unique TID, a calling convention and argument objects.
*/
protected
ExternSymbol
createExternSymbol
(
Symbol
symbol
)
{
Tid
tid
=
new
Tid
(
String
.
format
(
"sub_%s"
,
symbol
.
getAddress
().
toString
()),
symbol
.
getAddress
().
toString
());
ArrayList
<
Arg
>
args
=
createArguments
(
symbol
);
Boolean
noReturn
=
funcMan
.
getFunctionAt
(
symbol
.
getAddress
()).
hasNoReturn
();
return
new
ExternSymbol
(
tid
,
symbol
.
getAddress
().
toString
(),
symbol
.
getName
(),
funcMan
.
getDefaultCallingConvention
().
getName
(),
args
,
noReturn
);
}
/**
* @param def: Defined symbol
* @return: true if referencing function is thunk, else false
*
* Checks if current external symbol is referenced by a Thunk Function.
* If so, the Thunk Function is the internally called function.
*/
protected
Boolean
isThunkFunctionRef
(
Symbol
def
)
{
Reference
[]
refs
=
def
.
getReferences
();
if
(
refs
.
length
==
0
)
{
return
false
;
protected
void
createExternalSymbols
(
HashMap
<
String
,
ArrayList
<
Function
>>
symbolMap
)
{
for
(
Map
.
Entry
<
String
,
ArrayList
<
Function
>>
functions
:
symbolMap
.
entrySet
())
{
ExternSymbol
extSym
=
new
ExternSymbol
();
extSym
.
setName
(
functions
.
getKey
());
for
(
Function
func
:
functions
.
getValue
())
{
if
(
notInReferences
(
func
))
{
extSym
.
setTid
(
new
Tid
(
String
.
format
(
"sub_%s"
,
func
.
getEntryPoint
().
toString
()),
func
.
getEntryPoint
().
toString
()));
extSym
.
setNoReturn
(
func
.
hasNoReturn
());
extSym
.
setArguments
(
createArguments
(
func
));
extSym
.
setCallingConvention
(
funcMan
.
getDefaultCallingConvention
().
toString
());
}
if
(!
func
.
isExternal
())
{
extSym
.
getAddresses
().
add
(
func
.
getEntryPoint
().
toString
());
}
}
externalSymbolMap
.
put
(
functions
.
getKey
(),
extSym
);
}
Address
refAddr
=
def
.
getReferences
()[
0
].
getFromAddress
();
return
funcMan
.
getFunctionContaining
(
refAddr
)
!=
null
&&
funcMan
.
getFunctionContaining
(
refAddr
).
isThunk
();
}
...
...
@@ -743,14 +780,13 @@ public class PcodeExtractor extends GhidraScript {
/**
* @param
symbol: Symbol used to get corresponding function
* @param
func: function to get arguments
* @return: new Arg ArrayList
*
* Creates Arguments for the ExternSymbol object.
*/
protected
ArrayList
<
Arg
>
createArguments
(
Symbol
symbol
)
{
protected
ArrayList
<
Arg
>
createArguments
(
Function
func
)
{
ArrayList
<
Arg
>
args
=
new
ArrayList
<
Arg
>();
Function
func
=
funcMan
.
getFunctionAt
(
symbol
.
getAddress
());
Parameter
[]
params
=
func
.
getParameters
();
for
(
Parameter
param
:
params
)
{
args
.
add
(
specifyArg
(
param
));
...
...
@@ -819,8 +855,7 @@ public class PcodeExtractor extends GhidraScript {
* Creates a Sub Term with an unique TID consisting of the prefix sub and its entry address.
*/
protected
Term
<
Sub
>
createSubTerm
(
Function
func
)
{
Tid
subTid
=
new
Tid
(
String
.
format
(
"sub_%s"
,
func
.
getEntryPoint
().
toString
()),
func
.
getEntryPoint
().
toString
());
return
new
Term
<
Sub
>(
subTid
,
new
Sub
(
func
.
getName
(),
func
.
getBody
()));
return
new
Term
<
Sub
>(
functionEntryPoints
.
get
(
func
.
getEntryPoint
().
toString
()),
new
Sub
(
func
.
getName
(),
func
.
getBody
()));
}
...
...
@@ -1008,7 +1043,7 @@ public class PcodeExtractor extends GhidraScript {
* Either returns an address to the memory if not resolved or an address to a symbol
*/
protected
Label
handleLabelsForIndirectCalls
(
PcodeOp
pcodeOp
)
{
Tid
subTid
=
getTargetTid
(
pcodeOp
.
getInput
(
0
)
);
Tid
subTid
=
getTargetTid
();
if
(
subTid
!=
null
)
{
return
new
Label
(
subTid
);
}
...
...
@@ -1023,15 +1058,64 @@ public class PcodeExtractor extends GhidraScript {
*
* Resolves the target id for an indirect jump
*/
protected
Tid
getTargetTid
(
Varnode
target
)
{
protected
Tid
getTargetTid
()
{
Address
[]
flowDestinations
=
PcodeBlockData
.
instruction
.
getFlows
();
if
(
flowDestinations
.
length
==
1
)
{
for
(
Address
flow
:
flowDestinations
)
{
if
(
functionEntryPoints
.
containsKey
(
flow
.
toString
())){
return
new
Tid
(
String
.
format
(
"sub_%s"
,
flow
.
toString
()),
flow
.
toString
());
Address
flow
=
flowDestinations
[
0
];
if
(
functionEntryPoints
.
containsKey
(
flow
.
toString
())){
// In case a jump to an external address occured, check for fuction pointer
Function
external
=
funcMan
.
getFunctionAt
(
flow
);
if
(
flow
.
isExternalAddress
())
{
return
handleCallToFunctionPointer
(
flow
,
external
);
}
else
{
return
functionEntryPoints
.
get
(
flow
.
toString
());
}
}
}
return
null
;
}
/**
*
* @param flow: Flow address of indirect call
* @return: target tid of external symbol
*
* Tries to parse the function pointer address and if the external symbol TID
* is an external address overwrite the TID with the function pointer address.
* The function pointer address is always added to the address list of the external symbol.
*/
protected
Tid
handleCallToFunctionPointer
(
Address
flow
,
Function
external
)
{
Address
funcPointer
=
parseFunctionPointerAddress
();
Tid
targetTid
=
null
;
if
(
funcPointer
!=
null
&&
externalSymbolMap
.
containsKey
(
external
.
getName
()))
{
ExternSymbol
symbol
=
externalSymbolMap
.
get
(
external
.
getName
());
if
(
symbol
.
getTid
().
getId
().
startsWith
(
"sub_EXTERNAL"
))
{
targetTid
=
new
Tid
(
String
.
format
(
"sub_%s"
,
funcPointer
.
toString
()),
funcPointer
.
toString
());
symbol
.
setTid
(
targetTid
);
}
else
{
targetTid
=
symbol
.
getTid
();
}
symbol
.
getAddresses
().
add
(
funcPointer
.
toString
());
}
return
targetTid
;
}
/**
*
* @return Address of function pointer
*
* Parses the function pointer address out of an indirect call instruction
*/
protected
Address
parseFunctionPointerAddress
()
{
for
(
PcodeOp
op
:
PcodeBlockData
.
ops
)
{
if
(
op
.
getOpcode
()
==
PcodeOp
.
CALLIND
&&
op
.
getInput
(
0
).
isAddress
())
{
return
op
.
getInput
(
0
).
getAddress
();
}
}
return
null
;
}
...
...
ghidra/p_code_extractor/symbol/ExternSymbol.java
View file @
17022fdb
...
...
@@ -11,8 +11,8 @@ public class ExternSymbol {
@SerializedName
(
"tid"
)
private
Tid
tid
;
@SerializedName
(
"address"
)
private
String
addres
s
;
@SerializedName
(
"address
es
"
)
private
ArrayList
<
String
>
addresse
s
;
@SerializedName
(
"name"
)
private
String
name
;
@SerializedName
(
"calling_convention"
)
...
...
@@ -23,11 +23,12 @@ public class ExternSymbol {
private
Boolean
noReturn
;
public
ExternSymbol
()
{
this
.
setAddresses
(
new
ArrayList
<
String
>());
}
public
ExternSymbol
(
Tid
tid
,
String
addres
s
,
String
name
,
String
callingConvention
,
ArrayList
<
Arg
>
arguments
,
Boolean
noReturn
)
{
public
ExternSymbol
(
Tid
tid
,
ArrayList
<
String
>
addresse
s
,
String
name
,
String
callingConvention
,
ArrayList
<
Arg
>
arguments
,
Boolean
noReturn
)
{
this
.
setTid
(
tid
);
this
.
setAddress
(
addres
s
);
this
.
setAddress
es
(
addresse
s
);
this
.
setName
(
name
);
this
.
setCallingConvention
(
callingConvention
);
this
.
setArguments
(
arguments
);
...
...
@@ -42,12 +43,12 @@ public class ExternSymbol {
this
.
tid
=
tid
;
}
public
String
getAddres
s
()
{
return
address
;
public
ArrayList
<
String
>
getAddresse
s
()
{
return
address
es
;
}
public
void
setAddress
(
String
addres
s
)
{
this
.
address
=
addres
s
;
public
void
setAddress
es
(
ArrayList
<
String
>
addresse
s
)
{
this
.
address
es
=
addresse
s
;
}
public
String
getName
()
{
...
...
ghidra/p_code_extractor/term/Program.java
View file @
17022fdb
...
...
@@ -22,9 +22,8 @@ public class Program {
this
.
setSubs
(
subs
);
}
public
Program
(
ArrayList
<
Term
<
Sub
>>
subs
,
ArrayList
<
ExternSymbol
>
externSymbols
,
ArrayList
<
Tid
>
entryPoints
)
{
public
Program
(
ArrayList
<
Term
<
Sub
>>
subs
,
ArrayList
<
Tid
>
entryPoints
)
{
this
.
setSubs
(
subs
);
this
.
setExternSymbols
(
externSymbols
);
this
.
setEntryPoints
(
entryPoints
);
}
...
...
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