-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathGHIDRApy_FunctionStringAssociate.py
More file actions
134 lines (114 loc) · 4.15 KB
/
GHIDRApy_FunctionStringAssociate.py
File metadata and controls
134 lines (114 loc) · 4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# The script iterates through all the functions collecting all available strings in the function, and then sign their like a comment.
# @category: Strings
import ghidra.app.script.GhidraScript
import ghidra.program.model.data.StringDataType as StringDataType
import exceptions
class Node:
def __str__(self):
raise NotImplementedError("Must sub-class")
def indentedString(self):
raise NotImplementedError("")
def __str__(self):
return self.indentedString()
class ReferenceNode(Node):
def __init__(self, fromAddr, toAddr):
self.fromAddr = fromAddr
self.toAddr = toAddr
def indentedString(self, depth=0):
raise NotImplementedError("")
class StringNode(ReferenceNode):
def __init__(self, fromAddr, toAddr, string):
ReferenceNode.__init__(self, fromAddr, toAddr)
self.string = string
def __str__(self):
return self.indentedString()
def indentedString(self):
string = "%s\n" % ( self.string)
return string
def hasString(self):
return True
class FunctionNode(ReferenceNode):
def __init__(self, fromAddr, toAddr):
ReferenceNode.__init__(self, fromAddr, toAddr)
self.fn = getFunctionContaining(toAddr)
self.references = []
def hasString(self):
for r in self.references:
if isinstance(r, StringNode) or r.hasString():
return True
return False
def ReplaceStringTrash(self, str):
s = str.replace("\"", "")
s = s.replace("ds", "")
return s
def indentedString(self):
string = ""
for r in self.references:
if r.hasString():
string += "%s" % self.ReplaceStringTrash(r.indentedString())
return string
def getAddresses(self):
return self.fn.getBody().getAddresses(True)
def addReference(self, reference):
rlist = []
if not isinstance(reference, list):
rlist.append(reference)
for r in rlist:
if not isinstance(r, ReferenceNode):
raise ValueError("Must only add ReferenceNode type")
else:
self.references.append(r)
def getName(self):
if self.fn is not None:
return self.fn.getName()
else:
return "fun_%s" % (self.toAddr)
def process(self, processed=[]):
if self.fn is None:
return processed
print "Processing -> %s" % (str(self.toAddr))
if self.getName() in processed:
return processed
addresses = self.getAddresses()
while addresses.hasNext():
insn = getInstructionAt(addresses.next())
if insn is not None:
refs = getReferences(insn)
for r in refs:
self.addReference(r)
processed.append(self.getName())
for r in self.references:
if isinstance(r, FunctionNode):
processed = r.process(processed=processed)
return processed
def getStringAtAddr(addr):
"""Get string at an address, if present"""
data = getDataAt(addr)
if data and data.hasStringValue():
return data.getValue()
return None
def getStringReferences(insn):
"""Get strings referenced in any/all operands of an instruction, if present"""
numOperands = insn.getNumOperands()
found = []
for i in range(numOperands):
opRefs = insn.getOperandReferences(i)
for o in opRefs:
if o.getReferenceType().isData():
string = getStringAtAddr(o.getToAddress())
if string is not None:
found.append( StringNode(insn.getMinAddress(), o.getToAddress(), string) )
return found
def getReferences(insn):
refs = []
refs += getStringReferences(insn)
return refs
current_function = getFirstFunction()
while current_function is not None:
func = FunctionNode(None, current_function.getBody().getMinAddress())
func.process()
strings = func.indentedString()
print(strings)
if len(strings) >= 1:
current_function.setRepeatableComment(strings)
current_function = getFunctionAfter(current_function)