diff --git a/GhidraPlugin/.classpath b/GhidraPlugin/.classpath new file mode 100644 index 00000000..9129dd77 --- /dev/null +++ b/GhidraPlugin/.classpath @@ -0,0 +1,741 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GhidraPlugin/.project b/GhidraPlugin/.project new file mode 100644 index 00000000..e328680c --- /dev/null +++ b/GhidraPlugin/.project @@ -0,0 +1,24 @@ + + + GhidraPlugin + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + + + Ghidra + 2 + C:/Projects/ghidra_11.3.2_PUBLIC + + + diff --git a/GhidraPlugin/.settings/org.eclipse.core.resources.prefs b/GhidraPlugin/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000..99f26c02 --- /dev/null +++ b/GhidraPlugin/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/GhidraPlugin/.settings/org.eclipse.jdt.core.prefs b/GhidraPlugin/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..70f925cd --- /dev/null +++ b/GhidraPlugin/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,47 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 +org.eclipse.jdt.core.compiler.compliance=21 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=21 diff --git a/GhidraPlugin/Module.manifest b/GhidraPlugin/Module.manifest new file mode 100644 index 00000000..e69de29b diff --git a/GhidraPlugin/README.md b/GhidraPlugin/README.md index faa75105..355daa02 100644 --- a/GhidraPlugin/README.md +++ b/GhidraPlugin/README.md @@ -1,169 +1 @@ -# Symbol Rename Logger Plugin - -A Ghidra plugin that monitors and logs all symbol and function rename events to the console. This plugin is useful for tracking changes to your reverse engineering work and understanding how symbols are being modified during analysis. - -## Features - -- **Symbol Rename Monitoring**: Logs when any symbol is renamed, including the old and new names -- **Function Rename Monitoring**: Specifically tracks function renames with additional details like function signatures -- **Symbol Addition/Removal**: Optionally logs when symbols are added or removed -- **Detailed Logging**: Provides context including symbol type, namespace, and address information -- **Real-time Monitoring**: Events are logged as they happen during your analysis session - -## Build Instructions - -### Prerequisites - -- Java 17 or higher -- Ghidra 11.x installed -- Gradle (or use the wrapper) - -### Building the Plugin - -1. Set the `GHIDRA_INSTALL_DIR` environment variable to your Ghidra installation directory: - ```bash - export GHIDRA_INSTALL_DIR="/path/to/ghidra_11.x.x_PUBLIC" - ``` - -2. Build the plugin: - ```bash - cd GhidraPlugin - ./gradlew build - ``` - -3. The built plugin JAR will be located at `build/libs/GhidraPlugin.jar` - -## Installation - -### Method 1: Install from Ghidra - -1. Open Ghidra -2. Go to **File** → **Install Extensions...** -3. Click the **+** button to add a new extension -4. Navigate to and select the built `GhidraPlugin.jar` file -5. Restart Ghidra when prompted - -### Method 2: Manual Installation - -1. Copy the built JAR file to your Ghidra user directory: - ```bash - cp build/libs/GhidraPlugin.jar ~/ghidra_scripts/ - ``` - -2. Or copy to the Ghidra Extensions directory: - ```bash - cp build/libs/GhidraPlugin.jar $GHIDRA_INSTALL_DIR/Ghidra/Extensions/ - ``` - -## Usage - -### Enabling the Plugin - -1. Open a program in Ghidra's CodeBrowser -2. Go to **File** → **Configure...** -3. In the Configure Tool dialog, navigate to **Misc** category -4. Check the box next to **SymbolRenameLoggerPlugin** -5. Click **OK** - -### Viewing Logs - -The plugin logs all events to Ghidra's console. To view the logs: - -1. Go to **Window** → **Console** -2. The console will show messages like: - ``` - INFO REPORT: SymbolRenameLoggerPlugin initialized - INFO REPORT: Started listening for rename events in program: example.exe - INFO REPORT: SYMBOL RENAMED: 'FUN_00401000' -> 'main' at address 00401000 - INFO REPORT: Symbol type: Function, Namespace: Global - INFO REPORT: Function signature: undefined main(void) - ``` - -### Log Message Types - -The plugin generates several types of log messages: - -- **SYMBOL RENAMED**: When any symbol is renamed -- **FUNCTION RENAMED**: Specific function rename events with signatures -- **SYMBOL ADDED**: When new symbols are created -- **SYMBOL REMOVED**: When symbols are deleted - -Each message includes: -- Old and new symbol names -- Memory address -- Symbol type (Function, Label, etc.) -- Namespace information -- Function signatures (for functions) - -## Example Output - -``` -INFO REPORT: SYMBOL RENAMED: 'FUN_00401000' -> 'main' at address 00401000 -INFO REPORT: Symbol type: Function, Namespace: Global -INFO REPORT: Function signature: undefined main(void) - -INFO REPORT: SYMBOL RENAMED: 'DAT_00403000' -> 'g_config' at address 00403000 -INFO REPORT: Symbol type: Label, Namespace: Global - -INFO REPORT: FUNCTION RENAMED: 'FUN_00401234' -> 'initialize_system' at address 00401234 -INFO REPORT: Function signature: void initialize_system(int param_1) -``` - -## Development - -### Project Structure - -``` -GhidraPlugin/ -├── build.gradle # Build configuration -├── extension.properties # Plugin metadata -├── README.md # This file -└── src/main/java/symbollogger/ - └── SymbolRenameLoggerPlugin.java # Main plugin class -``` - -### Customization - -You can modify the plugin behavior by editing `SymbolRenameLoggerPlugin.java`: - -- **Filter events**: Add conditions in `handleProgramChange()` to only log certain types of symbols -- **Change log format**: Modify the `String.format()` calls in the handler methods -- **Add more details**: Extend the symbol information gathering in `handleSymbolRenamed()` -- **Export to file**: Modify the logging to write to files instead of console - -### Event Types Monitored - -The plugin currently monitors these Ghidra program events: - -- `ProgramEvent.SYMBOL_RENAMED` -- `ProgramEvent.FUNCTION_CHANGED` -- `ProgramEvent.SYMBOL_ADDED` -- `ProgramEvent.SYMBOL_REMOVED` - -You can add monitoring for additional events by modifying the `handleProgramChange()` method. - -## Troubleshooting - -### Plugin Not Loading - -- Ensure Java 17+ is being used -- Check that `GHIDRA_INSTALL_DIR` is set correctly -- Verify the plugin JAR is in the correct directory -- Check Ghidra's console for error messages - -### No Log Messages - -- Ensure the plugin is enabled in the tool configuration -- Check that the Console window is open (**Window** → **Console**) -- Verify that a program is loaded and active -- Try renaming a symbol to test if events are being captured - -### Build Errors - -- Ensure all Ghidra JAR dependencies are accessible -- Check that the Ghidra installation is complete -- Verify Java version compatibility - -## License - -This plugin is provided as-is for educational and research purposes. \ No newline at end of file +# GhidraPlugin diff --git a/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginAnalyzer.class b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginAnalyzer.class new file mode 100644 index 00000000..693f9d31 Binary files /dev/null and b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginAnalyzer.class differ diff --git a/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin$MyProvider$1.class b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin$MyProvider$1.class new file mode 100644 index 00000000..2b6277e9 Binary files /dev/null and b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin$MyProvider$1.class differ diff --git a/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin$MyProvider.class b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin$MyProvider.class new file mode 100644 index 00000000..da9e4eb6 Binary files /dev/null and b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin$MyProvider.class differ diff --git a/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin.class b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin.class new file mode 100644 index 00000000..4359fcfd Binary files /dev/null and b/GhidraPlugin/bin/main/ghidraplugin/GhidraPluginPlugin.class differ diff --git a/GhidraPlugin/bin/main/ghidraplugin/SymbolRenameLoggerPlugin.class b/GhidraPlugin/bin/main/ghidraplugin/SymbolRenameLoggerPlugin.class new file mode 100644 index 00000000..03c5934a Binary files /dev/null and b/GhidraPlugin/bin/main/ghidraplugin/SymbolRenameLoggerPlugin.class differ diff --git a/GhidraPlugin/bin/main/help/TOC_Source.xml b/GhidraPlugin/bin/main/help/TOC_Source.xml new file mode 100644 index 00000000..a34f62e8 --- /dev/null +++ b/GhidraPlugin/bin/main/help/TOC_Source.xml @@ -0,0 +1,57 @@ + + + + + + + diff --git a/GhidraPlugin/bin/main/help/topics/ghidraplugin/help.html b/GhidraPlugin/bin/main/help/topics/ghidraplugin/help.html new file mode 100644 index 00000000..1f9d6a1f --- /dev/null +++ b/GhidraPlugin/bin/main/help/topics/ghidraplugin/help.html @@ -0,0 +1,23 @@ + + + + + + + + + + + Skeleton Help File for a Module + + + + +

Skeleton Help File for a Module

+ +

This is a simple skeleton help topic. For a better description of what should and should not + go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your + favorite help topic. In general, language modules do not have their own help topics.

+ + diff --git a/GhidraPlugin/bin/main/images/README.txt b/GhidraPlugin/bin/main/images/README.txt new file mode 100644 index 00000000..f20ae77b --- /dev/null +++ b/GhidraPlugin/bin/main/images/README.txt @@ -0,0 +1,2 @@ +The "src/resources/images" directory is intended to hold all image/icon files used by +this module. diff --git a/GhidraPlugin/bin/scripts/README.txt b/GhidraPlugin/bin/scripts/README.txt new file mode 100644 index 00000000..9e408f4b --- /dev/null +++ b/GhidraPlugin/bin/scripts/README.txt @@ -0,0 +1 @@ +Java source directory to hold module-specific Ghidra scripts. diff --git a/GhidraPlugin/build.gradle b/GhidraPlugin/build.gradle index 328f0f4e..63365e84 100644 --- a/GhidraPlugin/build.gradle +++ b/GhidraPlugin/build.gradle @@ -1,44 +1,66 @@ -plugins { - id 'java' +/* ### + * 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. + */ +// Builds a Ghidra Extension for a given Ghidra installation. +// +// An absolute path to the Ghidra installation directory must be supplied either by setting the +// GHIDRA_INSTALL_DIR environment variable or Gradle project property: +// +// > export GHIDRA_INSTALL_DIR= +// > gradle +// +// or +// +// > gradle -PGHIDRA_INSTALL_DIR= +// +// Gradle should be invoked from the directory of the project to build. Please see the +// application.gradle.version property in /Ghidra/application.properties +// for the correction version of Gradle to use for the Ghidra installation you specify. + +//----------------------START "DO NOT MODIFY" SECTION------------------------------ +def ghidraInstallDir + +if (System.env.GHIDRA_INSTALL_DIR) { + ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR +} +else if (project.hasProperty("GHIDRA_INSTALL_DIR")) { + ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR") +} +else { + ghidraInstallDir = "" } -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 +task distributeExtension { + group "Ghidra" + + apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle" + dependsOn ':buildExtension' +} +//----------------------END "DO NOT MODIFY" SECTION------------------------------- repositories { - flatDir { - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Features/Base/lib' - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Framework/SoftwareModeling/lib' - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Framework/Docking/lib' - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Framework/Generic/lib' - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Framework/Project/lib' - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Framework/Utility/lib' - dirs System.getProperty('GHIDRA_INSTALL_DIR') + '/Ghidra/Framework/Gui/lib' - } + // Declare dependency repositories here. This is not needed if dependencies are manually + // dropped into the lib/ directory. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html for more info. + // Ex: mavenCentral() } dependencies { - implementation name: 'Base', version: '' - implementation name: 'SoftwareModeling', version: '' - implementation name: 'Docking', version: '' - implementation name: 'Generic', version: '' - implementation name: 'Project', version: '' - implementation name: 'Utility', version: '' - implementation name: 'Gui', version: '' + // Any external dependencies added here will automatically be copied to the lib/ directory when + // this extension is built. } -compileJava { - dependsOn configurations.compileClasspath -} - -jar { - manifest { - attributes( - 'Implementation-Title': 'Symbol Rename Logger Plugin', - 'Implementation-Version': '1.0' - ) - } - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} \ No newline at end of file +// Exclude additional files from the built extension +// Ex: buildExtension.exclude '.idea/**' diff --git a/GhidraPlugin/data/README.txt b/GhidraPlugin/data/README.txt new file mode 100644 index 00000000..1222f673 --- /dev/null +++ b/GhidraPlugin/data/README.txt @@ -0,0 +1,15 @@ +The "data" directory is intended to hold data files that will be used by this module and will +not end up in the .jar file, but will be present in the zip or tar file. Typically, data +files are placed here rather than in the resources directory if the user may need to edit them. + +An optional data/languages directory can exist for the purpose of containing various Sleigh language +specification files and importer opinion files. + +The data/buildLanguage.xml is used for building the contents of the data/languages directory. + +The skel language definition has been commented-out within the skel.ldefs file so that the +skeleton language does not show-up within Ghidra. + +See the Sleigh language documentation (docs/languages/index.html) for details Sleigh language +specification syntax. + \ No newline at end of file diff --git a/GhidraPlugin/extension.properties b/GhidraPlugin/extension.properties index 999fb499..86a8a29a 100644 --- a/GhidraPlugin/extension.properties +++ b/GhidraPlugin/extension.properties @@ -1,5 +1,5 @@ name=@extname@ -description=A plugin that logs symbol and function rename events -author=Your Name +description=The extension description can be customized by editing the extension.properties file. +author= createdOn= -version=@extversion@ \ No newline at end of file +version=@extversion@ diff --git a/GhidraPlugin/ghidra_scripts/README.txt b/GhidraPlugin/ghidra_scripts/README.txt new file mode 100644 index 00000000..9e408f4b --- /dev/null +++ b/GhidraPlugin/ghidra_scripts/README.txt @@ -0,0 +1 @@ +Java source directory to hold module-specific Ghidra scripts. diff --git a/GhidraPlugin/lib/README.txt b/GhidraPlugin/lib/README.txt new file mode 100644 index 00000000..528dbc6c --- /dev/null +++ b/GhidraPlugin/lib/README.txt @@ -0,0 +1,3 @@ +The "lib" directory is intended to hold Jar files which this module is dependent upon. Jar files +may be placed in this directory manually, or automatically by maven via the dependencies block +of this module's build.gradle file. \ No newline at end of file diff --git a/GhidraPlugin/os/linux_x86_64/README.txt b/GhidraPlugin/os/linux_x86_64/README.txt new file mode 100644 index 00000000..7dd33ce2 --- /dev/null +++ b/GhidraPlugin/os/linux_x86_64/README.txt @@ -0,0 +1,3 @@ +The "os/linux_x86_64" directory is intended to hold Linux native binaries +which this module is dependent upon. This directory may be eliminated for a specific +module if native binaries are not provided for the corresponding platform. diff --git a/GhidraPlugin/os/mac_x86_64/README.txt b/GhidraPlugin/os/mac_x86_64/README.txt new file mode 100644 index 00000000..fbf2469e --- /dev/null +++ b/GhidraPlugin/os/mac_x86_64/README.txt @@ -0,0 +1,3 @@ +The "os/mac_x86_64" directory is intended to hold macOS (OS X) native binaries +which this module is dependent upon. This directory may be eliminated for a specific +module if native binaries are not provided for the corresponding platform. diff --git a/GhidraPlugin/os/win_x86_64/README.txt b/GhidraPlugin/os/win_x86_64/README.txt new file mode 100644 index 00000000..e0359950 --- /dev/null +++ b/GhidraPlugin/os/win_x86_64/README.txt @@ -0,0 +1,3 @@ +The "os/win_x86_64" directory is intended to hold MS Windows native binaries (.exe) +which this module is dependent upon. This directory may be eliminated for a specific +module if native binaries are not provided for the corresponding platform. diff --git a/GhidraPlugin/src/main/help/help/TOC_Source.xml b/GhidraPlugin/src/main/help/help/TOC_Source.xml new file mode 100644 index 00000000..a34f62e8 --- /dev/null +++ b/GhidraPlugin/src/main/help/help/TOC_Source.xml @@ -0,0 +1,57 @@ + + + + + + + diff --git a/GhidraPlugin/src/main/help/help/topics/ghidraplugin/help.html b/GhidraPlugin/src/main/help/help/topics/ghidraplugin/help.html new file mode 100644 index 00000000..1f9d6a1f --- /dev/null +++ b/GhidraPlugin/src/main/help/help/topics/ghidraplugin/help.html @@ -0,0 +1,23 @@ + + + + + + + + + + + Skeleton Help File for a Module + + + + +

Skeleton Help File for a Module

+ +

This is a simple skeleton help topic. For a better description of what should and should not + go in here, see the "sample" Ghidra extension in the Extensions/Ghidra directory, or see your + favorite help topic. In general, language modules do not have their own help topics.

+ + diff --git a/GhidraPlugin/src/main/java/ghidraplugin/GhidraPluginAnalyzer.java b/GhidraPlugin/src/main/java/ghidraplugin/GhidraPluginAnalyzer.java new file mode 100644 index 00000000..8718a0d9 --- /dev/null +++ b/GhidraPlugin/src/main/java/ghidraplugin/GhidraPluginAnalyzer.java @@ -0,0 +1,74 @@ +/* ### + * 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 ghidraplugin; + +import ghidra.app.services.AbstractAnalyzer; +import ghidra.app.services.AnalyzerType; +import ghidra.app.util.importer.MessageLog; +import ghidra.framework.options.Options; +import ghidra.program.model.address.AddressSetView; +import ghidra.program.model.listing.Program; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.TaskMonitor; + +/** + * Provide class-level documentation that describes what this analyzer does. + */ +public class GhidraPluginAnalyzer extends AbstractAnalyzer { + + public GhidraPluginAnalyzer() { + + // Name the analyzer and give it a description. + + super("My Analyzer", "Analyzer description goes here", AnalyzerType.BYTE_ANALYZER); + } + + @Override + public boolean getDefaultEnablement(Program program) { + + // Return true if analyzer should be enabled by default + + return true; + } + + @Override + public boolean canAnalyze(Program program) { + + // Examine 'program' to determine of this analyzer should analyze it. Return true + // if it can. + + return true; + } + + @Override + public void registerOptions(Options options, Program program) { + + // If this analyzer has custom options, register them here + + options.registerOption("Option name goes here", false, null, + "Option description goes here"); + } + + @Override + public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log) + throws CancelledException { + + // Perform analysis when things get added to the 'program'. Return true if the + // analysis succeeded. + + return false; + } +} diff --git a/GhidraPlugin/src/main/java/ghidraplugin/GhidraPluginPlugin.java b/GhidraPlugin/src/main/java/ghidraplugin/GhidraPluginPlugin.java new file mode 100644 index 00000000..92ecd6a9 --- /dev/null +++ b/GhidraPlugin/src/main/java/ghidraplugin/GhidraPluginPlugin.java @@ -0,0 +1,116 @@ +/* ### + * 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 ghidraplugin; + +import java.awt.BorderLayout; + +import javax.swing.*; + +import docking.ActionContext; +import docking.ComponentProvider; +import docking.action.DockingAction; +import docking.action.ToolBarData; +import ghidra.app.ExamplesPluginPackage; +import ghidra.app.plugin.PluginCategoryNames; +import ghidra.app.plugin.ProgramPlugin; +import ghidra.framework.plugintool.*; +import ghidra.framework.plugintool.util.PluginStatus; +import ghidra.util.HelpLocation; +import ghidra.util.Msg; +import resources.Icons; + +/** + * Provide class-level documentation that describes what this plugin does. + */ +//@formatter:off +@PluginInfo( + status = PluginStatus.STABLE, + packageName = ExamplesPluginPackage.NAME, + category = PluginCategoryNames.EXAMPLES, + shortDescription = "Plugin short description goes here.", + description = "Plugin long description goes here." +) +//@formatter:on +public class GhidraPluginPlugin extends ProgramPlugin { + + MyProvider provider; + + /** + * Plugin constructor. + * + * @param tool The plugin tool that this plugin is added to. + */ + public GhidraPluginPlugin(PluginTool tool) { + super(tool); + + // Customize provider (or remove if a provider is not desired) + String pluginName = getName(); + provider = new MyProvider(this, pluginName); + + // Customize help (or remove if help is not desired) + String topicName = this.getClass().getPackage().getName(); + String anchorName = "HelpAnchor"; + provider.setHelpLocation(new HelpLocation(topicName, anchorName)); + } + + @Override + public void init() { + super.init(); + + // Acquire services if necessary + } + + // If provider is desired, it is recommended to move it to its own file + private static class MyProvider extends ComponentProvider { + + private JPanel panel; + private DockingAction action; + + public MyProvider(Plugin plugin, String owner) { + super(plugin.getTool(), "Skeleton Provider", owner); + buildPanel(); + createActions(); + } + + // Customize GUI + private void buildPanel() { + panel = new JPanel(new BorderLayout()); + JTextArea textArea = new JTextArea(5, 25); + textArea.setEditable(false); + panel.add(new JScrollPane(textArea)); + setVisible(true); + } + + // Customize actions + private void createActions() { + action = new DockingAction("My Action", getOwner()) { + @Override + public void actionPerformed(ActionContext context) { + Msg.showInfo(getClass(), panel, "Custom Action", "Hello!"); + } + }; + action.setToolBarData(new ToolBarData(Icons.ADD_ICON, null)); + action.setEnabled(true); + action.markHelpUnnecessary(); + dockingTool.addLocalAction(this, action); + } + + @Override + public JComponent getComponent() { + return panel; + } + } +} diff --git a/GhidraPlugin/src/main/java/ghidraplugin/SymbolRenameLoggerPlugin.java b/GhidraPlugin/src/main/java/ghidraplugin/SymbolRenameLoggerPlugin.java new file mode 100644 index 00000000..4f0c3cf6 --- /dev/null +++ b/GhidraPlugin/src/main/java/ghidraplugin/SymbolRenameLoggerPlugin.java @@ -0,0 +1,350 @@ +package ghidraplugin; + +import ghidra.app.plugin.PluginCategoryNames; +import ghidra.app.plugin.ProgramPlugin; +import ghidra.framework.plugintool.PluginInfo; +import ghidra.framework.plugintool.PluginTool; +import ghidra.framework.plugintool.util.PluginStatus; +import ghidra.program.model.listing.Program; +import ghidra.program.util.ProgramChangeRecord; +import ghidra.program.util.ProgramEvent; +import ghidra.util.Msg; +import ghidra.framework.model.*; +import ghidra.program.model.symbol.*; +import ghidra.program.model.listing.Function; +import ghidra.program.util.*; + +@PluginInfo( + status = PluginStatus.STABLE, + packageName = "SymbolLogger", + category = PluginCategoryNames.COMMON, + shortDescription = "Logs symbol and function renames", + description = "A plugin that monitors and logs all symbol and function rename events to the console", + servicesRequired = {}, + servicesProvided = {} +) +public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObjectListener { + + public SymbolRenameLoggerPlugin(PluginTool tool) { + super(tool); + } + + @Override + protected void init() { + super.init(); + Msg.info(this, "SymbolRenameLoggerPlugin initialized"); + } + + @Override + protected void programActivated(Program program) { + super.programActivated(program); + if (program != null) { + program.addListener(this); + Msg.info(this, "Started listening for rename events in program: " + program.getName()); + } + } + + @Override + protected void programDeactivated(Program program) { + if (program != null) { + program.removeListener(this); + Msg.info(this, "Stopped listening for rename events in program: " + program.getName()); + } + super.programDeactivated(program); + } + + @Override + public void domainObjectChanged(DomainObjectChangedEvent ev) { + for (DomainObjectChangeRecord record : ev) { + if (record instanceof ProgramChangeRecord) { + ProgramChangeRecord progRecord = (ProgramChangeRecord) record; + handleProgramChange(progRecord); + } + } + } + + private void handleProgramChange(ProgramChangeRecord record) { + ProgramEvent eventType = (ProgramEvent)record.getEventType(); + + // Handle symbol rename events + if (eventType == ProgramEvent.SYMBOL_RENAMED) { + handleSymbolRenamed(record); + } + // Handle function rename events (functions are also symbols, but we can be more specific) + else if (eventType == ProgramEvent.FUNCTION_CHANGED) { + handleFunctionChanged(record); + } + // Handle symbol added events (in case we want to track new symbols) + else if (eventType == ProgramEvent.SYMBOL_ADDED) { + handleSymbolAdded(record); + } + // Handle symbol removed events + else if (eventType == ProgramEvent.SYMBOL_REMOVED) { + handleSymbolRemoved(record); + } + // Handle data type changes (includes global type definitions, structures, etc.) + else if (eventType == ProgramEvent.DATA_TYPE_CHANGED) { + handleDataTypeChanged(record); + } + // Handle data type added events + else if (eventType == ProgramEvent.DATA_TYPE_ADDED) { + handleDataTypeAdded(record); + } + // Handle data type removed events + else if (eventType == ProgramEvent.DATA_TYPE_REMOVED) { + handleDataTypeRemoved(record); + } + // Handle data type renamed events + else if (eventType == ProgramEvent.DATA_TYPE_RENAMED) { + handleDataTypeRenamed(record); + } + // Handle function signature changes (parameters, return types, etc.) + else if (eventType == ProgramEvent.FUNCTION_CHANGED) { + handleFunctionSignatureChanged(record); + } + } + + private void handleSymbolRenamed(ProgramChangeRecord record) { + Object newValue = record.getNewValue(); + Object oldValue = record.getOldValue(); + + String newName = (newValue != null) ? newValue.toString() : "null"; + String oldName = (oldValue != null) ? oldValue.toString() : "null"; + + Msg.info(this, String.format("SYMBOL RENAMED: '%s' -> '%s' at address %s", + oldName, newName, record.getStart())); + + // Try to get additional information about the symbol + try { + Program program = getCurrentProgram(); + if (program != null) { + SymbolTable symbolTable = program.getSymbolTable(); + Symbol[] symbols = symbolTable.getSymbols(record.getStart()); + + for (Symbol symbol : symbols) { + if (symbol.getName().equals(newName)) { + String symbolType = getSymbolTypeDescription(symbol); + Msg.info(this, String.format(" Symbol type: %s, Namespace: %s", + symbolType, symbol.getParentNamespace().getName())); + + // If it's a function, log additional function details + if (symbol.getSymbolType() == SymbolType.FUNCTION) { + Function function = (Function) symbol.getObject(); + if (function != null) { + Msg.info(this, String.format(" Function signature: %s", + function.getPrototypeString(false, false))); + } + } + break; + } + } + } + } catch (Exception e) { + Msg.error(this, "Error getting symbol details: " + e.getMessage()); + } + } + + private void handleFunctionChanged(ProgramChangeRecord record) { + // This handles function-specific changes including renames and signature changes + Object newValue = record.getNewValue(); + Object oldValue = record.getOldValue(); + + if (newValue instanceof Function && oldValue instanceof Function) { + Function newFunc = (Function) newValue; + Function oldFunc = (Function) oldValue; + + // Check for name changes + if (!newFunc.getName().equals(oldFunc.getName())) { + Msg.info(this, String.format("FUNCTION RENAMED: '%s' -> '%s' at address %s", + oldFunc.getName(), newFunc.getName(), newFunc.getEntryPoint())); + } + + // Check for signature changes + String oldSignature = oldFunc.getPrototypeString(false, false); + String newSignature = newFunc.getPrototypeString(false, false); + if (!oldSignature.equals(newSignature)) { + Msg.info(this, String.format("FUNCTION SIGNATURE CHANGED at address %s:", newFunc.getEntryPoint())); + Msg.info(this, String.format(" Old: %s", oldSignature)); + Msg.info(this, String.format(" New: %s", newSignature)); + + // Log specific changes + logFunctionSignatureDetails(oldFunc, newFunc); + } + } else if (newValue instanceof Function) { + Function function = (Function) newValue; + Msg.info(this, String.format("FUNCTION MODIFIED: %s at address %s", + function.getName(), function.getEntryPoint())); + Msg.info(this, String.format(" Signature: %s", function.getPrototypeString(false, false))); + } + } + + private void handleFunctionSignatureChanged(ProgramChangeRecord record) { + // Handle detailed function signature changes + handleFunctionChanged(record); // Reuse the existing logic + } + + private void handleDataTypeChanged(ProgramChangeRecord record) { + Object newValue = record.getNewValue(); + Object oldValue = record.getOldValue(); + + Msg.info(this, String.format("DATA TYPE CHANGED at address %s", record.getStart())); + + if (oldValue != null && newValue != null) { + Msg.info(this, String.format(" Old type: %s", oldValue.toString())); + Msg.info(this, String.format(" New type: %s", newValue.toString())); + } else if (newValue != null) { + Msg.info(this, String.format(" Type set to: %s", newValue.toString())); + } + + // Try to get more context about the data type change + try { + Program program = getCurrentProgram(); + if (program != null && record.getStart() != null) { + ghidra.program.model.data.Data data = program.getListing().getDataAt(record.getStart()); + if (data != null) { + Msg.info(this, String.format(" Data label: %s", data.getLabel())); + Msg.info(this, String.format(" Data type: %s", data.getDataType().getName())); + } + } + } catch (Exception e) { + Msg.error(this, "Error getting data type details: " + e.getMessage()); + } + } + + private void handleDataTypeAdded(ProgramChangeRecord record) { + Object newValue = record.getNewValue(); + + Msg.info(this, String.format("DATA TYPE ADDED at address %s", record.getStart())); + if (newValue != null) { + Msg.info(this, String.format(" Type: %s", newValue.toString())); + } + } + + private void handleDataTypeRemoved(ProgramChangeRecord record) { + Object oldValue = record.getOldValue(); + + Msg.info(this, String.format("DATA TYPE REMOVED at address %s", record.getStart())); + if (oldValue != null) { + Msg.info(this, String.format(" Removed type: %s", oldValue.toString())); + } + } + + private void handleDataTypeRenamed(ProgramChangeRecord record) { + Object newValue = record.getNewValue(); + Object oldValue = record.getOldValue(); + + String newName = (newValue != null) ? newValue.toString() : "null"; + String oldName = (oldValue != null) ? oldValue.toString() : "null"; + + Msg.info(this, String.format("DATA TYPE RENAMED: '%s' -> '%s' at address %s", + oldName, newName, record.getStart())); + } + + private void logFunctionSignatureDetails(Function oldFunc, Function newFunc) { + try { + // Check return type changes + if (!oldFunc.getReturnType().equals(newFunc.getReturnType())) { + Msg.info(this, String.format(" Return type changed: %s -> %s", + oldFunc.getReturnType().getName(), newFunc.getReturnType().getName())); + } + + // Check parameter count changes + int oldParamCount = oldFunc.getParameterCount(); + int newParamCount = newFunc.getParameterCount(); + if (oldParamCount != newParamCount) { + Msg.info(this, String.format(" Parameter count changed: %d -> %d", + oldParamCount, newParamCount)); + } + + // Check individual parameter changes + int maxParams = Math.max(oldParamCount, newParamCount); + for (int i = 0; i < maxParams; i++) { + if (i < oldParamCount && i < newParamCount) { + ghidra.program.model.listing.Parameter oldParam = oldFunc.getParameter(i); + ghidra.program.model.listing.Parameter newParam = newFunc.getParameter(i); + + if (!oldParam.getDataType().equals(newParam.getDataType())) { + Msg.info(this, String.format(" Parameter %d type changed: %s -> %s", + i, oldParam.getDataType().getName(), newParam.getDataType().getName())); + } + + if (!oldParam.getName().equals(newParam.getName())) { + Msg.info(this, String.format(" Parameter %d name changed: %s -> %s", + i, oldParam.getName(), newParam.getName())); + } + } else if (i < newParamCount) { + ghidra.program.model.listing.Parameter newParam = newFunc.getParameter(i); + Msg.info(this, String.format(" Parameter %d added: %s %s", + i, newParam.getDataType().getName(), newParam.getName())); + } else { + ghidra.program.model.listing.Parameter oldParam = oldFunc.getParameter(i); + Msg.info(this, String.format(" Parameter %d removed: %s %s", + i, oldParam.getDataType().getName(), oldParam.getName())); + } + } + + // Check calling convention changes + if (!oldFunc.getCallingConventionName().equals(newFunc.getCallingConventionName())) { + Msg.info(this, String.format(" Calling convention changed: %s -> %s", + oldFunc.getCallingConventionName(), newFunc.getCallingConventionName())); + } + + } catch (Exception e) { + Msg.error(this, "Error logging function signature details: " + e.getMessage()); + } + } + + private void handleSymbolAdded(ProgramChangeRecord record) { + Object newValue = record.getNewValue(); + if (newValue instanceof Symbol) { + Symbol symbol = (Symbol) newValue; + String symbolType = getSymbolTypeDescription(symbol); + Msg.info(this, String.format("SYMBOL ADDED: '%s' (%s) at address %s", + symbol.getName(), symbolType, symbol.getAddress())); + } + } + + private void handleSymbolRemoved(ProgramChangeRecord record) { + Object oldValue = record.getOldValue(); + if (oldValue instanceof Symbol) { + Symbol symbol = (Symbol) oldValue; + String symbolType = getSymbolTypeDescription(symbol); + Msg.info(this, String.format("SYMBOL REMOVED: '%s' (%s) at address %s", + symbol.getName(), symbolType, symbol.getAddress())); + } + } + + private String getSymbolTypeDescription(Symbol symbol) { + SymbolType type = symbol.getSymbolType(); + + if (type == SymbolType.FUNCTION) { + return "Function"; + } else if (type == SymbolType.LABEL) { + return "Label"; + } else if (type == SymbolType.CLASS) { + return "Class"; + } else if (type == SymbolType.NAMESPACE) { + return "Namespace"; + } else if (type == SymbolType.PARAMETER) { + return "Parameter"; + } else if (type == SymbolType.LOCAL_VAR) { + return "Local Variable"; + } else if (type == SymbolType.GLOBAL_VAR) { + return "Global Variable"; + } else if (type == SymbolType.LIBRARY) { + return "Library"; + } else { + return type.toString(); + } + } + + @Override + protected void dispose() { + Program program = getCurrentProgram(); + if (program != null) { + program.removeListener(this); + } + super.dispose(); + Msg.info(this, "SymbolRenameLoggerPlugin disposed"); + } +} \ No newline at end of file diff --git a/GhidraPlugin/src/main/java/symbollogger/SymbolRenameLoggerPlugin.java b/GhidraPlugin/src/main/java/symbollogger/SymbolRenameLoggerPlugin.java deleted file mode 100644 index 774cd317..00000000 --- a/GhidraPlugin/src/main/java/symbollogger/SymbolRenameLoggerPlugin.java +++ /dev/null @@ -1,198 +0,0 @@ -package symbollogger; - -import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.ProgramPlugin; -import ghidra.framework.plugintool.PluginInfo; -import ghidra.framework.plugintool.PluginTool; -import ghidra.framework.plugintool.util.PluginStatus; -import ghidra.program.model.listing.Program; -import ghidra.program.util.ProgramChangeRecord; -import ghidra.program.util.ProgramEvent; -import ghidra.util.Msg; -import ghidra.framework.model.*; -import ghidra.program.model.symbol.*; -import ghidra.program.model.listing.Function; -import ghidra.program.util.*; - -@PluginInfo( - status = PluginStatus.STABLE, - packageName = "SymbolLogger", - category = PluginCategoryNames.MISC, - shortDescription = "Logs symbol and function renames", - description = "A plugin that monitors and logs all symbol and function rename events to the console", - servicesRequired = {}, - servicesProvided = {} -) -public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObjectListener { - - public SymbolRenameLoggerPlugin(PluginTool tool) { - super(tool); - } - - @Override - protected void init() { - super.init(); - Msg.info(this, "SymbolRenameLoggerPlugin initialized"); - } - - @Override - protected void programActivated(Program program) { - super.programActivated(program); - if (program != null) { - program.addListener(this); - Msg.info(this, "Started listening for rename events in program: " + program.getName()); - } - } - - @Override - protected void programDeactivated(Program program) { - if (program != null) { - program.removeListener(this); - Msg.info(this, "Stopped listening for rename events in program: " + program.getName()); - } - super.programDeactivated(program); - } - - @Override - public void domainObjectChanged(DomainObjectChangedEvent ev) { - for (DomainObjectChangeRecord record : ev) { - if (record instanceof ProgramChangeRecord) { - ProgramChangeRecord progRecord = (ProgramChangeRecord) record; - handleProgramChange(progRecord); - } - } - } - - private void handleProgramChange(ProgramChangeRecord record) { - ProgramEvent eventType = record.getEventType(); - - // Handle symbol rename events - if (eventType == ProgramEvent.SYMBOL_RENAMED) { - handleSymbolRenamed(record); - } - // Handle function rename events (functions are also symbols, but we can be more specific) - else if (eventType == ProgramEvent.FUNCTION_CHANGED) { - handleFunctionChanged(record); - } - // Handle symbol added events (in case we want to track new symbols) - else if (eventType == ProgramEvent.SYMBOL_ADDED) { - handleSymbolAdded(record); - } - // Handle symbol removed events - else if (eventType == ProgramEvent.SYMBOL_REMOVED) { - handleSymbolRemoved(record); - } - } - - private void handleSymbolRenamed(ProgramChangeRecord record) { - Object newValue = record.getNewValue(); - Object oldValue = record.getOldValue(); - - String newName = (newValue != null) ? newValue.toString() : "null"; - String oldName = (oldValue != null) ? oldValue.toString() : "null"; - - Msg.info(this, String.format("SYMBOL RENAMED: '%s' -> '%s' at address %s", - oldName, newName, record.getStart())); - - // Try to get additional information about the symbol - try { - Program program = getCurrentProgram(); - if (program != null) { - SymbolTable symbolTable = program.getSymbolTable(); - Symbol[] symbols = symbolTable.getSymbols(record.getStart()); - - for (Symbol symbol : symbols) { - if (symbol.getName().equals(newName)) { - String symbolType = getSymbolTypeDescription(symbol); - Msg.info(this, String.format(" Symbol type: %s, Namespace: %s", - symbolType, symbol.getParentNamespace().getName())); - - // If it's a function, log additional function details - if (symbol.getSymbolType() == SymbolType.FUNCTION) { - Function function = (Function) symbol.getObject(); - if (function != null) { - Msg.info(this, String.format(" Function signature: %s", - function.getPrototypeString(false, false))); - } - } - break; - } - } - } - } catch (Exception e) { - Msg.error(this, "Error getting symbol details: " + e.getMessage()); - } - } - - private void handleFunctionChanged(ProgramChangeRecord record) { - // This handles function-specific changes including renames - Object newValue = record.getNewValue(); - Object oldValue = record.getOldValue(); - - if (newValue instanceof Function && oldValue instanceof Function) { - Function newFunc = (Function) newValue; - Function oldFunc = (Function) oldValue; - - if (!newFunc.getName().equals(oldFunc.getName())) { - Msg.info(this, String.format("FUNCTION RENAMED: '%s' -> '%s' at address %s", - oldFunc.getName(), newFunc.getName(), newFunc.getEntryPoint())); - Msg.info(this, String.format(" Function signature: %s", - newFunc.getPrototypeString(false, false))); - } - } - } - - private void handleSymbolAdded(ProgramChangeRecord record) { - Object newValue = record.getNewValue(); - if (newValue instanceof Symbol) { - Symbol symbol = (Symbol) newValue; - String symbolType = getSymbolTypeDescription(symbol); - Msg.info(this, String.format("SYMBOL ADDED: '%s' (%s) at address %s", - symbol.getName(), symbolType, symbol.getAddress())); - } - } - - private void handleSymbolRemoved(ProgramChangeRecord record) { - Object oldValue = record.getOldValue(); - if (oldValue instanceof Symbol) { - Symbol symbol = (Symbol) oldValue; - String symbolType = getSymbolTypeDescription(symbol); - Msg.info(this, String.format("SYMBOL REMOVED: '%s' (%s) at address %s", - symbol.getName(), symbolType, symbol.getAddress())); - } - } - - private String getSymbolTypeDescription(Symbol symbol) { - SymbolType type = symbol.getSymbolType(); - switch (type) { - case FUNCTION: - return "Function"; - case LABEL: - return "Label"; - case CLASS: - return "Class"; - case NAMESPACE: - return "Namespace"; - case PARAMETER: - return "Parameter"; - case LOCAL_VAR: - return "Local Variable"; - case GLOBAL_VAR: - return "Global Variable"; - case LIBRARY: - return "Library"; - default: - return type.toString(); - } - } - - @Override - protected void dispose() { - Program program = getCurrentProgram(); - if (program != null) { - program.removeListener(this); - } - super.dispose(); - Msg.info(this, "SymbolRenameLoggerPlugin disposed"); - } -} \ No newline at end of file diff --git a/GhidraPlugin/src/main/resources/images/README.txt b/GhidraPlugin/src/main/resources/images/README.txt new file mode 100644 index 00000000..f20ae77b --- /dev/null +++ b/GhidraPlugin/src/main/resources/images/README.txt @@ -0,0 +1,2 @@ +The "src/resources/images" directory is intended to hold all image/icon files used by +this module. diff --git a/game_re/gh_fix/r3_BNK_playMovie.cxx b/game_re/gh_fix/r3_BNK_playMovie.cxx index d5c703fc..e24f3f16 100644 --- a/game_re/gh_fix/r3_BNK_playMovie.cxx +++ b/game_re/gh_fix/r3_BNK_playMovie.cxx @@ -167,7 +167,7 @@ LAB_00442549: r3_validateBinkVideoQuality(g_bink_videoBpp, g_bink_realVideoQuality); FUN_00485400(haveSoundtrack, 0); FUN_004420f0(0); - uVar7 = FUN_00401270(); + uVar7 = FUN_00401270(0, 0); FUN_0046f680(uVar7, 0); FUN_0046ed40(0, 0, 1); FUN_0046f410(0, 0xff);