Merge branch 'patch'

Conflicts:
	gradleScripts/distribution.gradle
This commit is contained in:
ghidra1 2019-04-25 17:32:19 -04:00
commit 1cae5552f6
23 changed files with 604 additions and 520 deletions

View file

@ -15,7 +15,29 @@
apply plugin: 'cpp'
apply plugin: 'c'
// Unclear if we can rely on the VisualCpp plugin to identify the correct Visual Studio paths
project.ext.VISUAL_STUDIO_BASE_DIR = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017"
project.ext.WINDOWS_KITS_DIR = "C:/Program Files (x86)/Windows Kits/10"
/****************************************************************************
* Method for extracting value from <name>=<value> pairs
****************************************************************************/
ext.getEnvironmentValue = { envLines, name ->
String assignment = name + "="
for (String line : envLines) {
if (line.startsWith(assignment)) {
String[] parts = line.split("=")
String value = parts[1].trim()
// remove trailing \ if present
if (value.endsWith("\\")) {
value = value.substring(0, value.length()-1)
}
return value
}
}
return null
}
// Ok, this is stupid, but mac and linux can't handle files paths that start with c:
// These paths are actually only used when running on windows, but the paths gets evaulated
@ -27,26 +49,31 @@ if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
if (!file(project.ext.VISUAL_STUDIO_INSTALL_DIR).exists()) {
project.ext.VISUAL_STUDIO_INSTALL_DIR = project.ext.VISUAL_STUDIO_BASE_DIR + "\\Community"
}
// TODO: Use of this will require coping with VC version in path
project.ext.WINDOWS_KITS_DIR = "C:/Program Files (x86)/Windows Kits/10.0"
println "Visual Studio Path: ${VISUAL_STUDIO_INSTALL_DIR}"
project.ext.VISUAL_STUDIO_VCVARS_CMD = "\"${VISUAL_STUDIO_INSTALL_DIR}\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x86_amd64"
// TODO: force VisualCpp installDir and windowsSdkDir
// NOTE: Windows 7 targeting requires the use of the Windows 8.1 SDK and setting the
// WINVER property a value of "0x0601" which may be specified to the compiler/linker.
// If using a VS Solution this must be specified within the project file(s).
project.ext.WINVER = "0x0601"
// Rely on vcvars script to supply SDK versions
def c = VISUAL_STUDIO_VCVARS_CMD + " && env"
String envText = c.execute().text
String[] envLines = c.execute().text.split("\n")
project.ext.MSVC_SDK_VERSION = getEnvironmentValue(envLines, "WINDOWSSDKVERSION")
println "Visual Studio SDK Version: ${MSVC_SDK_VERSION}"
project.ext.MSVC_TOOLS_VERSION = getEnvironmentValue(envLines, "VCTOOLSVERSION")
println "Visual Studio VCTools Version: ${MSVC_TOOLS_VERSION}"
}
else {
project.ext.VISUAL_STUDIO_INSTALL_DIR = "/"
project.ext.WINDOWS_KITS_DIR = "/"
project.ext.VISUAL_STUDIO_VCVARS_CMD = "NA"
project.ext.MSVC_SDK_VERSION = "?"
project.ext.MSVC_TOOLS_VERSION = "?"
}
/****************************************************************************
* Defines the platforms we have to support in Ghidra. This model is used
* for all native builds and should be extended by each module as-needed.

View file

@ -7,6 +7,49 @@
<BODY>
<H1 align="center">Ghidra 9.0.3 Change History (April 2019)</H1>
<blockquote><p><u>New Feature</u></p></blockquote>
<blockquote>
<ul>
<li><I>GUI.</I> Function tags are now viewable by function.</li>
</ul>
</blockquote>
<blockquote><p><u>Improvements</u></p></blockquote>
<blockquote>
<ul>
<li><I>Decompiler.</I> Improved modeling of CFG on Windows 10 (Thanks, Markus Pieton). (Issue #340)</li>
<li><I>Patcher.</I> Renamed patch directory to /Ghidra/patch and added README.txt that explains how the patch directory is used.</li>
<li><I>Search.</I> Fixed NullPointerException in Decompiler Data Type Reference Finder. (Issue #407)</li>
<li><I>Search.</I> Updated the Decompiler Data Type Finder to find references to inside of nested array access in a line of Decompiler C output. (Issue #416)</li>
</ul>
</blockquote>
<blockquote><p><u>Bugs</u></p></blockquote>
<blockquote>
<ul>
<li><I>Analysis.</I> Code that checks for thunks no longer throws an exception if the PC is not set for the processor.</li>
<li><I>Analysis.</I> Made a fix to enable Apply button when changing tool options. (Issue #40)</li>
<li><I>Data Types.</I> Fixed concurrent modification exception when replacing one datatype for another that results in some other datatype being renamed. </li>
<li><I>Decompiler.</I> Fixed dynamic variables and equates in 16-bit x86 programs. (Issue #336)</li>
<li><I>Decompiler:Java.</I> Fixed DEX decompilation regression issue. (Issue #350)</li>
<li><I>Eclipse Integration.</I> Fixed exception in Eclipse GhidraDev plugin that occurred when performing certain actions on a Ghidra project that was imported from a previously exported Archive File. (Issues #283, #383)</li>
<li><I>Importer.</I> Fixed an exception that occurred when batch importing APK files. (Issue #426)</li>
<li><I>Languages.</I> The 6502 Zero page indexed addressing has been corrected to only access the Zero page. (Issue #201)</li>
<li><I>Languages.</I> The 68000 BCD arithmetic instructions now have pcode semantics that allow disassembly to continue. (Issue #227)</li>
<li><I>Multi-User:Ghidra Server.</I> Restored ability to execute svrAdmin script in development mode. </li>
</ul>
</blockquote>
`
<li><I>
<H1 align="center">Ghidra 9.0.2 Change History (April 2019)</H1>
<blockquote><p><u>Bugs</u></p></blockquote>

View file

@ -33,6 +33,7 @@ import org.apache.commons.collections4.CollectionUtils;
import docking.options.editor.GenericOptionsComponent;
import docking.widgets.OptionDialog;
import docking.widgets.table.*;
import ghidra.GhidraOptions;
import ghidra.app.services.Analyzer;
import ghidra.framework.options.*;
import ghidra.program.model.listing.Program;
@ -465,20 +466,27 @@ class AnalysisPanel extends JPanel implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
checkForDifferences();
if (checkForDifferences()) {
propertyChangeListener.propertyChange(
new PropertyChangeEvent(this, GhidraOptions.APPLY_ENABLED, null, Boolean.TRUE));
}
}
private boolean checkForDifferences() {
boolean changes = false;
for (int i = 0; i < analyzerNames.size(); ++i) {
String analyzerName = analyzerNames.get(i);
boolean currEnabled = analyzerEnablement.get(i);
boolean origEnabled = analysisOptions.getBoolean(analyzerName, false);
if (currEnabled != origEnabled) {
changes = true;
propertyChangeListener.propertyChange(
new PropertyChangeEvent(this, analyzerName, origEnabled, currEnabled));
return true;
}
}
if (changes) {
return true;
}
for (EditorState info : editorList) {
if (info.isValueChanged()) {
return true;
@ -603,20 +611,17 @@ class AnalysisPanel extends JPanel implements PropertyChangeListener {
public void updateOptionForAllPrograms(String analyzerName, boolean enabled) {
for (Program program : programs) {
boolean commit = false;
int id = program.startTransaction("Setting analysis property");
try {
// Check to make sure we're only handling events that relate to analyzers. If we
// receive something else (eg: "analyze.apply") ignore it.
Options options = program.getOptions(Program.ANALYSIS_PROPERTIES);
// Sanity check to make sure that the analyzer is appropriate for
// this program. This should always be the case but it doesn't
// hurt to check.
if (!options.getOptionNames().contains(analyzerName)) {
continue;
}
boolean commit = false;
int id = program.startTransaction("Setting analysis property " + analyzerName);
try {
options.setBoolean(analyzerName, enabled);
commit = true;
}
finally {
@ -624,5 +629,4 @@ class AnalysisPanel extends JPanel implements PropertyChangeListener {
}
}
}
}

View file

@ -1,4 +1,5 @@
MODULE FILE LICENSE: lib/dex-ir-2.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/dexlib-1.4.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/dex-reader-2.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/dex-reader-api-2.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/dex-translator-2.0.jar Apache License 2.0
@ -7,3 +8,4 @@ MODULE FILE LICENSE: lib/baksmali-1.4.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/sevenzipjbinding-9.20-2.00beta.jar Apache License 2.0
MODULE FILE LICENSE: lib/sevenzipjbinding-all-platforms-9.20-2.00beta.jar Apache License 2.0
MODULE FILE LICENSE: lib/AXMLPrinter2.jar Apache License 2.0
MODULE FILE LICENSE: lib/util-1.4.0.jar BSD

View file

@ -20,7 +20,11 @@ dependencies {
compile ':dex-translator:2.0'
compile 'org.ow2.asm:asm-debug-all:4.1'
compile 'org.smali:baksmali:1.4.0' // TODO: Would like 1.4.2
compile 'org.smali:baksmali:1.4.0' // TODO: upgrade to 2.2.6
compile 'org.smali:dexlib:1.4.0'
compile 'org.smali:util:1.4.0'
compile 'net.sf.sevenzipjbinding:sevenzipjbinding:9.20-2.00beta'
compile ':AXMLPrinter2'

View file

@ -0,0 +1,403 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.server;
import java.io.*;
import java.util.ArrayList;
import java.util.Properties;
import javax.security.auth.x500.X500Principal;
import generic.jar.ResourceFile;
import ghidra.GhidraApplicationLayout;
import ghidra.GhidraLaunchable;
import ghidra.framework.Application;
import ghidra.framework.ApplicationConfiguration;
import ghidra.util.Msg;
import ghidra.util.NamingUtilities;
public class ServerAdmin implements GhidraLaunchable {
private static final String CONFIG_FILE_PROPERTY = "UserAdmin.config";
// property name defined within the sever.conf file which specifies
// server repositories directory
private static final String SERVER_DIR_CONFIG_PROPERTY = "ghidra.repositories.dir";
private static final String INVOCATION_NAME_PROPERTY = "UserAdmin.invocation";
// Immediate commands
private static final String LIST_COMMAND = "-list";
private static final String USERS_COMMAND = "-users";
// Delayed commands
private static final String MIGRATE_COMMAND = "-migrate";
private static final String MIGRATE_ALL_COMMAND = "-migrate-all";
private boolean propertyUsed = false;
/**
* Main method for launching the ServerAdmin Application via GhidraLauncher.
* The following properties may be set:
* <pre>
* UserAdmin.invocation - identifies the name of the application used when displaying usage text.
* UserAdmin.serverDir - identifies the server directory instead of passing on command line.
* </pre>
* @param args command line arguments
*/
@Override
public void launch(GhidraApplicationLayout layout, String[] args) {
// Perform static initializations if not already initialized
// Some tests invoke main method directly which have already initialized Application
if (!Application.isInitialized()) {
ApplicationConfiguration configuration = new ApplicationConfiguration();
configuration.setInitializeLogging(false);
Application.initializeApplication(layout, configuration);
}
execute(args);
}
/**
* Main method for processing ServerAdmin command line arguments.
* The following properties may be set:
* <pre>
* UserAdmin.invocation - identifies the name of the application used when displaying usage text.
* UserAdmin.serverDir - identifies the server directory instead of passing on command line.
* </pre>
* @param args command line arguments
*/
public void execute(String[] args) {
File serverDir = null;
int ix = 0;
if (args.length != 0 && !args[0].startsWith("-")) {
serverDir = new File(args[ix++]);
}
else {
serverDir = getServerDirFromConfig();
}
if (serverDir == null || (args.length - ix) == 0) {
displayUsage("");
System.exit(-1);
return;
}
try {
serverDir = serverDir.getCanonicalFile();
}
catch (IOException e1) {
System.err.println("Failed to resolve server directory: " + serverDir);
System.exit(-1);
}
if (propertyUsed) {
System.out.println("Using server directory: " + serverDir);
}
File userFile = new File(serverDir, UserManager.USER_PASSWORD_FILE);
if (!serverDir.isDirectory() || !userFile.isFile()) {
System.err.println("Invalid Ghidra server directory!");
System.exit(-1);
}
File cmdDir = new File(serverDir, UserAdmin.ADMIN_CMD_DIR);
if (!cmdDir.isDirectory() || !cmdDir.canWrite()) {
System.err.println("Insufficient privilege or server not started!");
System.exit(-1);
}
// Process command line
boolean listRepositories = false;
boolean listUsers = false;
boolean migrationConfirmed = false;
boolean migrationAbort = false;
ArrayList<String> cmdList = new ArrayList<>();
int cmdLen = 1;
for (; ix < args.length; ix += cmdLen) {
boolean queueCmd = true;
if (UserAdmin.ADD_USER_COMMAND.equals(args[ix])) { // add user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (UserAdmin.REMOVE_USER_COMMAND.equals(args[ix])) { // remove user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (UserAdmin.RESET_USER_COMMAND.equals(args[ix])) { // reset user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (UserAdmin.SET_USER_DN_COMMAND.equals(args[ix])) { // set/add user with DN for PKI
cmdLen = 3;
validateSID(args, ix + 1);
validateDN(args, ix + 2);
}
else if (UserAdmin.SET_ADMIN_COMMAND.equals(args[ix])) { // set/add repository admin
cmdLen = 3;
validateSID(args, ix + 1);
validateRepName(args, ix + 2, serverDir);
}
else if (LIST_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
listRepositories = true;
}
else if (USERS_COMMAND.equals(args[ix])) { // list users (also affects listRepositories)
cmdLen = 1;
queueCmd = false;
listUsers = true;
}
else if (MIGRATE_ALL_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
RepositoryManager.markAllRepositoriesForIndexMigration(serverDir);
}
}
else if (MIGRATE_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 2;
queueCmd = false;
if (ix == (args.length - 1)) {
System.err.println("Missing " + MIGRATE_COMMAND + " repository name argument");
}
else {
String repositoryName = args[ix + 1];
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
Repository.markRepositoryForIndexMigration(serverDir, repositoryName,
false);
}
}
}
else {
displayUsage("Invalid usage!");
System.exit(-1);
}
if (queueCmd) {
addCommand(cmdList, args, ix, cmdLen);
}
}
try {
UserAdmin.writeCommands(cmdList, cmdDir);
}
catch (IOException e) {
System.err.println("Failed to queue commands: " + e.toString());
System.exit(-1);
}
System.out.println(cmdList.size() + " command(s) queued.");
if (listUsers) {
UserManager.listUsers(serverDir);
}
if (listRepositories) {
RepositoryManager.listRepositories(serverDir, listUsers);
}
System.out.println();
}
/**
* @param serverDir
* @param args
* @param i
*/
private static void addCommand(ArrayList<String> cmdList, String[] args, int argOffset,
int argCnt) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < argCnt; i++) {
if (i > 0) {
buf.append(' ');
}
buf.append(args[argOffset + i]);
}
cmdList.add(buf.toString());
}
private static boolean confirmMigration() {
System.out.print("\nWARNING! Please confirm the requested migration of one or more\n" +
"Ghidra Server repositories. Once migrated to indexed storage,\n" +
"any attempt to use these server repositories with a Ghidra Server\n" +
"older than version 5.5 will corrupt the data storage.\n" +
"\nWould you like to continue? [y/n]: ");
try {
if ('y' == System.in.read()) {
System.out.println();
return true;
}
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("\nAll repository data migration(s) has been aborted.");
return false;
}
/**
* Validate properly formatted Distinguished Name
* Example: 'CN=Doe John, OU=X, OU=Y, OU=DoD, O=U.S. Government, C=US'
* @param args
* @param i argument index
*/
private void validateDN(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String dn = args[i];
try {
X500Principal x500User = new X500Principal(dn);
args[i] = "\"" + x500User.getName() + "\"";
}
catch (Exception e) {
Msg.error(UserAdmin.class, "Invalid DN: " + dn);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private void validateSID(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String sid = args[i];
if (!NamingUtilities.isValidName(sid) || sid.indexOf(' ') >= 0) {
Msg.error(UserAdmin.class, "Invalid username/sid: " + sid);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private void validateRepName(String[] args, int i, File rootDirFile) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String repName = args[i];
File f = new File(rootDirFile, NamingUtilities.mangle(repName));
if (!f.isDirectory()) {
Msg.error(UserAdmin.class, "Repository not found: " + repName);
System.exit(-1);
}
}
private File getServerDirFromConfig() {
String p = System.getProperty(CONFIG_FILE_PROPERTY);
if (p == null) {
return null;
}
propertyUsed = true;
File configFile = new File(p);
if (!configFile.exists()) {
System.out.println("Config file not found: " + configFile.getAbsolutePath());
}
Properties config = new Properties();
InputStream in = null;
try {
in = new FileInputStream(configFile);
config.load(in);
}
catch (IOException e) {
System.out.println("Failed to read " + configFile.getName() + ": " + e.getMessage());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// ignore
}
}
}
p = config.getProperty(SERVER_DIR_CONFIG_PROPERTY);
if (p == null) {
return null;
}
File dir = new File(p);
if (!dir.isAbsolute()) {
// Make relative repositories dir relative to installation root
ResourceFile installRoot = Application.getInstallationDirectory();
if (installRoot == null || installRoot.getFile(false) == null) {
System.out.println("Failed to resolve installation root directory!");
return null;
}
dir = new File(installRoot.getFile(false), p);
}
return dir;
}
/**
* Display an optional message followed by usage syntax.
* @param msg
*/
private void displayUsage(String msg) {
if (msg != null) {
System.err.println(msg);
}
String invocationName = System.getProperty(INVOCATION_NAME_PROPERTY);
System.err.println("Usage: " +
(invocationName != null ? invocationName : "java " + UserAdmin.class.getName()) +
(propertyUsed ? "" : " <serverPath>") + " [<command>] [<command>] ...");
System.err.println("\nSupported commands:");
System.err.println(" -add <sid>");
System.err.println(" Add a new user to the server identified by their sid identifier");
System.err.println(" -remove <sid>");
System.err.println(" Remove the specified user from the server's user list");
System.err.println(" -reset <sid>");
System.err.println(" Reset the specified user's server login password");
System.err.println(" -dn <sid> \"<dname>\"");
System.err.println(
" When PKI authentication is used, add the specified X500 Distinguished Name for a user");
System.err.println(" -admin <sid> \"<repository-name>\"");
System.err.println(
" Grant ADMIN privilege to the specified user with the specified repository");
System.err.println(" -list [-users]");
System.err.println(
" Output list of repositories to the console (user access list will be included with -users)");
System.err.println(" -users");
System.err.println(" Output list of users to console which have server access");
System.err.println(" -migrate \"<repository-name>\"");
System.err.println(
" Migrate the specified repository to the latest file system storage schema (see svrREADME.html)");
System.err.println(" -migrate-all");
System.err.println(
" Migrate the all repositories to the latest file system storage schema (see svrREADME.html)");
System.err.println();
}
}

View file

@ -23,15 +23,8 @@ import javax.security.auth.x500.X500Principal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import generic.jar.ResourceFile;
import ghidra.framework.Application;
import ghidra.framework.ApplicationConfiguration;
import ghidra.framework.store.local.LocalFileSystem;
import ghidra.server.remote.GhidraServerApplicationLayout;
import ghidra.util.Msg;
import ghidra.util.NamingUtilities;
import ghidra.util.exception.DuplicateNameException;
import utility.application.ApplicationLayout;
/**
* <code>UserAdmin</code> is an Application for generating administrative
@ -41,32 +34,15 @@ import utility.application.ApplicationLayout;
public class UserAdmin {
static final Logger log = LogManager.getLogger(UserAdmin.class);
private static final String INVOCATION_NAME_PROPERTY = "UserAdmin.invocation";
private static final String CONFIG_FILE_PROPERTY = "UserAdmin.config";
// property name defined within the sever.conf file which specifies
// server repositories directory
private static final String SERVER_DIR_CONFIG_PROPERTY = "ghidra.repositories.dir";
private static boolean propertyUsed = false;
// Queued commands
private static final String ADD_USER_COMMAND = "-add";
private static final String REMOVE_USER_COMMAND = "-remove";
private static final String RESET_USER_COMMAND = "-reset";
private static final String SET_USER_DN_COMMAND = "-dn";
private static final String SET_ADMIN_COMMAND = "-admin";
static final String ADD_USER_COMMAND = "-add";
static final String REMOVE_USER_COMMAND = "-remove";
static final String RESET_USER_COMMAND = "-reset";
static final String SET_USER_DN_COMMAND = "-dn";
static final String SET_ADMIN_COMMAND = "-admin";
// Immediate commands
private static final String LIST_COMMAND = "-list";
private static final String USERS_COMMAND = "-users";
// Delayed commands
private static final String MIGRATE_COMMAND = "-migrate";
private static final String MIGRATE_ALL_COMMAND = "-migrate-all";
private static final String ADMIN_CMD_DIR = LocalFileSystem.HIDDEN_DIR_PREFIX + "admin";
private static final String COMMAND_FILE_EXT = ".cmd";
static final String ADMIN_CMD_DIR = LocalFileSystem.HIDDEN_DIR_PREFIX + "admin";
static final String COMMAND_FILE_EXT = ".cmd";
/**
* Command file filter
@ -264,7 +240,7 @@ public class UserAdmin {
* @param cmdDir command file directory
* @throws IOException
*/
private static void writeCommands(ArrayList<String> cmdList, File cmdDir) throws IOException {
static void writeCommands(ArrayList<String> cmdList, File cmdDir) throws IOException {
File cmdFile = File.createTempFile("adm", ".tmp", cmdDir);
String cmdFilename = cmdFile.getName();
cmdFilename = cmdFilename.substring(0, cmdFilename.length() - 4) + COMMAND_FILE_EXT;
@ -289,346 +265,4 @@ public class UserAdmin {
}
}
/**
* Validate properly formatted Distinguished Name
* Example: 'CN=Doe John, OU=X, OU=Y, OU=DoD, O=U.S. Government, C=US'
* @param args
* @param i argument index
*/
private static void validateDN(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String dn = args[i];
try {
X500Principal x500User = new X500Principal(dn);
args[i] = "\"" + x500User.getName() + "\"";
}
catch (Exception e) {
Msg.error(UserAdmin.class, "Invalid DN: " + dn);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private static void validateSID(String[] args, int i) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String sid = args[i];
if (!NamingUtilities.isValidName(sid) || sid.indexOf(' ') >= 0) {
Msg.error(UserAdmin.class, "Invalid username/sid: " + sid);
System.exit(-1);
}
}
/**
* Validate username/sid
* @param args
* @param i argument index
*/
private static void validateRepName(String[] args, int i, File rootDirFile) {
if (args.length < (i + 1)) {
displayUsage("Invalid usage!");
System.exit(-1);
}
String repName = args[i];
File f = new File(rootDirFile, NamingUtilities.mangle(repName));
if (!f.isDirectory()) {
Msg.error(UserAdmin.class, "Repository not found: " + repName);
System.exit(-1);
}
}
/**
* @param serverDir
* @param args
* @param i
*/
private static void addCommand(ArrayList<String> cmdList, String[] args, int argOffset,
int argCnt) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < argCnt; i++) {
if (i > 0) {
buf.append(' ');
}
buf.append(args[argOffset + i]);
}
cmdList.add(buf.toString());
}
/**
* Display an optional message followed by usage syntax.
* @param msg
*/
private static void displayUsage(String msg) {
if (msg != null) {
System.err.println(msg);
}
String invocationName = System.getProperty(INVOCATION_NAME_PROPERTY);
System.err.println("Usage: " +
(invocationName != null ? invocationName : "java " + UserAdmin.class.getName()) +
(propertyUsed ? "" : " <serverPath>") + " [<command>] [<command>] ...");
System.err.println("\nSupported commands:");
System.err.println(" -add <sid>");
System.err.println(" Add a new user to the server identified by their sid identifier");
System.err.println(" -remove <sid>");
System.err.println(" Remove the specified user from the server's user list");
System.err.println(" -reset <sid>");
System.err.println(" Reset the specified user's server login password");
System.err.println(" -dn <sid> \"<dname>\"");
System.err.println(
" When PKI authentication is used, add the specified X500 Distinguished Name for a user");
System.err.println(" -admin <sid> \"<repository-name>\"");
System.err.println(
" Grant ADMIN privilege to the specified user with the specified repository");
System.err.println(" -list [-users]");
System.err.println(
" Output list of repositories to the console (user access list will be included with -users)");
System.err.println(" -users");
System.err.println(" Output list of users to console which have server access");
System.err.println(" -migrate \"<repository-name>\"");
System.err.println(
" Migrate the specified repository to the latest file system storage schema (see svrREADME.html)");
System.err.println(" -migrate-all");
System.err.println(
" Migrate the all repositories to the latest file system storage schema (see svrREADME.html)");
System.err.println();
}
private static File getServerDirFromConfig() {
String p = System.getProperty(CONFIG_FILE_PROPERTY);
if (p == null) {
return null;
}
propertyUsed = true;
File configFile = new File(p);
if (!configFile.exists()) {
System.out.println("Config file not found: " + configFile.getAbsolutePath());
}
Properties config = new Properties();
InputStream in = null;
try {
in = new FileInputStream(configFile);
config.load(in);
}
catch (IOException e) {
System.out.println("Failed to read " + configFile.getName() + ": " + e.getMessage());
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
// ignore
}
}
}
p = config.getProperty(SERVER_DIR_CONFIG_PROPERTY);
if (p == null) {
return null;
}
File dir = new File(p);
if (!dir.isAbsolute()) {
// Make relative repositories dir relative to installation root
ResourceFile installRoot = Application.getInstallationDirectory();
if (installRoot == null || installRoot.getFile(false) == null) {
System.out.println("Failed to resolve installation root directory!");
return null;
}
dir = new File(installRoot.getFile(false), p);
}
return dir;
}
/**
* Main method for running the UserAdmin Application.
* The following properties may be set:
* <pre>
* UserAdmin.invocation - identifies the name of the application used when displaying usage text.
* UserAdmin.serverDir - identifies the server directory instead of passing on command line.
* </pre>
* @param args command line arguments
*/
public static void main(String[] args) throws Exception {
// Perform static initializations if not already initialized
// Some tests invoke main method directly which have already initialized Application
if (!Application.isInitialized()) {
ApplicationLayout layout = new GhidraServerApplicationLayout();
ApplicationConfiguration configuration = new ApplicationConfiguration();
configuration.setInitializeLogging(false);
Application.initializeApplication(layout, configuration);
}
File serverDir = null;
int ix = 0;
if (args.length != 0 && !args[0].startsWith("-")) {
serverDir = new File(args[ix++]);
}
else {
serverDir = getServerDirFromConfig();
}
if (serverDir == null || (args.length - ix) == 0) {
displayUsage("");
System.exit(-1);
return;
}
try {
serverDir = serverDir.getCanonicalFile();
}
catch (IOException e1) {
System.err.println("Failed to resolve server directory: " + serverDir);
System.exit(-1);
}
if (propertyUsed) {
System.out.println("Using server directory: " + serverDir);
}
File userFile = new File(serverDir, UserManager.USER_PASSWORD_FILE);
if (!serverDir.isDirectory() || !userFile.isFile()) {
System.err.println("Invalid Ghidra server directory specified: " + serverDir);
System.exit(-1);
}
File cmdDir = new File(serverDir, ADMIN_CMD_DIR);
if (!cmdDir.exists()) {
System.err.println("Insufficient privilege or server not started.");
System.exit(-1);
}
if (!cmdDir.isDirectory()) {
System.err.println("Bad server directory: " + serverDir);
System.exit(-1);
}
// Process command line
boolean listRepositories = false;
boolean listUsers = false;
boolean migrationConfirmed = false;
boolean migrationAbort = false;
ArrayList<String> cmdList = new ArrayList<>();
int cmdLen = 1;
for (; ix < args.length; ix += cmdLen) {
boolean queueCmd = true;
if (ADD_USER_COMMAND.equals(args[ix])) { // add user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (REMOVE_USER_COMMAND.equals(args[ix])) { // remove user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (RESET_USER_COMMAND.equals(args[ix])) { // reset user
cmdLen = 2;
validateSID(args, ix + 1);
}
else if (SET_USER_DN_COMMAND.equals(args[ix])) { // set/add user with DN for PKI
cmdLen = 3;
validateSID(args, ix + 1);
validateDN(args, ix + 2);
}
else if (SET_ADMIN_COMMAND.equals(args[ix])) { // set/add repository admin
cmdLen = 3;
validateSID(args, ix + 1);
validateRepName(args, ix + 2, serverDir);
}
else if (LIST_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
listRepositories = true;
}
else if (USERS_COMMAND.equals(args[ix])) { // list users (also affects listRepositories)
cmdLen = 1;
queueCmd = false;
listUsers = true;
}
else if (MIGRATE_ALL_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 1;
queueCmd = false;
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
RepositoryManager.markAllRepositoriesForIndexMigration(serverDir);
}
}
else if (MIGRATE_COMMAND.equals(args[ix])) { // list repositories
cmdLen = 2;
queueCmd = false;
if (ix == (args.length - 1)) {
System.err.println("Missing " + MIGRATE_COMMAND + " repository name argument");
}
else {
String repositoryName = args[ix + 1];
if (!migrationConfirmed && !confirmMigration()) {
migrationAbort = true;
}
migrationConfirmed = true;
if (!migrationAbort) {
Repository.markRepositoryForIndexMigration(serverDir, repositoryName,
false);
}
}
}
else {
displayUsage("Invalid usage!");
System.exit(-1);
}
if (queueCmd) {
addCommand(cmdList, args, ix, cmdLen);
}
}
try {
writeCommands(cmdList, cmdDir);
}
catch (IOException e) {
System.err.println("Failed to queue commands: " + e.toString());
System.exit(-1);
}
System.out.println(cmdList.size() + " command(s) queued.");
if (listUsers) {
UserManager.listUsers(serverDir);
}
if (listRepositories) {
RepositoryManager.listRepositories(serverDir, listUsers);
}
System.out.println();
}
private static boolean confirmMigration() {
System.out.print("\nWARNING! Please confirm the requested migration of one or more\n" +
"Ghidra Server repositories. Once migrated to indexed storage,\n" +
"any attempt to use these server repositories with a Ghidra Server\n" +
"older than version 5.5 will corrupt the data storage.\n" +
"\nWould you like to continue? [y/n]: ");
try {
if ('y' == System.in.read()) {
System.out.println();
return true;
}
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("\nAll repository data migration(s) has been aborted.");
return false;
}
}

View file

@ -532,12 +532,17 @@ public class UserManager {
readUserList(userFile, list, lookupMap);
System.out.println("\nRepository Server Users:");
if (list.isEmpty()) {
System.out.println(" <No users have been added>");
}
else {
for (String name : list.keySet()) {
System.out.println(" " + name);
}
}
}
catch (IOException e) {
System.out.println("Failed to read user file: " + e.getMessage());
System.out.println("\nFailed to read user file: " + e.getMessage());
}
}

View file

@ -16,6 +16,13 @@ import DisplayParser, SemanticParser;
gDisplayParser.setLexer(lexer);
gSemanticParser.setLexer(lexer);
}
@Override
public void setEnv(ParsingEnvironment env) {
super.setEnv(env);
gDisplayParser.setEnv(env);
gSemanticParser.setEnv(env);
}
}
/**

View file

@ -1,30 +1,29 @@
#!/usr/bin/env bash
# ***********************************************************
# ** Arguments (each -argument option may be repeated):
# ** [-add <sid>] [-remove <sid>] [-reset <sid>] [-dn <sid> "<x500_distinguished_name>"]
# ** [-admin <sid> "<repository-name>"] [-list] [-migrate "<repository-name>"] [-migrate-all]
# ** [-add <sid>] [-dn <sid> "<x500_distinguished_name>"]
# ** [-remove <sid>]
# ** [-reset <sid>]
# ** [-admin <sid> "<repository-name>"]
# ** [-list] [-users]
# ** [-migrate "<repository-name>"] [-migrate-all]
# **
# ** add - add a new user to the server with the default password 'changeme'
# ** dn - set a user's distinguished name for PKI authentication
# ** remove - remove an existing user from the server
# ** reset - reset an existing user's password to 'changeme'
# ** dn - set a user's distinguished name for PKI authentication
# ** admin - set the specified existing user as an admin of the specified repository
# ** list - list all existing named repositories
# ** users - list all users or those associated with each listed repository
# ** migrate - migrate the specified named repository to an indexed data storage
# ** migrate-all - migrate all named repositories to index data storage
# ***********************************************************
UMASK=027
SUDO=sudo
# Preserve quoted arguments
ARGS=()
WHITESPACE="[[:space:]]"
for AA in "$@"; do
if [[ $AA =~ $WHITESPACE ]]; then
AA="\"$AA\""
fi
ARGS[${#ARGS[@]}]=$AA
done
# Maximum heap memory may be changed if default is inadequate. This will generally be up to 1/4 of
# the physical memory available to the OS. Uncomment MAXMEM setting if non-default value is needed.
MAXMEM=128M
# Resolve symbolic link if present and get the directory this script lives in.
# NOTE: "readlink -f" is best but works on Linux only, "readlink" will only work if your PWD
@ -34,49 +33,20 @@ SCRIPT_FILE="$(readlink -f "$0" 2>/dev/null || readlink "$0" 2>/dev/null || echo
SCRIPT_DIR="${SCRIPT_FILE%/*}"
if [ -d "${SCRIPT_DIR}/../Ghidra" ]; then
# Production Environment
CONFIG="${SCRIPT_DIR}/server.conf"
GHIDRA_DIR="${SCRIPT_DIR}/../Ghidra"
CPATH="${GHIDRA_DIR}/Features/GhidraServer/lib/GhidraServer.jar:${GHIDRA_DIR}/Framework/FileSystem/lib/FileSystem.jar:${GHIDRA_DIR}/Framework/DB/lib/DB.jar:${GHIDRA_DIR}/Framework/Generic/lib/Generic.jar:${GHIDRA_DIR}/Framework/Utility/lib/Utility.jar:${GHIDRA_DIR}/Framework/Generic/lib/log4j-core-2.8.1.jar:${GHIDRA_DIR}/Framework/Generic/lib/log4j-api-2.8.1.jar"
LS_CPATH="${GHIDRA_DIR}/../support/LaunchSupport.jar"
else
# Development Environment
CONFIG="${SCRIPT_DIR}/../../Common/server/server.conf"
GHIDRA_DIR="${SCRIPT_DIR}/../../.."
GHIDRA_BIN_REPO="${GHIDRA_DIR}/../../ghidra.bin"
CPATH="${GHIDRA_DIR}/Features/GhidraServer/bin/main:${GHIDRA_DIR}/Framework/FileSystem/bin/main:${GHIDRA_DIR}/Framework/DB/bin/main:${GHIDRA_DIR}/Framework/Generic/bin/main:${GHIDRA_DIR}/Framework/Utility/bin/main:${GHIDRA_BIN_REPO}/ExternalLibraries/libsForRuntime/log4j-core-2.8.1.jar:${GHIDRA_BIN_REPO}/ExternalLibraries/libsForRuntime/log4j-api-2.8.1.jar"
LS_CPATH="${GHIDRA_DIR}/../GhidraBuild/LaunchSupport/bin/main"
fi
# Make sure some kind of java is on the path. It's required to run the LaunchSupport program.
if ! [ -x "$(command -v java)" ] ; then
echo "Java runtime not found. Please refer to the Ghidra Installation Guide's Troubleshooting section."
exit 1
fi
# Get the java that will be used to launch GhidraServer
JAVA_HOME=$(java -cp "${LS_CPATH}" LaunchSupport "${GHIDRA_DIR}/.." -java_home)
if [ ! $? -eq 0 ]; then
echo "Failed to find a supported Java runtime. Please refer to the Ghidra Installation Guide's Troubleshooting section."
exit 1
fi
JAVA_CMD="${JAVA_HOME}/bin/java"
VMARGS="-DUserAdmin.invocation=$(basename "${SCRIPT_FILE}") -DUserAdmin.config=\"${CONFIG}\""
OLD_UMASK=$(umask)
umask $UMASK
# Identify server process owner if set within server.conf
OWNER="$(grep '^wrapper.app.account=' "${CONFIG}" | sed -e 's/^.*=\(.*\)\s*.*$/\1/')"
if [ -z "${OWNER}" -o "${OWNER}" = "$(whoami)" ]; then
eval "\"${JAVA_CMD}\" ${VMARGS} -cp \"${CPATH}\" ghidra.server.UserAdmin ${ARGS[@]}"
VMARGS="-DUserAdmin.invocation=$(basename "${SCRIPT_FILE}") -DUserAdmin.config=\"${CONFIG}\""
"${SCRIPT_DIR}"/../support/launch.sh fg svrAdmin "${MAXMEM}" "$VMARGS" ghidra.server.ServerAdmin "$@"
else
echo "Running svrAdmin with sudo as ${OWNER} ..."
eval "sudo -u "${OWNER}" \"${JAVA_CMD}\" ${VMARGS} -cp \"${CPATH}\" ghidra.server.UserAdmin ${ARGS[@]}"
echo "Running svrAdmin with $SUDO as ${OWNER} ..."
$SUDO -u $OWNER "$0" "${ARGS[@]}"
fi
umask $OLD_UMASK

View file

@ -1,22 +1,30 @@
@echo off
:: ***********************************************************
:: ** Arguments (each argument set may be repeated):
:: ** [-add <sid>] [-remove <sid>] [-reset <sid>] [-dn <sid> "<x500_distinguished_name>"]
:: ** [-admin <sid> "<repository-name>"] [-list] [-migrate "<repository-name>"] [-migrate-all]
:: ** Arguments (each -argument option may be repeated):
:: ** [-add <sid>] [-dn <sid> "<x500_distinguished_name>"]
:: ** [-remove <sid>]
:: ** [-reset <sid>]
:: ** [-admin <sid> "<repository-name>"]
:: ** [-list] [-users]
:: ** [-migrate "<repository-name>"] [-migrate-all]
:: **
:: ** add - add a new user to the server with the default password 'changeme'
:: ** dn - set a user's distinguished name for PKI authentication
:: ** remove - remove an existing user from the server
:: ** reset - reset an existing user's password to 'changeme'
:: ** dn - set a user's distinguished name for PKI authentication
:: ** admin - set the specified existing user as an admin of the specified repository
:: ** list - list all existing named repositories
:: ** users - list all users or those associated with each listed repository
:: ** migrate - migrate the specified named repository to an indexed data storage
:: ** migrate-all - migrate all named repositories to index data storage
:: ***********************************************************
setlocal
:: maximum heap memory may be change if inadequate
set MAXMEM=128M
:: Sets SCRIPT_DIR to the directory that contains this file
::
:: '% ~' dereferences the value in param 0
@ -24,51 +32,16 @@ setlocal
:: 'p' - path (without filename)
set SCRIPT_DIR=%~dp0
:: Uncomment and set the value below as necessary
:: set SCRIPT_DIR=<full Ghidra installation server directory path>
if not exist "%SCRIPT_DIR%" (
echo Unable to set the Ghidra server script directory.
echo.
echo To run Ghidra in this mode you must set the
echo value of SCRIPT_DIR in this file to be
echo the full path containing this batch file
goto :eof
)
:: Production Environment
set CONFIG=%SCRIPT_DIR%.\server.conf
set GHIDRA_DIR=%SCRIPT_DIR%..\Ghidra
set CPATH=%GHIDRA_DIR%\Features\GhidraServer\lib\GhidraServer.jar;%GHIDRA_DIR%\Framework\FileSystem\lib\FileSystem.jar;%GHIDRA_DIR%\Framework\DB\lib\DB.jar;%GHIDRA_DIR%\Framework\Generic\lib\Generic.jar;%GHIDRA_DIR%\Framework\Utility\lib\Utility.jar;%GHIDRA_DIR%\Framework\Generic\lib\log4j-core-2.8.1.jar;%GHIDRA_DIR%\Framework\Generic\lib\log4j-api-2.8.1.jar
set LS_CPATH=%GHIDRA_DIR%\..\support\LaunchSupport.jar
if exist "%GHIDRA_DIR%" goto continue
:: Development Environment - assumes suitable java in command path
:: Development Environment
set CONFIG=%SCRIPT_DIR%..\..\Common\server\server.conf
set GHIDRA_DIR=%SCRIPT_DIR%..\..\..
set GHIDRA_BIN_HOME=%GHIDRA_DIR%\..\..\ghidra.bin
set CPATH=%GHIDRA_DIR%\Features\GhidraServer\bin\main;%GHIDRA_DIR%\Framework\FileSystem\bin\main;%GHIDRA_DIR%\Framework\DB\bin\main;%GHIDRA_DIR%\Framework\Generic\bin\main;%GHIDRA_DIR%\Framework\Utility\bin\main;%GHIDRA_BIN_HOME%\ExternalLibraries\libsForRuntime\log4j-core-2.8.1.jar;%GHIDRA_BIN_HOME%\ExternalLibraries\libsForRuntime\log4j-api-2.8.1.jar
set LS_CPATH=%GHIDRA_DIR%\..\GhidraBuild\LaunchSupport\bin\main
:continue
:: Make sure some kind of java is on the path. It's required to run the LaunchSupport program.
java -version >nul 2>nul
if not %ERRORLEVEL% == 0 (
echo Java runtime not found. Please refer to the Ghidra Installation Guide's Troubleshooting section.
exit /B 1
)
set VMARGS=-DUserAdmin.invocation="%0" -DUserAdmin.config="%CONFIG%"
:: Get the java that will be used to launch GhidraServer
set JAVA_HOME=
for /f "delims=*" %%i in ('java -cp "%LS_CPATH%" LaunchSupport "%GHIDRA_DIR%\.." -java_home') do set JAVA_HOME=%%i
if "%JAVA_HOME%" == "" (
echo Failed to find a supported Java runtime. Please refer to the Ghidra Installation Guide's Troubleshooting section.
exit /B 1
)
set JAVA=%JAVA_HOME%\bin\java.exe
set VMARGS=-DUserAdmin.invocation="%0" -DUserAdmin.config="%CONFIG%" -Djava.net.preferIPv4Stack=true
"%JAVA%" %VMARGS% -cp "%CPATH%" ghidra.server.UserAdmin %*
call "%~dp0\..\support\launch.bat" fg svrAdmin "%MAXMEM%" "%VMARGS%" ghidra.server.ServerAdmin %*

View file

@ -10,31 +10,45 @@
@echo off
setlocal
if "%~1" == "" (
echo "Usage: createPdbXmlFiles.bat <path to .pdb file|path to directory of .pdb files>"
Exit /B 0
)
REM Get parent of current folder
for %%A in (%~dp0\.) do set ghidraPath=%%~dpA
set SCRIPT_DIR=%~dp0
set GHIDRA_DIR=%SCRIPT_DIR%..\Ghidra
set OS_DIR=os
REM Production Environment
if exist "%ghidraPath%Ghidra" goto continue
if exist "%GHIDRA_DIR%" goto continue
REM Development Environment
set ghidraPath="%ghidraPath%..\..\..\..\ghidra.bin\"
set GHIDRA_DIR=%SCRIPT_DIR%..\..\..
set OS_DIR=build\os
:continue
set arg1="%~1"
REM create absolute path
for /f %%i in ("%GHIDRA_DIR%") do set GHIDRA_DIR=%%~fi
REM Determine if 64-bit or 32-bit
if exist "%PROGRAMFILES(X86)%" (
set osType=win64
set OS_TYPE=win64
) else (
set osType=win32
set OS_TYPE=win32
)
set PDB_EXE=%GHIDRA_DIR%\Features\PDB\%OS_DIR%\%OS_TYPE%\pdb.exe
if not exist "%PDB_EXE%" (
echo "%PDB_EXE% not found"
Exit /B 1
)
if "%~1" == "" (
echo "Usage: createPdbXmlFiles.bat <path to .pdb file|path to directory of .pdb files>"
Exit /B 1
)
set arg1="%~1"
set /a count=0
REM Recursively traverse through the given directory
@ -50,7 +64,7 @@ for /f "tokens=* delims=" %%a in ('dir %arg1% /s /b') do (
setlocal enableDelayedExpansion
(
echo "Processing file: %%a"
START /B /WAIT "" "%ghidraPath%Ghidra\Features\PDB\os\%ostype%\pdb.exe" %%a > "%%a.xml"
START /B /WAIT "" "%PDB_EXE%" %%a > "%%a.xml"
REM Exit if executable returned non-zero error code (signifies that there is a problem).
if !errorlevel! neq 0 (
@ -63,7 +77,7 @@ for /f "tokens=* delims=" %%a in ('dir %arg1% /s /b') do (
echo Error detected. Exiting...
)
Exit /B 0
Exit /B 1
)
)

View file

@ -40,7 +40,7 @@ import ghidra.framework.store.local.LocalFileSystem;
import ghidra.framework.store.local.LocalFolderItem;
import ghidra.net.*;
import ghidra.program.model.listing.Program;
import ghidra.server.UserAdmin;
import ghidra.server.ServerAdmin;
import ghidra.server.UserManager;
import ghidra.test.ToyProgramBuilder;
import ghidra.util.*;
@ -942,11 +942,12 @@ public class ServerTestUtil {
* @throws Exception
*/
public static void addPKIUser(File serverRoot, String userName, String dn) throws Exception {
ServerAdmin serverAdmin = new ServerAdmin();
if (dn != null) {
UserAdmin.main(new String[] { serverRoot.getAbsolutePath(), "-dn", userName, dn });
serverAdmin.execute(new String[] { serverRoot.getAbsolutePath(), "-dn", userName, dn });
}
else {
UserAdmin.main(new String[] { serverRoot.getAbsolutePath(), "-add", userName });
serverAdmin.execute(new String[] { serverRoot.getAbsolutePath(), "-add", userName });
}
}

View file

@ -1,3 +0,0 @@
Drop jar files in this directory to apply patches to an installation of Ghidra. Any jar files
found in this directory will be placed at the front of the classpath, allowing them to override
any existing classes in any module.

View file

@ -1,2 +0,0 @@
##VERSION: 2.0
README.txt||GHIDRA||||END|

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<site>
<feature url="features/ghidra.ghidradev_2.0.0.qualifier.jar" id="ghidra.ghidradev" version="2.0.0.qualifier">
<feature url="features/ghidra.ghidradev_2.0.1.qualifier.jar" id="ghidra.ghidradev" version="2.0.1.qualifier">
<category name="ghidra.ghidradev"/>
</feature>
<category-def name="ghidra.ghidradev" label="Ghidra"/>

View file

@ -2,7 +2,7 @@
<feature
id="ghidra.ghidradev"
label="GhidraDev"
version="2.0.0.qualifier"
version="2.0.1.qualifier"
provider-name="Ghidra">
<description>

View file

@ -19,7 +19,7 @@
<h1>GhidraDev README</h1>
<p>GhidraDev provides support for developing and debugging Ghidra scripts and modules in Eclipse.
</p>
<p>The information provided in this document is effective as of GhidraDev 2.0.0 and is subject to
<p>The information provided in this document is effective as of GhidraDev 2.0.1 and is subject to
change with future releases.</p>
<ul>
@ -53,7 +53,9 @@ change with future releases.</p>
</ul>
<h2><a name="ChangeHistory"></a>Change History</h2>
<p><u><b>2.0.0</b>:</u></p>
<p><u><b>2.0.1</b>:</u> Fixed exception that occurred when performing certain actions on a Ghidra
project that was imported from a previously exported Archive File.</p>
<p><u><b>2.0.0</b>:</u>
<ul>
<li>
Improved Ghidra module project starting templates for Analyzer and Plugin and added new

View file

@ -3,7 +3,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: GhidraDev
Bundle-SymbolicName: ghidra.ghidradev;singleton:=true
Bundle-Version: 2.0.0.qualifier
Bundle-Version: 2.0.1.qualifier
Bundle-Activator: ghidradev.Activator
Require-Bundle: org.eclipse.ant.core;bundle-version="3.5.200",
org.eclipse.buildship.core;bundle-version="3.0.0",

View file

@ -222,7 +222,7 @@ public class GhidraModuleUtils {
}
File ghidraInstallDir = ghidraLayout.getApplicationInstallationDir().getFile(false);
File antFile = new File(project.getRawLocation().toFile(), ".antProperties.xml"); // hidden
File antFile = new File(project.getLocation().toFile(), ".antProperties.xml"); // hidden
try (PrintWriter writer = new PrintWriter(new FileWriter(antFile))) {
writer.println(

View file

@ -352,7 +352,7 @@ public class GhidraProjectUtils {
IFolder ghidraFolder =
javaProject.getProject().getFolder(GhidraProjectUtils.GHIDRA_FOLDER_NAME);
IPath oldGhidraInstallPath = ghidraFolder.exists()
? new Path(ghidraFolder.getRawLocation().toFile().getAbsolutePath())
? new Path(ghidraFolder.getLocation().toFile().getAbsolutePath())
: null;
// Loop through the project's existing classpath to decide what to keep (things that aren't

View file

@ -111,7 +111,7 @@ public class ExportGhidraModuleWizard extends Wizard implements INewWizard {
// Get path to Ghidra installation directory
String ghidraInstallDirPath = project.getFolder(
GhidraProjectUtils.GHIDRA_FOLDER_NAME).getRawLocation().toOSString();
GhidraProjectUtils.GHIDRA_FOLDER_NAME).getLocation().toOSString();
// Get project's java. Gradle should use the same version.
// TODO: It's more correct to get this from the project's classpath, since Ghidra's
@ -126,7 +126,7 @@ public class ExportGhidraModuleWizard extends Wizard implements INewWizard {
// Setup the Gradle build attributes
List<String> tasks = new ArrayList<>();
String workingDir = project.getRawLocation().toOSString();
String workingDir = project.getLocation().toOSString();
String gradleDist = gradleDistribution.toString();
String gradleUserHome = "";
String javaHome = javaHomeDir.getAbsolutePath();

View file

@ -144,7 +144,7 @@ public class ConfigureGradleWizardPage extends WizardPage {
if (visible) {
IProject project = projectPage.getGhidraModuleProject().getProject();
IFolder ghidraFolder = project.getFolder(GhidraProjectUtils.GHIDRA_FOLDER_NAME);
File ghidraDir = ghidraFolder.getRawLocation().toFile();
File ghidraDir = ghidraFolder.getLocation().toFile();
try {
GhidraApplicationLayout ghidraLayout = new GhidraApplicationLayout(ghidraDir);
ApplicationProperties props = ghidraLayout.getApplicationProperties();