44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
7- *
7+ *
88 * http://www.apache.org/licenses/LICENSE-2.0
9- *
9+ *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1212 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -64,10 +64,11 @@ public class BinarySimilarityPlugin extends ProgramPlugin {
6464 private final AIDecompilationdWindow decompiledWindow ;
6565 private final SimilarFunctionsWindow similarFunctionsWindow ;
6666
67- private GhidraRevengService apiService ;
68-
6967 public final static String REVENG_AI_NAMESPACE = "RevEng.AI" ;
7068
69+ private GhidraRevengService getApiService () {
70+ return tool .getService (GhidraRevengService .class );
71+ }
7172
7273 @ Override
7374 protected void locationChanged (ProgramLocation loc ) {
@@ -78,6 +79,11 @@ protected void locationChanged(ProgramLocation loc) {
7879 return ;
7980 }
8081
82+ var apiService = getApiService ();
83+ if (apiService == null ) {
84+ return ;
85+ }
86+
8187 // If no program, or not attached to a complete analysis, do not trigger location change events
8288 var program = loc .getProgram ();
8389 if (program == null || apiService .getAnalysedProgram (program ).isEmpty ()) {
@@ -90,7 +96,7 @@ protected void locationChanged(ProgramLocation loc) {
9096
9197 /**
9298 * Plugin constructor.
93- *
99+ *
94100 * @param tool The plugin tool that this plugin is added to.
95101 */
96102 public BinarySimilarityPlugin (PluginTool tool ) {
@@ -110,19 +116,13 @@ public BinarySimilarityPlugin(PluginTool tool) {
110116 collectionsComponent .addToTool ();
111117 }
112118
113- /// In `init()` the services are guaranteed to be available
114- @ Override
115- public void init () {
116- super .init ();
117-
118- apiService = tool .getService (GhidraRevengService .class );
119- }
120-
121119 private void setupActions () {
122120 new ActionBuilder ("Auto Unstrip" , this .getName ())
123121 .menuGroup (ReaiPluginPackage .NAME )
124122 .menuPath (ReaiPluginPackage .MENU_GROUP_NAME , "Auto Unstrip" )
125123 .enabledWhen (context -> {
124+ var apiService = getApiService ();
125+ if (apiService == null ) return false ;
126126 var program = tool .getService (ProgramManager .class ).getCurrentProgram ();
127127 if (program != null ) {
128128 return apiService .getKnownProgram (program ).isPresent ();
@@ -132,6 +132,7 @@ private void setupActions() {
132132 }
133133 )
134134 .onAction (context -> {
135+ var apiService = getApiService ();
135136 var program = tool .getService (ProgramManager .class ).getCurrentProgram ();
136137 if (apiService .getAnalysedProgram (program ).isEmpty ()) {
137138 Msg .showError (this , null , ReaiPluginPackage .WINDOW_PREFIX + "Auto Unstrip" ,
@@ -155,6 +156,8 @@ private void setupActions() {
155156 .menuGroup (ReaiPluginPackage .NAME )
156157 .menuPath (ReaiPluginPackage .MENU_GROUP_NAME , "Function Matching" )
157158 .enabledWhen (context -> {
159+ var apiService = getApiService ();
160+ if (apiService == null ) return false ;
158161 var program = tool .getService (ProgramManager .class ).getCurrentProgram ();
159162 if (program != null ) {
160163 return apiService .getAnalysedProgram (program ).isPresent ();
@@ -164,6 +167,7 @@ private void setupActions() {
164167 }
165168 )
166169 .onAction (context -> {
170+ var apiService = getApiService ();
167171 var program = tool .getService (ProgramManager .class ).getCurrentProgram ();
168172 var knownProgram = apiService .getAnalysedProgram (program );
169173 if (knownProgram .isEmpty ()){
@@ -181,6 +185,8 @@ private void setupActions() {
181185 new ActionBuilder ("Match function" , this .getName ())
182186 .withContext (ProgramLocationActionContext .class )
183187 .enabledWhen (context -> {
188+ var apiService = getApiService ();
189+ if (apiService == null ) return false ;
184190 var func = context .getProgram ().getFunctionManager ().getFunctionContaining (context .getAddress ());
185191 return func != null
186192 // Exclude thunks and external functions because we do not support them in the portal
@@ -189,6 +195,7 @@ private void setupActions() {
189195 && apiService .getAnalysedProgram (context .getProgram ()).isPresent ();
190196 })
191197 .onAction (context -> {
198+ var apiService = getApiService ();
192199 // We know analysed program is present due to enabledWhen
193200 var knownProgram = apiService .getAnalysedProgram (context .getProgram ()).get ();
194201
@@ -206,6 +213,8 @@ private void setupActions() {
206213 new ActionBuilder ("AI Decompilation" , this .getName ())
207214 .withContext (ProgramLocationActionContext .class )
208215 .enabledWhen (context -> {
216+ var apiService = getApiService ();
217+ if (apiService == null ) return false ;
209218 var func = context .getProgram ().getFunctionManager ().getFunctionContaining (context .getAddress ());
210219 return func != null
211220 // Exclude thunks and external functions because we do not support them in the portal
@@ -214,6 +223,7 @@ private void setupActions() {
214223 && apiService .getAnalysedProgram (context .getProgram ()).isPresent ();
215224 })
216225 .onAction (context -> {
226+ var apiService = getApiService ();
217227 var func = context .getProgram ().getFunctionManager ().getFunctionContaining (context .getAddress ());
218228 var analysedProgram = apiService .getAnalysedProgram (context .getProgram ()).get ();
219229 var functionWithId = analysedProgram .getIDForFunction (func );
@@ -237,11 +247,14 @@ private void setupActions() {
237247 new ActionBuilder ("View function in portal" , this .getName ())
238248 .withContext (ProgramLocationActionContext .class )
239249 .enabledWhen (context -> {
250+ var apiService = getApiService ();
251+ if (apiService == null ) return false ;
240252 var func = context .getProgram ().getFunctionManager ().getFunctionContaining (context .getAddress ());
241253 return func != null
242254 && apiService .getAnalysedProgram (context .getProgram ()).isPresent ();
243255 })
244256 .onAction (context -> {
257+ var apiService = getApiService ();
245258 var func = context .getProgram ().getFunctionManager ().getFunctionContaining (context .getAddress ());
246259 var analysedProgram = apiService .getAnalysedProgram (context .getProgram ()).get ();
247260 var functionWithID = analysedProgram .getIDForFunction (func );
@@ -263,6 +276,8 @@ private void setupActions() {
263276
264277 @ Override
265278 public void readDataState (SaveState saveState ) {
279+ var apiService = getApiService ();
280+ if (apiService == null ) return ;
266281 int [] rawCollectionIDs = saveState .getInts ("collectionIDs" , new int [0 ]);
267282 var restoredCollections = Arrays .stream (rawCollectionIDs )
268283 .mapToObj (TypedApiInterface .CollectionID ::new )
@@ -273,6 +288,8 @@ public void readDataState(SaveState saveState) {
273288
274289 @ Override
275290 public void writeDataState (SaveState saveState ) {
291+ var apiService = getApiService ();
292+ if (apiService == null ) return ;
276293 int [] collectionIDs = apiService .getActiveCollections ().stream ().map (Collection ::collectionID ).mapToInt (TypedApiInterface .CollectionID ::id ).toArray ();
277294 saveState .putInts ("collectionIDs" , collectionIDs );
278295 }
0 commit comments