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-gitdep
cwe_checker
Commits
02b9ec8a
Unverified
Commit
02b9ec8a
authored
4 years ago
by
Melvin Klimke
Committed by
GitHub
4 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix direct call targets (#104)
parent
17022fdb
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
61 additions
and
52 deletions
+61
-52
PcodeExtractor.java
ghidra/p_code_extractor/PcodeExtractor.java
+61
-52
No files found.
ghidra/p_code_extractor/PcodeExtractor.java
View file @
02b9ec8a
...
@@ -36,10 +36,7 @@ import ghidra.program.model.listing.Parameter;
...
@@ -36,10 +36,7 @@ import ghidra.program.model.listing.Parameter;
import
ghidra.program.model.listing.VariableStorage
;
import
ghidra.program.model.listing.VariableStorage
;
import
ghidra.program.model.pcode.PcodeOp
;
import
ghidra.program.model.pcode.PcodeOp
;
import
ghidra.program.model.pcode.Varnode
;
import
ghidra.program.model.pcode.Varnode
;
import
ghidra.program.model.symbol.Symbol
;
import
ghidra.program.model.symbol.SymbolTable
;
import
ghidra.program.model.symbol.SymbolTable
;
import
ghidra.program.model.symbol.SymbolType
;
import
ghidra.program.model.symbol.Reference
;
import
ghidra.program.util.VarnodeContext
;
import
ghidra.program.util.VarnodeContext
;
import
ghidra.util.exception.CancelledException
;
import
ghidra.util.exception.CancelledException
;
...
@@ -105,21 +102,17 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -105,21 +102,17 @@ public class PcodeExtractor extends GhidraScript {
* This will later speed up the cast of indirect Calls.
* This will later speed up the cast of indirect Calls.
*/
*/
protected
void
setFunctionEntryPoints
()
{
protected
void
setFunctionEntryPoints
()
{
// 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
// Add internal function addresses
for
(
Function
func
:
funcMan
.
getFunctionsNoStubs
(
true
))
{
for
(
Function
func
:
funcMan
.
getFunctionsNoStubs
(
true
))
{
String
address
=
func
.
getEntryPoint
().
toString
();
String
address
=
func
.
getEntryPoint
().
toString
();
functionEntryPoints
.
put
(
address
,
new
Tid
(
String
.
format
(
"sub_%s"
,
address
),
address
));
functionEntryPoints
.
put
(
address
,
new
Tid
(
String
.
format
(
"sub_%s"
,
address
),
address
));
}
}
// Add external addresses
for
(
Function
ext
:
funcMan
.
getExternalFunctions
())
{
// Add thunk addresses for external functions
String
address
=
ext
.
getEntryPoint
().
toString
();
for
(
ExternSymbol
sym
:
externalSymbolMap
.
values
()){
functionEntryPoints
.
put
(
address
,
new
Tid
(
String
.
format
(
"sub_%s"
,
address
),
address
));
for
(
String
address
:
sym
.
getAddresses
())
{
functionEntryPoints
.
put
(
address
,
sym
.
getTid
());
}
}
}
}
}
...
@@ -1013,14 +1006,14 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -1013,14 +1006,14 @@ public class PcodeExtractor extends GhidraScript {
Label
jumpLabel
;
Label
jumpLabel
;
if
(
fallThrough
==
null
)
{
if
(
fallThrough
==
null
)
{
switch
(
mnemonic
)
{
switch
(
mnemonic
)
{
case
"CALL"
:
case
"CALLIND"
:
case
"CALLIND"
:
jumpLabel
=
handleLabelsFor
Indirect
Calls
(
pcodeOp
);
jumpLabel
=
handleLabelsForCalls
(
pcodeOp
);
break
;
break
;
case
"BRANCHIND"
:
case
"BRANCHIND"
:
case
"RETURN"
:
case
"RETURN"
:
jumpLabel
=
new
Label
((
Variable
)
createVariable
(
pcodeOp
.
getInput
(
0
)));
jumpLabel
=
new
Label
((
Variable
)
createVariable
(
pcodeOp
.
getInput
(
0
)));
break
;
break
;
case
"CALL"
:
case
"CALLOTHER"
:
case
"CALLOTHER"
:
jumpLabel
=
new
Label
((
Tid
)
new
Tid
(
String
.
format
(
"sub_%s"
,
pcodeOp
.
getInput
(
0
).
getAddress
().
toString
()),
pcodeOp
.
getInput
(
0
).
getAddress
().
toString
()));
jumpLabel
=
new
Label
((
Tid
)
new
Tid
(
String
.
format
(
"sub_%s"
,
pcodeOp
.
getInput
(
0
).
getAddress
().
toString
()),
pcodeOp
.
getInput
(
0
).
getAddress
().
toString
()));
break
;
break
;
...
@@ -1042,11 +1035,14 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -1042,11 +1035,14 @@ public class PcodeExtractor extends GhidraScript {
*
*
* Either returns an address to the memory if not resolved or an address to a symbol
* Either returns an address to the memory if not resolved or an address to a symbol
*/
*/
protected
Label
handleLabelsFor
Indirect
Calls
(
PcodeOp
pcodeOp
)
{
protected
Label
handleLabelsForCalls
(
PcodeOp
pcodeOp
)
{
Tid
subTid
=
getTargetTid
();
Tid
subTid
=
getTargetTid
(
pcodeOp
);
if
(
subTid
!=
null
)
{
if
(
subTid
!=
null
)
{
return
new
Label
(
subTid
);
return
new
Label
(
subTid
);
}
}
if
(
pcodeOp
.
getOpcode
()
==
PcodeOp
.
CALL
)
{
return
new
Label
(
new
Tid
(
String
.
format
(
"sub_%s"
,
pcodeOp
.
getInput
(
0
).
getAddress
().
toString
()),
pcodeOp
.
getInput
(
0
).
getAddress
().
toString
()));
}
return
new
Label
((
Variable
)
createVariable
(
pcodeOp
.
getInput
(
0
)));
return
new
Label
((
Variable
)
createVariable
(
pcodeOp
.
getInput
(
0
)));
}
}
...
@@ -1058,18 +1054,38 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -1058,18 +1054,38 @@ public class PcodeExtractor extends GhidraScript {
*
*
* Resolves the target id for an indirect jump
* Resolves the target id for an indirect jump
*/
*/
protected
Tid
getTargetTid
()
{
protected
Tid
getTargetTid
(
PcodeOp
pcodeOp
)
{
// First check whether the parsed address from the pcodeOp operation
// is in the entry points map and if so, return the corresponding Tid.
// This is a cheap operation
String
targetAddress
=
parseCallTargetAddress
(
pcodeOp
);
if
(
functionEntryPoints
.
containsKey
(
targetAddress
))
{
return
functionEntryPoints
.
get
(
targetAddress
);
}
// If no such target exists in the entry points map, follow the flows
// from the instruction
Address
[]
flowDestinations
=
PcodeBlockData
.
instruction
.
getFlows
();
Address
[]
flowDestinations
=
PcodeBlockData
.
instruction
.
getFlows
();
// Check whether there is only one flow, so the result is unambiguous
if
(
flowDestinations
.
length
==
1
)
{
if
(
flowDestinations
.
length
==
1
)
{
Address
flow
=
flowDestinations
[
0
];
Address
flow
=
flowDestinations
[
0
];
if
(
functionEntryPoints
.
containsKey
(
flow
.
toString
())){
// Check if the flow target is in the entry points map
// In case a jump to an external address occured, check for fuction pointer
// This has to be done in case the parsed target address points
Function
external
=
funcMan
.
getFunctionAt
(
flow
);
// to a location in a jump table
if
(
flow
.
isExternalAddress
())
{
if
(
functionEntryPoints
.
containsKey
(
flow
.
toString
()))
{
return
handleCallToFunctionPointer
(
flow
,
external
);
return
functionEntryPoints
.
get
(
flow
.
toString
());
}
else
{
}
return
functionEntryPoints
.
get
(
flow
.
toString
());
// In some cases indirect calls do not follow addresses directly but contents of registers
}
if
(
targetAddress
==
null
)
{
return
null
;
}
// If the flow points to an external address, the earlier parsed address
// from the pcodeOp is most likely a function pointer which will be added
// to the entry points map for later calls.
// Also, since the function pointer address is not already in the entry points map
// the sub TID of the corresponding external symbol will be swapped with the function
// pointer address.
if
(
flow
.
isExternalAddress
())
{
return
updateExternalSymbolLocations
(
flow
,
targetAddress
);
}
}
}
}
...
@@ -1079,42 +1095,35 @@ public class PcodeExtractor extends GhidraScript {
...
@@ -1079,42 +1095,35 @@ public class PcodeExtractor extends GhidraScript {
/**
/**
*
*
* @param flow:
Flow address of indirect call
* @param flow:
flow from instruction to target
* @
return: target tid of external symbol
* @
param targetAddress: address of target
*
*
* Tries to parse the function pointer address and if the external symbol TID
* Adds function pointer address to external symbol and updates the 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
)
{
protected
Tid
updateExternalSymbolLocations
(
Address
flow
,
String
targetAddress
)
{
Address
funcPointer
=
parseFunctionPointerAddress
();
Function
external
=
funcMan
.
getFunctionAt
(
flow
);
Tid
targetTid
=
null
;
ExternSymbol
symbol
=
externalSymbolMap
.
get
(
external
.
getName
());
if
(
funcPointer
!=
null
&&
externalSymbolMap
.
containsKey
(
external
.
getName
()))
{
symbol
.
getAddresses
().
add
(
targetAddress
);
ExternSymbol
symbol
=
externalSymbolMap
.
get
(
external
.
getName
());
if
(
symbol
.
getTid
().
getId
().
startsWith
(
"sub_EXTERNAL"
))
{
if
(
symbol
.
getTid
().
getId
().
startsWith
(
"sub_EXTERNAL"
))
{
Tid
targetTid
=
new
Tid
(
String
.
format
(
"sub_%s"
,
targetAddress
),
targetAddress
);
targetTid
=
new
Tid
(
String
.
format
(
"sub_%s"
,
funcPointer
.
toString
()),
funcPointer
.
toString
());
functionEntryPoints
.
put
(
targetAddress
,
targetTid
);
symbol
.
setTid
(
targetTid
);
symbol
.
setTid
(
targetTid
);
}
else
{
return
targetTid
;
targetTid
=
symbol
.
getTid
();
}
symbol
.
getAddresses
().
add
(
funcPointer
.
toString
());
}
}
return
symbol
.
getTid
();
return
targetTid
;
}
}
/**
/**
*
*
* @return Address of function pointer
* @param op: call pcode operation
* @return: Address of function pointer
*
*
* Parses the function pointer address out of an
indirect
call instruction
* Parses the function pointer address out of an call instruction
*/
*/
protected
Address
parseFunctionPointerAddress
()
{
protected
String
parseCallTargetAddress
(
PcodeOp
op
)
{
for
(
PcodeOp
op
:
PcodeBlockData
.
ops
)
{
if
(
op
.
getInput
(
0
).
isAddress
())
{
if
(
op
.
getOpcode
()
==
PcodeOp
.
CALLIND
&&
op
.
getInput
(
0
).
isAddress
())
{
return
op
.
getInput
(
0
).
getAddress
().
toString
();
return
op
.
getInput
(
0
).
getAddress
();
}
}
}
return
null
;
return
null
;
}
}
...
...
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