Skip to content

Commit 2b5aa01

Browse files
committed
implemented forgotten distinct builtin. added boundary check for goto builtin. various enhancements
1 parent 793ccda commit 2b5aa01

File tree

8 files changed

+79
-12
lines changed

8 files changed

+79
-12
lines changed

README.md

-2
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,6 @@ The following API documentations and their behaviors may change until reached fi
151151
| Description | Locates the current address selection by given offset. Real address value calculated by adding the offset value to the image base value. |
152152
| Aliases | None |
153153

154-
***Note***: *This built-in does not perform any boundary check for now. I have to implement strict boundary check for each executable sections. If you give a value that out of valid boundary, you may experience undefined behavior.*
155-
156154

157155

158156
**import(** *String* : filePathOrCoverageName **)**

extension.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name=@extname@
1+
name=Dragon Dance
22
description=Coverage data visualizer plugin.
33
author=Oguz Kartal
44
createdOn=

src/main/java/dragondance/Globals.java

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Globals {
1010
public static boolean EnableStdoutLog=false;
1111
public static boolean DumpInstructions=false;
1212

13+
public static String LastFileDialogPath="";
1314

1415
public static final float MIN_HUE = 190.0f;
1516
public static final float MAX_HUE = 360.0f;

src/main/java/dragondance/components/GuiAffectedOpInterface.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ public interface GuiAffectedOpInterface {
88
public CoverageData loadCoverage(String coverageDataFile) throws FileNotFoundException;
99
public boolean removeCoverage(int id);
1010
public boolean visualizeCoverage(CoverageData coverage);
11-
public void goTo(long offset);
11+
public boolean goTo(long offset);
1212
}

src/main/java/dragondance/components/MainDockProvider.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -732,8 +732,14 @@ public boolean visualizeCoverage(CoverageData coverage) {
732732
}
733733

734734
@Override
735-
public void goTo(long offset) {
736-
DragonHelper.goToAddress(DragonHelper.getImageBase().getOffset() + offset);
735+
public boolean goTo(long offset) {
736+
boolean success = DragonHelper.goToAddress(DragonHelper.getImageBase().getOffset() + offset);
737+
738+
if (!success) {
739+
DragonHelper.showWarning("offset 0x%x is not valid",offset);
740+
}
741+
742+
return success;
737743
}
738744

739745

src/main/java/dragondance/eng/DragonHelper.java

+40-6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import dragondance.Globals;
2323
import dragondance.StringResources;
2424
import dragondance.exceptions.InvalidInstructionAddress;
25+
import dragondance.util.Util;
2526
import generic.concurrent.GThreadPool;
2627
import generic.jar.ResourceFile;
2728
import ghidra.app.plugin.core.colorizer.ColorizingService;
@@ -217,13 +218,34 @@ public static void printConsole(String format, Object... args) {
217218

218219
}
219220

220-
public static void goToAddress(long addr) {
221+
public static boolean isValidExecutableSectionAddress(long addr) {
222+
if (addr < getImageBase().getOffset())
223+
return false;
224+
225+
if (addr >= getImageEnd().getOffset())
226+
return false;
227+
228+
return isCodeSectionAddress(addr);
229+
}
230+
231+
232+
public static boolean goToAddress(long addr) {
221233
GoToService gotoService = tool.getService(GoToService.class);
222234

223235
if (gotoService==null)
224-
return;
236+
return false;
237+
238+
if (!isValidExecutableSectionAddress(addr)) {
239+
showWarning("%x is not valid offset.",addr);
240+
return false;
241+
}
242+
243+
244+
if (getInstructionNoThrow(getAddress(addr),true) == null) {
245+
return false;
246+
}
225247

226-
gotoService.goTo(getAddress(addr));
248+
return gotoService.goTo(getAddress(addr));
227249
}
228250

229251
public static Address getAddress(long addrValue) {
@@ -233,9 +255,12 @@ public static Address getAddress(long addrValue) {
233255
public static String askFile(Component parent, String title, String okButtonText) {
234256

235257
GhidraFileChooser gfc = new GhidraFileChooser(parent);
236-
File def = new File("D:\\Tools\\coveragetools\\pintool");
237258

238-
gfc.setSelectedFile(def);
259+
if (!Globals.LastFileDialogPath.isEmpty()) {
260+
File def = new File(Globals.LastFileDialogPath);
261+
gfc.setSelectedFile(def);
262+
}
263+
239264
gfc.setTitle(title);
240265
gfc.setApproveButtonText(okButtonText);
241266
gfc.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
@@ -249,6 +274,11 @@ public static String askFile(Component parent, String title, String okButtonText
249274
if (!file.exists())
250275
return null;
251276

277+
Globals.LastFileDialogPath = Util.getDirectoryOfFile(file.getAbsolutePath());
278+
279+
if (Globals.LastFileDialogPath == null)
280+
Globals.LastFileDialogPath = System.getProperty("user.dir");
281+
252282
return file.getAbsolutePath();
253283
}
254284

@@ -275,6 +305,10 @@ public static Address getImageBase() {
275305
return fapi.getCurrentProgram().getImageBase();
276306
}
277307

308+
public static Address getImageEnd() {
309+
return fapi.getCurrentProgram().getMaxAddress();
310+
}
311+
278312
public static InstructionContext getInstruction(long addr, boolean throwEx) throws InvalidInstructionAddress {
279313
return getInstruction(fapi.toAddr(addr),throwEx);
280314
}
@@ -414,7 +448,7 @@ public static boolean isCodeSectionAddress(long addr) {
414448
List<MemoryBlock> execBlocks = getExecutableMemoryBlocks();
415449

416450
for (MemoryBlock mb : execBlocks) {
417-
if (addr >= mb.getStart().getOffset() && addr <= mb.getEnd().getOffset()) {
451+
if (addr >= mb.getStart().getOffset() && addr < mb.getEnd().getOffset()) {
418452
status=true;
419453
break;
420454
}

src/main/java/dragondance/scripting/functions/impl/BuiltinFunctionDistinct.java

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dragondance.scripting.functions.impl;
22

3+
import dragondance.datasource.CoverageData;
34
import dragondance.scripting.functions.BuiltinAlias;
45
import dragondance.scripting.functions.BuiltinFunctionBase;
56

@@ -9,5 +10,23 @@ public class BuiltinFunctionDistinct extends BuiltinFunctionBase {
910
public BuiltinFunctionDistinct() {
1011
super("distinct");
1112
}
13+
14+
@Override
15+
public int requiredArgCount(boolean minimum) {
16+
if (minimum)
17+
return 2;
18+
19+
return -1;
20+
}
21+
22+
@Override
23+
public CoverageData execute() {
24+
CoverageData[] finalArgs = prepareFinalArguments();
25+
26+
setReturn(CoverageData.distinct(finalArgs));
27+
28+
return super.execute();
29+
}
1230

31+
1332
}

src/main/java/dragondance/util/Util.java

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ public static String getObjectNameFromPath(String path) {
2222
return path.substring(p1+1, p2);
2323
}
2424

25+
public static String getDirectoryOfFile(String path) {
26+
File file = new File(path);
27+
28+
if (file.isDirectory())
29+
return file.getAbsolutePath();
30+
31+
return file.getParent();
32+
}
33+
2534
public static String md5(String sval) {
2635
return md5(sval.getBytes());
2736
}

0 commit comments

Comments
 (0)