Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
s2fuzzer
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
文周繁
s2fuzzer
Commits
7681ccd6
Commit
7681ccd6
authored
Jul 02, 2025
by
文周繁
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:rename
parent
cc4fbcdd
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
462 additions
and
0 deletions
+462
-0
.gitignore
e9patch/ghidrascript/.gitignore
+0
-0
FunctionRef.java
e9patch/ghidrascript/src/FunctionRef.java
+0
-0
GhidraCustomScript.java
e9patch/ghidrascript/src/GhidraCustomScript.java
+462
-0
HelloIdeaGhidra.java
e9patch/ghidrascript/src/HelloIdeaGhidra.java
+0
-0
VarInfo.java
e9patch/ghidrascript/src/VarInfo.java
+0
-0
testghidra.iml
e9patch/ghidrascript/testghidra.iml
+0
-0
No files found.
e9patch/
testghidra
/.gitignore
→
e9patch/
ghidrascript
/.gitignore
View file @
7681ccd6
File moved
e9patch/
testghidra
/src/FunctionRef.java
→
e9patch/
ghidrascript
/src/FunctionRef.java
View file @
7681ccd6
File moved
e9patch/ghidrascript/src/GhidraCustomScript.java
0 → 100644
View file @
7681ccd6
//@author Kolmogorov
//@category test
//@keybinding
//@menupath
//@toolbar
import
ghidra.app.script.GhidraScript
;
import
ghidra.graph.GDirectedGraph
;
import
ghidra.graph.GraphFactory
;
import
ghidra.program.model.address.Address
;
import
ghidra.program.model.address.AddressSetView
;
import
ghidra.program.model.block.*
;
import
ghidra.program.model.block.graph.CodeBlockEdge
;
import
ghidra.program.model.block.graph.CodeBlockVertex
;
import
ghidra.program.model.data.DataType
;
import
ghidra.program.model.listing.*
;
import
ghidra.program.model.mem.MemoryBlock
;
import
ghidra.program.model.pcode.Varnode
;
import
ghidra.program.model.symbol.RefType
;
import
ghidra.program.model.symbol.Reference
;
import
ghidra.program.model.symbol.ReferenceManager
;
import
ghidra.program.model.symbol.Symbol
;
import
ghidra.util.exception.CancelledException
;
import
java.io.File
;
import
java.io.FileOutputStream
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.LinkedList
;
import
java.util.List
;
public
class
GhidraCustomScript
extends
GhidraScript
{
/*
* Creates a new control flow graph for a function
* Vertex: a Basic Block as CodeBlockVertex
* Edge: connection between basic blocks as CodeBlockEdge
* */
public
class
FunctionControlFlowGraph
{
protected
GDirectedGraph
<
CodeBlockVertex
,
CodeBlockEdge
>
cfg
;
protected
Function
function
;
protected
GDirectedGraph
<
CodeBlockVertex
,
CodeBlockEdge
>
createGraph
()
{
return
GraphFactory
.
createDirectedGraph
();
}
// Dummy constructor
public
FunctionControlFlowGraph
()
{
this
.
cfg
=
this
.
createGraph
();
}
// Creates a control flow graph for the input function
public
FunctionControlFlowGraph
(
Function
function
)
{
this
.
cfg
=
this
.
createGraph
();
this
.
function
=
function
;
BasicBlockModel
basicBlockModel
=
new
BasicBlockModel
(
currentProgram
);
AddressSetView
addrSet
=
function
.
getBody
();
try
{
CodeBlockIterator
codeBlockIter
=
basicBlockModel
.
getCodeBlocksContaining
(
addrSet
,
getMonitor
());
// go through each block and add the outgoing edges to the graph
while
(
codeBlockIter
.
hasNext
())
{
CodeBlock
block
=
codeBlockIter
.
next
();
CodeBlockReferenceIterator
dstBlocks
=
block
.
getDestinations
(
getMonitor
());
// using the CodeBlockReference to add each edge
while
(
dstBlocks
.
hasNext
())
{
this
.
addEdge
(
dstBlocks
.
next
());
}
}
}
catch
(
CancelledException
e
)
{
e
.
printStackTrace
();
throw
new
RuntimeException
(
e
);
}
}
/*
* Helper function to print a Vertex and its successors
*/
public
void
printVertex
(
CodeBlockVertex
codeBlockVertex
)
{
CodeBlock
blockInfo
=
codeBlockVertex
.
getCodeBlock
();
printf
(
"[+] Code Block Start Address: 0x%x\n"
,
blockInfo
.
getFirstStartAddress
().
getOffset
());
Collection
<
CodeBlockVertex
>
successors
=
cfg
.
getSuccessors
(
codeBlockVertex
);
for
(
CodeBlockVertex
cbv
:
successors
)
{
blockInfo
=
cbv
.
getCodeBlock
();
printf
(
"[-] ------> Successor Block at: 0x%x\n"
,
blockInfo
.
getFirstStartAddress
().
getOffset
());
}
}
/*
* Prints the edges of the CFG
*/
public
void
printEdges
()
{
printf
(
"[+] Printing Edges of the CFG:\n"
);
Collection
<
CodeBlockEdge
>
edges
=
cfg
.
getEdges
();
CodeBlock
blockFrom
,
blockTo
;
for
(
CodeBlockEdge
edge
:
edges
)
{
blockFrom
=
edge
.
getStart
().
getCodeBlock
();
blockTo
=
edge
.
getEnd
().
getCodeBlock
();
printf
(
"[-] 0x%x --> 0x%x\n"
,
blockFrom
.
getFirstStartAddress
().
getOffset
(),
blockTo
.
getFirstStartAddress
().
getOffset
());
}
}
/*
* Simple dumping of the CFG just for validation
*/
public
void
printFCFG
()
{
Address
entryPoint
=
this
.
function
.
getEntryPoint
();
BasicBlockModel
basicBlockModel
=
new
BasicBlockModel
(
currentProgram
);
printf
(
"[+] Printing CFG for function at:0x%x\n"
,
this
.
function
.
getEntryPoint
().
getOffset
());
try
{
CodeBlock
entryBlock
=
basicBlockModel
.
getCodeBlockAt
(
entryPoint
,
getMonitor
());
CodeBlockVertex
entryVertex
=
new
CodeBlockVertex
(
entryBlock
);
List
<
CodeBlockVertex
>
vertexBuffer
=
new
ArrayList
<
CodeBlockVertex
>();
vertexBuffer
.
add
(
entryVertex
);
int
i
=
0
;
while
(
i
<
vertexBuffer
.
size
())
{
this
.
printVertex
(
vertexBuffer
.
get
(
i
));
for
(
CodeBlockVertex
successor
:
cfg
.
getSuccessors
(
vertexBuffer
.
get
(
i
)))
{
if
(!
vertexBuffer
.
contains
(
successor
))
{
vertexBuffer
.
add
(
successor
);
}
}
i
++;
}
}
catch
(
CancelledException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
public
void
addEdge
(
CodeBlockReference
codeBlockRef
)
{
CodeBlockEdge
edge
=
new
CodeBlockEdge
(
new
CodeBlockVertex
(
codeBlockRef
.
getSourceBlock
()),
new
CodeBlockVertex
(
codeBlockRef
.
getDestinationBlock
()));
this
.
cfg
.
addEdge
(
edge
);
}
public
void
addEdge
(
CodeBlock
srcBlock
,
CodeBlock
dstBlock
)
{
CodeBlockEdge
edge
=
new
CodeBlockEdge
(
new
CodeBlockVertex
(
srcBlock
),
new
CodeBlockVertex
(
dstBlock
));
this
.
cfg
.
addEdge
(
edge
);
}
}
protected
void
run
()
throws
Exception
{
// hello
printf
(
"hello idea\n"
);
printf
(
"hello ghidra\n"
);
String
name
=
currentProgram
.
getName
();
Address
BaseAddr
=
currentProgram
.
getImageBase
();
MemoryBlock
[]
sections
=
currentProgram
.
getMemory
().
getBlocks
();
// getSection Information
LinkedList
<
MemoryBlock
>
pltsection
=
new
LinkedList
<
MemoryBlock
>();
for
(
MemoryBlock
section
:
sections
)
{
if
(
section
.
getName
().
matches
(
".plt.*"
))
{
printf
(
"Name:%s,addr:0x%x-0x%x,size:0x%x"
,
section
.
getName
(),
section
.
getStart
().
getOffset
(),
section
.
getEnd
().
getOffset
(),
section
.
getSize
());
pltsection
.
add
(
section
);
}
}
long
BaseOff
=
BaseAddr
.
getOffset
();
printf
(
"[*] name:%s\n"
,
name
);
printf
(
"[*] Base addr:0x%x\n"
,
BaseOff
);
// getFunctions
Listing
listing
=
currentProgram
.
getListing
();
long
funcOff
;
long
funcRetOff
=
0
;
LinkedList
<
String
>
funcNameList
=
new
LinkedList
<
String
>();
String
funcName
;
Address
Instraddr
;
String
Instroper
;
int
variable_len
;
int
stack_offset
=
0
;
int
prev_stack_offset
=
0
;
int
FirstUseOffset
;
Symbol
variableSymbol
;
Reference
[]
varReferences
;
FileOutputStream
LogfileWriter
=
new
FileOutputStream
(
"/home/hunter/Desktop/jhead-funcInfo.log"
);
FileOutputStream
LogVarWriter
=
new
FileOutputStream
(
"/home/hunter/Desktop/jhead-VarInfo.log"
);
FunctionIterator
functions
=
listing
.
getFunctions
(
true
);
//
int
RBPOpNum
=
0
;
int
RSPOpNum
=
0
;
int
BBNum
;
BasicBlockModel
basicBlockModel
=
new
BasicBlockModel
(
currentProgram
);
List
<
CodeBlock
>
CodeBlockBuffer
=
new
ArrayList
<
CodeBlock
>();
List
<
CodeBlock
>
FunCodeBlockBuffer
=
new
ArrayList
<
CodeBlock
>();
int
StateNum
=
0
,
LenNum
=
0
,
OtherNum
=
0
;
for
(
Function
function
:
functions
)
{
StateNum
=
0
;
LenNum
=
0
;
OtherNum
=
0
;
BBNum
=
0
;
funcOff
=
function
.
getEntryPoint
().
getOffset
()
-
BaseOff
;
funcName
=
function
.
getName
();
AddressSetView
addrSet
=
function
.
getBody
();
printf
(
"\n--------------------------%s @ 0x%x~0x%x--------------------\n"
,
funcName
,
addrSet
.
getMinAddress
().
getOffset
(),
addrSet
.
getMaxAddress
().
getOffset
());
int
j
=
0
;
boolean
skipflag
=
false
;
while
(
j
<
pltsection
.
size
())
{
if
(
pltsection
.
get
(
j
).
getStart
().
getOffset
()
<=
function
.
getEntryPoint
().
getOffset
()
&&
function
.
getEntryPoint
().
getOffset
()
<=
pltsection
.
get
(
j
).
getStart
().
getOffset
()
+
pltsection
.
get
(
j
).
getSize
())
{
printf
(
"function %s is in section:%s,we skip it\n"
,
funcName
,
pltsection
.
get
(
j
).
getName
());
skipflag
=
true
;
break
;
}
j
++;
}
if
(
skipflag
)
{
continue
;
}
if
(!
funcNameList
.
contains
(
funcName
))
{
funcNameList
.
add
(
funcName
);
String
record
=
"0x"
+
Integer
.
toHexString
((
int
)
funcOff
)
+
":"
+
funcName
+
"\n"
;
LogfileWriter
.
write
(
record
.
getBytes
());
}
// Control Flow Graph Recovery
// FunctionControlFlowGraph fcfg=new FunctionControlFlowGraph(function);
// fcfg.printFCFG();
// fcfg.printEdges();
// getBasicBlock Information
// get Basic Block information
// try
// {
// CodeBlockIterator codeBlockIter =basicBlockModel.getCodeBlocksContaining(addrSet,getMonitor());
// // go through each block and add the outgoing edges to the graph
// while(codeBlockIter.hasNext()){
// CodeBlock block=codeBlockIter.next();
// CodeBlockReferenceIterator dstBlocks=block.getDestinations(getMonitor());
// CodeBlockBuffer.add(block);
// FunCodeBlockBuffer.add(block); // local store
// BBNum++;
// }
// printf("[*] Basic Block is:%d",BBNum);
// }
// catch (CancelledException e)
// {
// e.printStackTrace();
// throw new RuntimeException(e);
// }
//
// int i=0;
// Address StartAddr,EndAddr;
// while(i<FunCodeBlockBuffer.size())
// {
// StartAddr=FunCodeBlockBuffer.get(i).getFirstStartAddress();
// InstructionIterator instructions = listing.getInstructions(StartAddr, true);
//
// if(i+1<FunCodeBlockBuffer.size())
// {
// EndAddr=FunCodeBlockBuffer.get(i+1).getFirstStartAddress();
// printf("[*] ------------------------------------------------------\n");
// for(Instruction instr:instructions)
// {
// Instraddr = instr.getAddress();
// if(instr.getAddress().getOffset() < EndAddr.getOffset()) // locate RET instruction
// {
// printf("[*] 0x%x:%s\n", Instraddr.getOffset(), instr);
// }
// else
// break;
// }
// }
// else {
// printf("[*] ------------------------------------------------------\n");
// for(Instruction instr:instructions)
// {
// Instraddr = instr.getAddress();
// if(addrSet.contains(instr.getAddress())) // locate RET instruction
// {
// printf("[*] 0x%x:%s\n", Instraddr.getOffset(), instr);
// }
// else
// break;
// }
// }
//
// i++;
// }
// FunCodeBlockBuffer.clear();
// variable analysis
Variable
[]
variables
=
function
.
getLocalVariables
();
if
(
variables
.
length
==
0
)
{
printf
(
"[*] function have zero variable\n"
);
printf
(
"[*] ------------------------------------------------------\n"
);
// print instr information
continue
;
}
else
{
printf
(
"[*] function have %d variable(s)\n"
,
variables
.
length
);
// Analysis instr to find Instrument Point
printf
(
"[*] ------------------------------------------------------\n"
);
// instruction analysis
InstructionIterator
instructions
=
listing
.
getInstructions
(
function
.
getEntryPoint
(),
true
);
for
(
Instruction
instr
:
instructions
)
{
Instraddr
=
instr
.
getAddress
();
Instroper
=
instr
.
getMnemonicString
();
printf
(
"[*] 0x%x:%s\n"
,
Instraddr
.
getOffset
(),
instr
);
Address
[]
flows
=
instr
.
getFlows
();
// for(Address flow:flows)
// {
// printf("[-] instr flows to:0x%x\n",flow.getOffset());
// }
if
(
flows
.
length
>=
1
)
{
//printf("[*] 0x%x:%s\n",Instraddr.getOffset(),instr);
printf
(
"[*] ------------------------------------------------------\n"
);
}
if
(
instr
.
toString
().
equals
(
"PUSH RBP"
)
&&
instr
.
getNext
().
toString
().
equals
(
"MOV RBP,RSP"
))
{
// printf("[*] 0x%x:%s\n",Instraddr.getOffset(),instr);
// funcOff=instr.getNext().getAddress().getOffset()-BaseOff;
printf
(
"[-] A standard way to Generate Stack Frame\n"
);
// printf("[-] update instrument point address from start addr 0x%x to 0x%x\n",function.getEntryPoint().getOffset()-BaseOff,funcOff);
}
if
(
instr
.
toString
().
contains
(
"SUB RSP"
))
{
// printf("[*] 0x%x:%s\n",Instraddr.getOffset(),instr);
printf
(
"[-] Adjust Stack Frame\n"
);
}
if
(!
addrSet
.
contains
(
Instraddr
))
// locate RET instruction
{
// printf("[*] 0x%x:%s\n",Instraddr.getOffset(),instr);
// funcRetOff=Instraddr.getOffset()-BaseOff;
funcRetOff
=
instr
.
getPrevious
().
getAddress
().
getOffset
()
-
BaseOff
;
//printf("[*] %s:[RET]\n",addr);
break
;
// function end
}
}
}
StackFrame
funcStackFrame
=
function
.
getStackFrame
();
int
ReturnAddr
=
funcStackFrame
.
getReturnAddressOffset
();
int
idex
=
0
;
int
varlen
=
0
;
int
inferLen
=
0
;
int
RefWNum
=
0
,
RefRNum
=
0
,
RefDNum
=
0
;
for
(
Variable
variable
:
variables
)
{
RefWNum
=
0
;
RefRNum
=
0
;
RefDNum
=
0
;
variable_len
=
variable
.
getLength
();
FirstUseOffset
=
variable
.
getFirstUseOffset
();
variableSymbol
=
variable
.
getSymbol
();
printf
(
"[*]-------------------------var[%d]:%s-----------------------\n"
,
idex
,
variable
.
getName
());
printf
(
"[*] varName: %s @ varlen is:%d\n"
,
variable
.
getName
(),
variable_len
);
printf
(
"[*] first use offset is:0x%x\n"
,
FirstUseOffset
);
if
(
variable
.
isStackVariable
())
{
// get name and stack offset
stack_offset
=
variable
.
getStackOffset
();
printf
(
"[*] stack offset:%d\n"
,
stack_offset
);
// DataType Info
DataType
varType
=
variable
.
getDataType
();
varlen
=
varType
.
getLength
();
printf
(
"[*] [type info]:%s @ [type len]:%d \n"
,
varType
.
getName
(),
varlen
);
// byte
if
(
idex
!=
0
)
// skip the first
{
inferLen
=
prev_stack_offset
-
stack_offset
;
if
(
inferLen
!=
variable_len
)
{
printf
(
"[*] inferred len is:%d bytes"
,
inferLen
);
}
}
prev_stack_offset
=
stack_offset
;
VariableStorage
varStore
=
variable
.
getVariableStorage
();
int
stackOff
=
varStore
.
getStackOffset
();
Varnode
firstVarnode
=
variable
.
getFirstStorageVarnode
();
int
size
=
firstVarnode
.
getSize
();
long
off
=
firstVarnode
.
getOffset
();
// get xref info
ReferenceManager
referenceManager
=
function
.
getProgram
().
getReferenceManager
();
varReferences
=
referenceManager
.
getReferencesTo
(
variable
);
for
(
Reference
varReference
:
varReferences
)
{
RefType
varefType
=
varReference
.
getReferenceType
();
Address
varFromAddr
=
varReference
.
getFromAddress
();
Address
varToAddr
=
varReference
.
getToAddress
();
printf
(
"[*] [ref addr]:0x%x @ [ref type]:%s\n"
,
varFromAddr
.
getOffset
()
-
BaseOff
,
varefType
.
getName
());
// analysis xref info
if
(
varefType
.
getName
().
equals
(
"WRITE"
))
{
RefWNum
++;
}
if
(
varefType
.
getName
().
equals
(
"READ"
))
{
RefRNum
++;
}
if
(
varefType
.
getName
().
equals
(
"DATA"
))
{
RefDNum
++;
}
}
printf
(
"[*] Refer Info: [W]:%d,[R]:%d,[D]:%d\n"
,
RefWNum
,
RefRNum
,
RefDNum
);
// judge if it should be record
if
(
inferLen
>=
16
)
{
LenNum
++;
if
((
RefWNum
>=
1
&&
RefDNum
>=
1
)
||
(
RefRNum
>=
1
&&
RefDNum
>=
1
)
||
(
RefWNum
>=
1
&&
RefRNum
>=
1
)
||
(
RefDNum
>=
2
))
{
printf
(
"[*] This var relate to state"
);
// write to varlog file funcName@funcOffset:VarStackOffset@VarSize
String
Varecord
=
"0x"
+
Integer
.
toHexString
((
int
)
funcOff
)
+
":"
+
funcName
+
"@"
+
"RET"
+
":"
+
"0x"
+
Integer
.
toHexString
((
int
)
funcRetOff
)
+
"@"
+
Integer
.
toString
(
stack_offset
)
+
":"
+
Integer
.
toString
(
inferLen
)
+
"\n"
;
StateNum
++;
LogVarWriter
.
write
(
Varecord
.
getBytes
());
// Record
}
else
{
printf
(
"[*] Ref type is not various\n"
);
}
}
else
{
OtherNum
++;
printf
(
"[*] not enough length\n"
);
}
}
idex
++;
}
// end variable
// analysis variable reference type
printf
(
"LenVar/Total:[%d/%d], StateVar/Total[%d/%d]:, StateVar/LenVar:[%d/%d]\n"
,
LenNum
,
idex
,
StateNum
,
idex
,
StateNum
,
LenNum
);
if
(
StateNum
>=
1
)
{
printf
(
"[*]******************[*]\n"
);
}
}
//end function
//printf("[*] Basic Block is:%d",CodeBlockBuffer.size());
LogfileWriter
.
close
();
LogVarWriter
.
close
();
}
}
e9patch/
testghidra
/src/HelloIdeaGhidra.java
→
e9patch/
ghidrascript
/src/HelloIdeaGhidra.java
View file @
7681ccd6
File moved
e9patch/
testghidra
/src/VarInfo.java
→
e9patch/
ghidrascript
/src/VarInfo.java
View file @
7681ccd6
File moved
e9patch/
testghidra
/testghidra.iml
→
e9patch/
ghidrascript
/testghidra.iml
View file @
7681ccd6
File moved
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