4 |
5 | GhidraQuark bridges Quark Engine into Ghidra.
6 |
7 | Fire a Quark analysis or inspect program behaviors with Quark report. Work with Quark and Ghidra all at once!
8 |
9 | ## Demo
10 |
11 | [](https://www.youtube.com/watch?v=VXzfFB2S4bo&ab_channel=JunWeiSong)
12 |
13 | ## Installing the extension
14 |
15 | + Download the built extension from GitHub
16 | + Visit the Releases page, normally use the latest release
17 | + Download the built extension zip file `ghidra_9.2.2_PUBLIC_20210204_QuarkEngineHelper`
18 | + If you don't already have Ghdira, download and install Ghidra from https://ghidra-sre.org/
19 | + Install the extension into Ghidra
20 | + Start Ghidra
21 | + Open `File->Install Extensions...`
22 | + Press the `+` icon found in the top right of the `Install Extensions` window
23 | + Navigate to the file location where you downloaded the extension zip file above and select it
24 | + Press `OK`
25 | + You may want to restart Ghidra for the changes to take effect
26 | + Enjoy it!
27 |
28 | ## Building extension from the command line
29 |
30 | + Install Gradle
31 |
32 | + Execute the following commands
33 |
34 | ```
35 | $ gradle -PGHIDRA_INSTALL_DIR=
36 | ```
37 |
38 | + Zip file will be created in the `dist` folder
39 |
40 | ## Resources
41 |
42 | ### Ghidra
43 |
44 | + https://ghidra.re/online-courses/
45 | + https://ghidra.re/ghidra_docs/api/
46 | + https://github.com/edmcman/ghidra-scala-loader
47 |
48 | ---
49 |
50 | Don't forget to take a glance at our [Quark-Engine](https://github.com/quark-engine/quark-engine) GitHub page :)
51 |
--------------------------------------------------------------------------------
/bin/README.txt:
--------------------------------------------------------------------------------
1 | Java source directory to hold module-specific Ghidra scripts.
2 |
--------------------------------------------------------------------------------
/bin/help/TOC_Source.xml:
--------------------------------------------------------------------------------
1 |
2 |
49 |
50 |
51 |
52 |
57 |
58 |
--------------------------------------------------------------------------------
/bin/help/shared/Frontpage.css:
--------------------------------------------------------------------------------
1 | /* ###
2 | * IP: GHIDRA
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | /*
17 | WARNING!
18 | This file is copied to all help directories. If you change this file, you must copy it
19 | to each src/main/help/help/shared directory.
20 |
21 |
22 | Java Help Note: JavaHelp does not accept sizes (like in 'margin-top') in anything but
23 | px (pixel) or with no type marking.
24 |
25 | */
26 |
27 | body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 10px; } /* some padding to improve readability */
28 | li { font-family:times new roman; font-size:14pt; }
29 | h1 { color:#000080; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; }
30 | h2 { margin: 10px; margin-top: 20px; color:#984c4c; font-family:times new roman; font-size:18pt; font-weight:bold; }
31 | h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; `font-size:14pt; font-weight:bold; }
32 | h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; }
33 |
34 | /*
35 | P tag code. Most of the help files nest P tags inside of blockquote tags (the was the
36 | way it had been done in the beginning). The net effect is that the text is indented. In
37 | modern HTML we would use CSS to do this. We need to support the Ghidra P tags, nested in
38 | blockquote tags, as well as naked P tags. The following two lines accomplish this. Note
39 | that the 'blockquote p' definition will inherit from the first 'p' definition.
40 | */
41 | p { margin-left: 40px; font-family:times new roman; font-size:14pt; }
42 | blockquote p { margin-left: 10px; }
43 |
44 | p.providedbyplugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px }
45 | p.ProvidedByPlugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px }
46 | p.relatedtopic { color:#800080; margin-left: 10px; font-size:14pt; }
47 | p.RelatedTopic { color:#800080; margin-left: 10px; font-size:14pt; }
48 |
49 | /*
50 | We wish for a tables to have space between it and the preceding element, so that text
51 | is not too close to the top of the table. Also, nest the table a bit so that it is clear
52 | the table relates to the preceding text.
53 | */
54 | table { margin-left: 20px; margin-top: 10px; width: 80%;}
55 | td { font-family:times new roman; font-size:14pt; vertical-align: top; }
56 | th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; }
57 |
58 | /*
59 | Code-like formatting for things such as file system paths and proper names of classes,
60 | methods, etc. To apply this to a file path, use this syntax:
61 | ...
62 | */
63 | code { color: black; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
64 | code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
65 |
--------------------------------------------------------------------------------
/bin/help/topics/quarkenginehelper/help.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 | Skeleton Help File for a Module
13 |
14 |
15 |
16 |
17 |
Skeleton Help File for a Module
18 |
19 |
This is a simple skeleton help topic. For a better description of what should and should not
20 | go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your
21 | favorite help topic. In general, language modules do not have their own help topics.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Builds a Ghidra Extension for a given Ghidra installation.
2 | //
3 | // An absolute path to the Ghidra installation directory must be supplied either by setting the
4 | // GHIDRA_INSTALL_DIR environment variable or Gradle project property:
5 | //
6 | // > export GHIDRA_INSTALL_DIR=
7 | // > gradle
8 | //
9 | // or
10 | //
11 | // > gradle -PGHIDRA_INSTALL_DIR=
12 | //
13 | // Gradle should be invoked from the directory of the project to build. Please see the
14 | // application.gradle.version property in /Ghidra/application.properties
15 | // for the correction version of Gradle to use for the Ghidra installation you specify.
16 |
17 | //----------------------START "DO NOT MODIFY" SECTION------------------------------
18 | def ghidraInstallDir
19 |
20 | if (System.env.GHIDRA_INSTALL_DIR) {
21 | ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR
22 | }
23 | else if (project.hasProperty("GHIDRA_INSTALL_DIR")) {
24 | ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR")
25 | }
26 |
27 | if (ghidraInstallDir) {
28 | apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle"
29 | }
30 | else {
31 | throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
32 | }
33 | //----------------------END "DO NOT MODIFY" SECTION-------------------------------
34 |
--------------------------------------------------------------------------------
/data/README.txt:
--------------------------------------------------------------------------------
1 | The "data" directory is intended to hold data files that will be used by this module and will
2 | not end up in the .jar file, but will be present in the zip or tar file. Typically, data
3 | files are placed here rather than in the resources directory if the user may need to edit them.
4 |
5 | An optional data/languages directory can exist for the purpose of containing various Sleigh language
6 | specification files and importer opinion files.
7 |
8 | The data/buildLanguage.xml is used for building the contents of the data/languages directory.
9 |
10 | The skel language definition has been commented-out within the skel.ldefs file so that the
11 | skeleton language does not show-up within Ghidra.
12 |
13 | See the Sleigh language documentation (docs/languages/index.html) for details Sleigh language
14 | specification syntax.
15 |
--------------------------------------------------------------------------------
/extension.properties:
--------------------------------------------------------------------------------
1 | name=GhidraQuark
2 | description=Quark Engine integration.
3 | author=Quark-Engine
4 | createdOn=2020
5 | version=@extversion@
6 |
--------------------------------------------------------------------------------
/ghidra_scripts/README.txt:
--------------------------------------------------------------------------------
1 | Java source directory to hold module-specific Ghidra scripts.
2 |
--------------------------------------------------------------------------------
/lib/README.txt:
--------------------------------------------------------------------------------
1 | The "lib" directory is intended to hold Jar files which this module
2 | is dependent upon. This directory may be eliminated from a specific
3 | module if no other Jar files are needed.
4 |
--------------------------------------------------------------------------------
/os/linux64/README.txt:
--------------------------------------------------------------------------------
1 | The "os/linux64" directory is intended to hold Linux native binaries
2 | which this module is dependent upon. This directory may be eliminated for a specific
3 | module if native binaries are not provided for the corresponding platform.
4 |
--------------------------------------------------------------------------------
/os/osx64/README.txt:
--------------------------------------------------------------------------------
1 | The "os/osx64" directory is intended to hold macOS (OS X) native binaries
2 | which this module is dependent upon. This directory may be eliminated for a specific
3 | module if native binaries are not provided for the corresponding platform.
4 |
--------------------------------------------------------------------------------
/os/win64/README.txt:
--------------------------------------------------------------------------------
1 | The "os/win64" directory is intended to hold MS Windows native binaries (.exe)
2 | which this module is dependent upon. This directory may be eliminated for a specific
3 | module if native binaries are not provided for the corresponding platform.
4 |
--------------------------------------------------------------------------------
/src/main/help/help/TOC_Source.xml:
--------------------------------------------------------------------------------
1 |
2 |
49 |
50 |
51 |
52 |
57 |
58 |
--------------------------------------------------------------------------------
/src/main/help/help/shared/Frontpage.css:
--------------------------------------------------------------------------------
1 | /* ###
2 | * IP: GHIDRA
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | /*
17 | WARNING!
18 | This file is copied to all help directories. If you change this file, you must copy it
19 | to each src/main/help/help/shared directory.
20 |
21 |
22 | Java Help Note: JavaHelp does not accept sizes (like in 'margin-top') in anything but
23 | px (pixel) or with no type marking.
24 |
25 | */
26 |
27 | body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 10px; } /* some padding to improve readability */
28 | li { font-family:times new roman; font-size:14pt; }
29 | h1 { color:#000080; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; }
30 | h2 { margin: 10px; margin-top: 20px; color:#984c4c; font-family:times new roman; font-size:18pt; font-weight:bold; }
31 | h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; `font-size:14pt; font-weight:bold; }
32 | h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; }
33 |
34 | /*
35 | P tag code. Most of the help files nest P tags inside of blockquote tags (the was the
36 | way it had been done in the beginning). The net effect is that the text is indented. In
37 | modern HTML we would use CSS to do this. We need to support the Ghidra P tags, nested in
38 | blockquote tags, as well as naked P tags. The following two lines accomplish this. Note
39 | that the 'blockquote p' definition will inherit from the first 'p' definition.
40 | */
41 | p { margin-left: 40px; font-family:times new roman; font-size:14pt; }
42 | blockquote p { margin-left: 10px; }
43 |
44 | p.providedbyplugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px }
45 | p.ProvidedByPlugin { color:#7f7f7f; margin-left: 10px; font-size:14pt; margin-top:100px }
46 | p.relatedtopic { color:#800080; margin-left: 10px; font-size:14pt; }
47 | p.RelatedTopic { color:#800080; margin-left: 10px; font-size:14pt; }
48 |
49 | /*
50 | We wish for a tables to have space between it and the preceding element, so that text
51 | is not too close to the top of the table. Also, nest the table a bit so that it is clear
52 | the table relates to the preceding text.
53 | */
54 | table { margin-left: 20px; margin-top: 10px; width: 80%;}
55 | td { font-family:times new roman; font-size:14pt; vertical-align: top; }
56 | th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; }
57 |
58 | /*
59 | Code-like formatting for things such as file system paths and proper names of classes,
60 | methods, etc. To apply this to a file path, use this syntax:
61 | ...
62 | */
63 | code { color: black; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
64 | code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
65 |
--------------------------------------------------------------------------------
/src/main/help/help/topics/quarkenginehelper/help.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 | Skeleton Help File for a Module
13 |
14 |
15 |
16 |
17 |
Skeleton Help File for a Module
18 |
19 |
This is a simple skeleton help topic. For a better description of what should and should not
20 | go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your
21 | favorite help topic. In general, language modules do not have their own help topics.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/main/java/quarkenginehelper/CallQuarkTask.java:
--------------------------------------------------------------------------------
1 | package quarkenginehelper;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.util.Arrays;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | import ghidra.util.Msg;
10 | import ghidra.util.exception.CancelledException;
11 | import ghidra.util.task.Task;
12 | import ghidra.util.task.TaskMonitor;
13 |
14 | public final class CallQuarkTask extends Task {
15 |
16 | final String absoluteQuarkPath;
17 | final String absoluteDexPath;
18 | final String absoluteReportPath;
19 |
20 | CallQuarkTask(String quarkPath, String dexPath, String reportPath) {
21 | super("Quark-Engine launching", true, true, false);
22 |
23 | this.absoluteQuarkPath = quarkPath;
24 | this.absoluteDexPath = dexPath;
25 | this.absoluteReportPath = reportPath;
26 |
27 | Msg.debug(this, "QuarkPath:" + absoluteQuarkPath);
28 | Msg.debug(this, "DexPath :" + absoluteDexPath);
29 | Msg.debug(this, "ReportPath:" + absoluteReportPath);
30 | }
31 |
32 | @Override
33 | public void run(TaskMonitor monitor) throws CancelledException {
34 | monitor.setShowProgressValue(false);
35 |
36 | monitor.setMessage("Launching Quark-Engine");
37 |
38 | String[] commands = { absoluteQuarkPath, "-a", absoluteDexPath, "-o", absoluteReportPath };
39 | Process quark = null;
40 | try {
41 | quark = new ProcessBuilder().command(commands).redirectErrorStream(true).start();
42 | BufferedReader quarkStdOutNErr = new BufferedReader(new InputStreamReader(quark.getInputStream()));
43 |
44 | monitor.setMessage("Analyzing File");
45 | Msg.debug(this, "Executing Quark with following command: ");
46 | Msg.debug(this, Arrays.toString(commands));
47 | while (!quark.waitFor(1, TimeUnit.SECONDS)) {
48 | String line = null;
49 | while ((line = quarkStdOutNErr.readLine()) != null) {
50 | monitor.setMessage(line);
51 | Msg.debug(this, line);
52 |
53 | monitor.checkCanceled();
54 | }
55 | }
56 |
57 | } catch (IOException | InterruptedException e) {
58 | Msg.error(this, "Error on running Quark.", e);
59 | return;
60 |
61 | } catch (CancelledException e) {
62 | if (quark != null)
63 | quark.destroyForcibly();
64 | Msg.debug(this, "--Cancelled by User--");
65 | return;
66 |
67 | }
68 |
69 | Msg.debug(this, "--End of Output--");
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/quarkenginehelper/QuarkEnginePlugin.java:
--------------------------------------------------------------------------------
1 | /* ###
2 | * IP: GHIDRA
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package quarkenginehelper;
17 |
18 | import java.io.BufferedReader;
19 | import java.io.File;
20 | import java.io.IOException;
21 | import java.io.InputStreamReader;
22 | import java.nio.file.Path;
23 | import java.util.concurrent.TimeUnit;
24 |
25 | import javax.swing.ImageIcon;
26 |
27 | import docking.ActionContext;
28 | import docking.action.DockingAction;
29 | import docking.action.ToolBarData;
30 | import docking.widgets.filechooser.GhidraFileChooser;
31 | import docking.widgets.filechooser.GhidraFileChooserMode;
32 | import ghidra.app.ExamplesPluginPackage;
33 | import ghidra.app.plugin.PluginCategoryNames;
34 | import ghidra.app.plugin.ProgramPlugin;
35 | import ghidra.app.services.GoToService;
36 | import ghidra.framework.plugintool.PluginInfo;
37 | import ghidra.framework.plugintool.PluginTool;
38 | import ghidra.framework.plugintool.util.PluginStatus;
39 | import ghidra.program.model.listing.Program;
40 | import ghidra.util.Msg;
41 | import ghidra.util.filechooser.ExtensionFileFilter;
42 | import ghidra.util.task.Task;
43 | import ghidra.util.task.TaskListener;
44 | import resources.Icons;
45 | import resources.ResourceManager;
46 |
47 | /**
48 | * TODO: Provide class-level documentation that describes what this plugin does.
49 | */
50 | //@formatter:off
51 | @PluginInfo(
52 | status = PluginStatus.STABLE,
53 | packageName = ExamplesPluginPackage.NAME,
54 | category = PluginCategoryNames.ANALYSIS,
55 | servicesRequired = GoToService.class,
56 | shortDescription = "Quark Engine integration with Ghidra.",
57 | description = "A plugin bridges Quark Engine to Ghidra. Now you can view malware reports generated by Quark without switching! Of cause, launching Quark analysis directly in Ghidra is possible, too!"
58 | )
59 | //@formatter:on
60 | public class QuarkEnginePlugin extends ProgramPlugin implements TaskListener {
61 |
62 | private String absoluteQuarkPath;
63 |
64 | // User interfaces
65 | private SummaryProvider summaryProvider;
66 |
67 | // Service
68 | private GoToService goToService;
69 |
70 | private GhidraFileChooser chooser;
71 |
72 | private DockingAction launchQuark;
73 | private DockingAction openReport;
74 |
75 | final static String QUARK_GROUP = "Quark";
76 | final static ImageIcon ICON = ResourceManager.loadImage("images/quark-icon.png");
77 |
78 | public QuarkEnginePlugin(PluginTool tool) {
79 | super(tool, true, true);
80 |
81 | summaryProvider = new SummaryProvider(this);
82 | createActions();
83 | }
84 |
85 | private void initChooser() {
86 | if (chooser == null) {
87 | chooser = new GhidraFileChooser(tool.getActiveWindow());
88 |
89 | var filter = ExtensionFileFilter.forExtensions("Quark-Enging Report", "json");
90 | chooser.addFileFilter(filter);
91 | chooser.setSelectedFileFilter(filter);
92 |
93 | chooser.setFileSelectionMode(GhidraFileChooserMode.FILES_ONLY);
94 | chooser.setMultiSelectionEnabled(false);
95 | chooser.setTitle("Select Report to import");
96 | }
97 | }
98 |
99 | private String findQuarkPath() {
100 | int timeout = 2; // 2 seconds
101 | String command[] = { "where", "quark" };
102 |
103 | try {
104 | Process process = new ProcessBuilder().command(command).start();
105 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
106 |
107 | boolean exitInTime = process.waitFor(timeout, TimeUnit.SECONDS);
108 | if (exitInTime & process.exitValue() == 0)
109 | return reader.readLine();
110 |
111 | } catch (IOException | InterruptedException e) {
112 | return null;
113 | }
114 |
115 | return null;
116 | }
117 |
118 | boolean isSupportedFormat(Program newProgram) {
119 | return newProgram.getExecutableFormat().equals("Dalvik Executable (DEX)");
120 | }
121 |
122 | void callQuarkTask() {
123 |
124 | String absoluteDexPath = currentProgram.getExecutablePath();
125 | if (System.getProperty("os.name").startsWith("Windows")) {
126 | if (absoluteDexPath.startsWith("\\") || absoluteDexPath.startsWith("/"))
127 | absoluteDexPath = absoluteDexPath.substring(1);
128 | }
129 |
130 | File projectDir = currentProgram.getDomainFile().getProjectLocator().getProjectDir();
131 | String absoluteReportPath = Path.of(projectDir.getPath(), "QuarkReport.json").toString();
132 |
133 | Msg.info(this, "Activating Quark-Engine.");
134 | CallQuarkTask task = new CallQuarkTask(absoluteQuarkPath, absoluteDexPath, absoluteReportPath);
135 | task.addTaskListener(this);
136 |
137 | getTool().execute(task);
138 | }
139 |
140 | @Override
141 | public void init() {
142 | goToService = getTool().getService(GoToService.class);
143 | if (goToService == null) {
144 | Msg.warn(this, "Quark-Engine Plugin cannot find GoToService. Some features may disappear.");
145 | } else {
146 | summaryProvider.setGoToService(goToService);
147 | }
148 |
149 | absoluteQuarkPath = findQuarkPath();
150 | if (absoluteQuarkPath != null)
151 | Msg.debug(this, "Find Quark at: " + absoluteQuarkPath);
152 | else
153 | Msg.error(this, "Unable to find Quark. The plugin will not activate.");
154 | }
155 |
156 | private void createActions() {
157 | // Action for user to launch Quark
158 | launchQuark = new DockingAction("Launch Quark Analysis", getName()) {
159 | @Override
160 | public void actionPerformed(ActionContext context) {
161 | callQuarkTask();
162 | }
163 | };
164 | launchQuark.setToolBarData(new ToolBarData(ICON, null));
165 | launchQuark.setEnabled(false);
166 | launchQuark.markHelpUnnecessary();
167 | tool.addAction(launchQuark);
168 |
169 | // Action for user to open a Quark report.
170 | openReport = new DockingAction("Open a report", getName()) {
171 |
172 | @Override
173 | public void actionPerformed(ActionContext context) {
174 | initChooser();
175 | File selected = chooser.getSelectedFile();
176 | if (selected != null)
177 | summaryProvider.openFile(selected);
178 | }
179 |
180 | };
181 | openReport.setToolBarData(new ToolBarData(Icons.OPEN_FOLDER_ICON, null));
182 | openReport.setEnabled(false);
183 | openReport.markHelpUnnecessary();
184 | tool.addAction(openReport);
185 | }
186 |
187 | GoToService getGoToService() {
188 | return goToService;
189 | }
190 |
191 | @Override
192 | protected void programOpened(Program newProgram) {
193 | if (isSupportedFormat(newProgram)) {
194 | summaryProvider.setEnable(newProgram);
195 |
196 | launchQuark.setEnabled(true);
197 | openReport.setEnabled(true);
198 | }
199 |
200 | }
201 |
202 | @Override
203 | protected void programClosed(Program newProgram) {
204 | summaryProvider.setDisable();
205 |
206 | launchQuark.setEnabled(false);
207 | openReport.setEnabled(false);
208 | }
209 |
210 | @Override
211 | public void taskCompleted(Task task) {
212 | if (task instanceof CallQuarkTask) {
213 | Msg.info(this, "Analysis of Quark-Engine ended.");
214 |
215 | // Refresh Panel
216 | File jsonReport = new File(((CallQuarkTask) task).absoluteReportPath);
217 | summaryProvider.openFile(jsonReport);
218 | }
219 | }
220 |
221 | @Override
222 | public void taskCancelled(Task task) {
223 | // Do nothing
224 | }
225 |
226 | }
227 |
--------------------------------------------------------------------------------
/src/main/java/quarkenginehelper/QuarkReport.java:
--------------------------------------------------------------------------------
1 | package quarkenginehelper;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class QuarkReport {
7 | public String md5;
8 | public String filename;
9 | public double totalScore;
10 |
11 | public List crimes;
12 | public List nodes;
13 |
14 | public static class Crime {
15 | public String description;
16 | public double score;
17 | public double weight;
18 | public String confidence;
19 | public String[] permissions;
20 | public Method[] nativeAPI;
21 | }
22 |
23 | public static class Method {
24 | public final String className;
25 | public final String name;
26 | public final String descriptor;
27 |
28 | public Method(String className, String name, String descriptor) {
29 | super();
30 | this.className = className;
31 | this.name = name;
32 | this.descriptor = descriptor;
33 | }
34 | }
35 |
36 | public static class Node {
37 | public final Crime crime;
38 |
39 | public final Method location;
40 |
41 | public final byte[] firstInvocation;
42 | public final byte[] secondInvocation;
43 |
44 | public Node(Crime crime, Method location, byte[] firstInvocation, byte[] secondInvocation) {
45 | super();
46 | this.crime = crime;
47 | this.location = location;
48 | this.firstInvocation = firstInvocation;
49 | this.secondInvocation = secondInvocation;
50 | }
51 | }
52 |
53 | public QuarkReport() {
54 | crimes = new ArrayList();
55 | nodes = new ArrayList();
56 | }
57 | }
--------------------------------------------------------------------------------
/src/main/java/quarkenginehelper/ReportExporter.java:
--------------------------------------------------------------------------------
1 | /* ###
2 | * IP: GHIDRA
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package quarkenginehelper;
17 |
18 | import java.io.File;
19 | import java.io.IOException;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import ghidra.app.util.*;
24 | import ghidra.app.util.exporter.Exporter;
25 | import ghidra.app.util.exporter.ExporterException;
26 | import ghidra.framework.model.DomainObject;
27 | import ghidra.program.model.address.AddressSetView;
28 | import ghidra.util.task.TaskMonitor;
29 |
30 | /**
31 | * TODO: Provide class-level documentation that describes what this exporter
32 | * does.
33 | */
34 | public class ReportExporter extends Exporter {
35 |
36 | /**
37 | * Exporter constructor.
38 | */
39 | public ReportExporter() {
40 |
41 | // TODO: Name the exporter and associate a file extension with it
42 |
43 | super("Quark Engine Report Exporter", "Quark-Engine_Helper", null);
44 | }
45 |
46 | @Override
47 | public boolean export(File file, DomainObject domainObj, AddressSetView addrSet, TaskMonitor monitor)
48 | throws ExporterException, IOException {
49 |
50 | // TODO: Perform the export, and return true if it succeeded
51 |
52 | return false;
53 | }
54 |
55 | @Override
56 | public List