NationalSecurityAgency / ghidra

Ghidra is a software reverse engineering (SRE) framework
https://www.nsa.gov/ghidra
Apache License 2.0
51.23k stars 5.84k forks source link

Wanting to write another demangler, not sure where to begin #3115

Closed Schala closed 3 years ago

Schala commented 3 years ago

I apologise in advance if this is the wrong place to ask, because I'm not sure if there are community forums or anything for this. It does relate to contributing to Ghidra, nonetheless.

There's some very old abandoned Macintosh software I'm looking into to try and SRE. The developers left the debug symbols and everything in with it. The problem is that it uses an outdated C++ mangling ABI used by Mac compilers like MacApp or Metrowerks CodeWarrior in the 90s. While I have the PDF file for the specs, and can understand it, the issue arises when I tried looking into making a demangler plugin for Ghidra.

I know Java, though I'm admittedly a bit rusty, as I've not embraced it since Java 1.5 (5.0?). My real roadblock is Ghidra's massive API. The GNU and Microsoft demangler code seems like no small feat, either. What I've done so far is a bit of the parser, as some of both demanglers are just regex pattern constants. Other than that, I'm not sure what to do, despite studying both demanglers.

dragonmacher commented 3 years ago

I will briefly describe how we approach demangling.

  1. We find a mangled symbol.
  2. We pass the text of that symbol to a demangler (for Microsoft, we have our own demangling code; for Gnu we use a pre-built version of c++filt)
  3. The demangled text is converted into Ghidra DemangledObjects, either directly, such as for Microsoft, or by parsing the demangled output, such as for GNU.
  4. The DemangledObject types know internally how to apply themselves to the program upon request when the applyTo() method is called.

Demangling is typically performed during normal analysis, by either the MicrosoftDemanglerAnalyzer or the GnuDemanglerAnalyzer. (These account for step 1 above.)

You would need to mimic each of these things: a custom analyzer (this can be modeled on the analyzers mentioned above), demangler code that will convert the mangled string (which you are now working on), code that will turn the demangled string into DemangledObjects that can then be applied by your analyzer.

astrelsky commented 3 years ago

If it is actually Codewarrior you can use this. https://github.com/Cuyler36/CodeWarriorDemangler

If it isn't here is what you need to do to create a demangler.

When Ghidra sees your class in the classpath it will automatically be used when appropriate. You may or may not need to create an analyzer to ensure it is used during analysis as some of the existing ones might prevent it from being used.

You can also try using the deprecated gnu demangler options. You may be able to get by with an existing old format.

Schala commented 3 years ago

Thanks! I was unaware of the CW demangler!

Schala commented 3 years ago

Question: I'm not sure how to go about using it. There's no documentation, and I've tried bumping the version in the .properties file and tried building with Gradle, have attempted extension installation as well as dropping it in the script manager but to no avail. Am I supposed to write my own script for either or that utilises it?

ryanmkurtz commented 3 years ago

So you built the extension with gradle, and it produced a zip file? Then you installed the zipped extension through the File -> Install Extensions... menu in the Ghidra GUI?

Schala commented 3 years ago

No, the build failed because of missing/nonexistent project files. I cloned it right from the git repo itself, too.

ryanmkurtz commented 3 years ago

I just tried it out. I think they created their extension using a development version of Ghidra that suffered from dropping the wrong build.gradle file into new extensions. Replace the contents of their build.gradle file with the following and it should work (after following the instructions at the top of the new build.gradle):

 * 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=<Absolute path to Ghidra> 
//     > gradle
//
//         or
//
//     > gradle -PGHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
//
// Gradle should be invoked from the directory of the project to build.  Please see the
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/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")
}

if (ghidraInstallDir) {
    apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle"
}
else {
    throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
}
//----------------------END "DO NOT MODIFY" SECTION-------------------------------
Schala commented 3 years ago

Alright, appreciated!