16
16
package ghidra .app .plugin .core .analysis ;
17
17
18
18
import java .io .*;
19
- import java .util .HashSet ;
20
- import java .util .List ;
21
- import java .util .Set ;
19
+ import java .util .*;
22
20
23
21
import generic .jar .ResourceFile ;
24
22
import ghidra .app .cmd .function .CreateFunctionCmd ;
@@ -47,6 +45,7 @@ public class NoReturnFunctionAnalyzer extends AbstractAnalyzer {
47
45
private boolean createBookmarksEnabled = OPTION_DEFAULT_CREATE_BOOKMARKS_ENABLED ;
48
46
49
47
private Set <String > functionNames ;
48
+ private Set <String > wildcardFunctionNames ;
50
49
51
50
public NoReturnFunctionAnalyzer () {
52
51
super (NAME , DESCRIPTION , AnalyzerType .BYTE_ANALYZER );
@@ -91,67 +90,90 @@ public boolean added(Program program, AddressSetView set, TaskMonitor monitor, M
91
90
name = name .substring (startIndex );
92
91
}
93
92
94
- if (!functionNames .contains (name )) {
93
+ // check for exact match
94
+ if (functionNames .contains (name )) {
95
+ makeNoReturnFunction (program , symbol , monitor , log );
95
96
continue ;
96
97
}
97
98
98
- // skip noreturn marking if its namespace is not global, library, or std
99
- // it prevents class methods (e.g. Menu::_exit()) incorrectly marked as noreturn
100
- Namespace parentNamespace = symbol .getParentNamespace ();
101
- if (parentNamespace != null && !parentNamespace .isGlobal () && !parentNamespace .isLibrary ()) {
102
- List <String > pathList = parentNamespace .getPathList (true );
103
- if (!(pathList .size () == 1 && pathList .get (0 ) == "std" )) {
104
- continue ;
99
+ // if any wildcarded names, check for prefix match
100
+ for (String functionName : wildcardFunctionNames ) {
101
+ if (name .startsWith (functionName )) {
102
+ makeNoReturnFunction (program , symbol , monitor , log );
103
+ break ;
105
104
}
106
105
}
106
+ }
107
107
108
- // if this is an external entry place holder, create the function in the external entry location
109
- symbol = checkForAssociatedExternalSymbol (symbol );
110
-
111
- if (symbol .isExternal ()) {
112
- ExternalLocation externalLocation =
113
- program .getExternalManager ().getExternalLocation (symbol );
114
- if (externalLocation != null ) {
115
- Function functionAt = externalLocation .createFunction ();
116
- //Msg.debug(this,
117
- // "Setting \"no return\" flag on external function " + symbol.getName(true));
118
- functionAt .setNoReturn (true );
119
- }
120
- continue ;
108
+ // now that all the functions are set, safe to disassemble
109
+ // should not disassemble here, could be just a pointer, disassemble later
110
+ return true ;
111
+ }
112
+
113
+ /**
114
+ * Make the symbol into a non-returning function
115
+ *
116
+ * @param program program
117
+ * @param symbol symbol for a function
118
+ * @param monitor monitor
119
+ * @param log log for errors
120
+ */
121
+ private void makeNoReturnFunction (Program program , Symbol symbol , TaskMonitor monitor ,
122
+ MessageLog log ) {
123
+ // skip noreturn marking if its namespace is not global, library, or std
124
+ // it prevents class methods (e.g. Menu::_exit()) incorrectly marked as noreturn
125
+ Namespace parentNamespace = symbol .getParentNamespace ();
126
+ if (parentNamespace != null && !parentNamespace .isGlobal () &&
127
+ !parentNamespace .isLibrary ()) {
128
+ List <String > pathList = parentNamespace .getPathList (true );
129
+ if (!(pathList .size () == 1 && pathList .get (0 ) == "std" )) {
130
+ return ;
121
131
}
132
+ }
122
133
123
- Address address = symbol .getAddress ();
124
- if (symbol .getSymbolType () == SymbolType .LABEL ) {
125
- if (!SymbolType .FUNCTION .isValidParent (program , parentNamespace , address , false )) {
126
- continue ; // skip if parent does not permit function creation
127
- }
128
- CreateFunctionCmd fCommand = new CreateFunctionCmd (address );
129
- fCommand .applyTo (program , monitor );
134
+ // if this is an external entry place holder, create the function in the external entry location
135
+ symbol = checkForAssociatedExternalSymbol (symbol );
136
+
137
+ if (symbol .isExternal ()) {
138
+ ExternalLocation externalLocation =
139
+ program .getExternalManager ().getExternalLocation (symbol );
140
+ if (externalLocation != null ) {
141
+ Function functionAt = externalLocation .createFunction ();
142
+ //Msg.debug(this,
143
+ // "Setting \"no return\" flag on external function " + symbol.getName(true));
144
+ functionAt .setNoReturn (true );
130
145
}
146
+ return ;
147
+ }
131
148
132
- Function functionAt = program .getFunctionManager ().getFunctionAt (address );
133
- if (functionAt == null ) {
134
- log .appendMsg ("Failed to create \" no return\" function " + symbol .getName (true ) +
135
- " at " + address );
136
- continue ;
149
+ Address address = symbol .getAddress ();
150
+ if (symbol .getSymbolType () == SymbolType .LABEL ) {
151
+ if (!SymbolType .FUNCTION .isValidParent (program , parentNamespace , address , false )) {
152
+ return ; // skip if parent does not permit function creation
137
153
}
154
+ CreateFunctionCmd fCommand = new CreateFunctionCmd (address );
155
+ fCommand .applyTo (program , monitor );
156
+ }
138
157
139
- //Msg.debug(this, "Setting \"no return\" flag on function " + symbol.getName(true) +
140
- // " at " + address);
158
+ Function functionAt = program .getFunctionManager ().getFunctionAt (address );
159
+ if (functionAt == null ) {
160
+ log .appendMsg ("Failed to create \" no return\" function " + symbol .getName (true ) +
161
+ " at " + address );
162
+ return ;
163
+ }
141
164
142
- functionAt .setNoReturn (true );
165
+ //Msg.debug(this, "Setting \"no return\" flag on function " + symbol.getName(true) +
166
+ // " at " + address);
143
167
144
- // disassembled later after all bad functions have been marked
168
+ functionAt . setNoReturn ( true );
145
169
146
- if (createBookmarksEnabled ) {
147
- program .getBookmarkManager ().setBookmark (address , BookmarkType .ANALYSIS ,
148
- "Non-Returning Function" , "Non-Returning Function Identified" );
149
- }
150
- }
170
+ // disassembled later after all bad functions have been marked
151
171
152
- // now that all the functions are set, safe to disassemble
153
- // should not disassemble here, could be just a pointer, disassemble later
154
- return true ;
172
+ if (createBookmarksEnabled ) {
173
+ program .getBookmarkManager ()
174
+ .setBookmark (address , BookmarkType .ANALYSIS , "Non-Returning Function" ,
175
+ "Non-Returning Function Identified" );
176
+ }
155
177
}
156
178
157
179
/**
@@ -192,6 +214,7 @@ private void loadFunctionNamesIfNeeded(Program program)
192
214
}
193
215
194
216
functionNames = new HashSet <>();
217
+ wildcardFunctionNames = new HashSet <>();
195
218
196
219
ResourceFile [] files = NonReturningFunctionNames .findDataFiles (program );
197
220
for (ResourceFile file : files ) {
@@ -217,7 +240,16 @@ private void loadFunctionNamesIfNeeded(Program program)
217
240
"' specified in file: " + file .getAbsolutePath ());
218
241
line = line .substring (startIndex );
219
242
}
220
- functionNames .add (line .trim ());
243
+
244
+ String funcName = line .trim ();
245
+ if (funcName .endsWith ("*" )) {
246
+ // if funcName has a wildcard at the end, put on wildcard list
247
+ funcName = funcName .substring (0 , funcName .length () - 1 );
248
+ wildcardFunctionNames .add (funcName );
249
+ }
250
+ else {
251
+ functionNames .add (funcName );
252
+ }
221
253
}
222
254
}
223
255
finally {
0 commit comments