mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-3952 Updated the script categories to simplify and reduce the number of folders.
This commit is contained in:
parent
7772d98143
commit
7db176b2bd
82 changed files with 885 additions and 981 deletions
|
@ -19,7 +19,7 @@
|
||||||
//script is more for diagnostic and demonstration purposes, since the application of unwind
|
//script is more for diagnostic and demonstration purposes, since the application of unwind
|
||||||
//information is already integrated into the Debugger.
|
//information is already integrated into the Debugger.
|
||||||
//@author
|
//@author
|
||||||
//@category Stack
|
//@category
|
||||||
//@keybinding
|
//@keybinding
|
||||||
//@menupath
|
//@menupath
|
||||||
//@toolbar
|
//@toolbar
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Example script for training random forests to find function starts
|
//Example script for training random forests to find function starts
|
||||||
//@category machineLearning
|
//@category Training
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
// Turns off function start searching (intended for use with the
|
// Turns off function start searching (intended for use with the
|
||||||
// headless analyzer as a prescript)
|
// headless analyzer as a prescript)
|
||||||
//@category machineLearning
|
//@category Search
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
##
|
##
|
||||||
# Generate the BSim signature for the function at the current address,
|
# Generate the BSim signature for the function at the current address,
|
||||||
# then dump the signature hashes and debug information to the console
|
# then dump the signature hashes and debug information to the console
|
||||||
# @category: BSim.python
|
# @category: BSim.Python
|
||||||
# @runtime Jython
|
# @runtime Jython
|
||||||
|
|
||||||
import ghidra.app.decompiler.DecompInterface as DecompInterface
|
import ghidra.app.decompiler.DecompInterface as DecompInterface
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
##
|
##
|
||||||
# Generate the BSim signature for the function at the current address, then dump the
|
# Generate the BSim signature for the function at the current address, then dump the
|
||||||
# signature hashes to the console
|
# signature hashes to the console
|
||||||
# @category: BSim.python
|
# @category: BSim.Python
|
||||||
# @runtime Jython
|
# @runtime Jython
|
||||||
|
|
||||||
import ghidra.app.decompiler.DecompInterface as DecompInterface
|
import ghidra.app.decompiler.DecompInterface as DecompInterface
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
# Example of how to perform an overview query in a script
|
# Example of how to perform an overview query in a script
|
||||||
# @category BSim.python
|
# @category BSim.Python
|
||||||
# @runtime Jython
|
# @runtime Jython
|
||||||
|
|
||||||
import ghidra.features.bsim.query.facade.SFOverviewInfo as SFOverviewInfo
|
import ghidra.features.bsim.query.facade.SFOverviewInfo as SFOverviewInfo
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
#Generate signatures for every function in the current program and write them to an XML file in a user-specified directory
|
#Generate signatures for every function in the current program and write them to an XML file in a user-specified directory
|
||||||
#@category BSim.python
|
#@category BSim.Python
|
||||||
#@runtime Jython
|
#@runtime Jython
|
||||||
|
|
||||||
import java.lang.System as System
|
import java.lang.System as System
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
# Example of performing a BSim query on a single function
|
# Example of performing a BSim query on a single function
|
||||||
# @category BSim.python
|
# @category BSim.Python
|
||||||
# @runtime Jython
|
# @runtime Jython
|
||||||
|
|
||||||
import ghidra.features.bsim.query.BSimClientFactory as BSimClientFactory
|
import ghidra.features.bsim.query.BSimClientFactory as BSimClientFactory
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
// Build ResultState for current function
|
// Build ResultState for current function
|
||||||
// @category Experimental
|
// @category
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
// Adds a SourceFile with a user-defined path and name to the program.
|
// Adds a SourceFile with a user-defined path and name to the program.
|
||||||
//@category SourceMapping
|
//@category Source Mapping
|
||||||
import java.util.HexFormat;
|
import java.util.HexFormat;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// Add a source map entry for the current selection.
|
// Add a source map entry for the current selection.
|
||||||
// The current selection must consist of a single address range.
|
// The current selection must consist of a single address range.
|
||||||
// If there is no selection, a length 0 entry will be added at the current address.
|
// If there is no selection, a length 0 entry will be added at the current address.
|
||||||
//@category SourceMapping
|
//@category Source Mapping
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Converts an ascii hex file into binary file. Works for files with spaces and without. Assumes hex bytes are zero padded so all values are two bytes long.
|
//Converts an ascii hex file into binary file. Works for files with spaces and without. Assumes hex bytes are zero padded so all values are two bytes long.
|
||||||
//@category Conversion
|
//@category
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
||||||
public class AsciiToBinaryScript extends GhidraScript {
|
public class AsciiToBinaryScript extends GhidraScript {
|
||||||
|
|
||||||
private static final String EMPTY_STRING = "";
|
private static final String EMPTY_STRING = "";
|
||||||
|
@ -37,7 +37,8 @@ public class AsciiToBinaryScript extends GhidraScript {
|
||||||
File outBinaryFile = askFile("Select Binary File", "Binary File");
|
File outBinaryFile = askFile("Select Binary File", "Binary File");
|
||||||
|
|
||||||
if (outBinaryFile.equals(inAsciiFile)) {
|
if (outBinaryFile.equals(inAsciiFile)) {
|
||||||
popup("Input file and output file are the same. Please choose a different file for the output." +
|
popup(
|
||||||
|
"Input file and output file are the same. Please choose a different file for the output." +
|
||||||
inAsciiFile.getAbsolutePath());
|
inAsciiFile.getAbsolutePath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Recursively finds a folder that matches a string and renames it to a new name.
|
//Recursively finds a folder that matches a string and renames it to a new name.
|
||||||
//@category Project
|
//@category Program
|
||||||
//@menupath
|
//@menupath
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
@ -26,7 +26,6 @@ public class BatchRename extends GhidraScript {
|
||||||
public BatchRename() {
|
public BatchRename() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Separates co-mingled n-bit and 64-bit binaries into two folder trees.
|
//Separates co-mingled n-bit and 64-bit binaries into two folder trees.
|
||||||
//@category Project
|
//@category Program
|
||||||
//@menupath
|
//@menupath
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,13 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Converts a binary file into an ascii hex file.
|
//Converts a binary file into an ascii hex file.
|
||||||
//@category Conversion
|
//@category
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
|
||||||
import ghidra.util.Conv;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
import ghidra.app.script.GhidraScript;
|
||||||
|
import ghidra.util.Conv;
|
||||||
|
|
||||||
public class BinaryToAsciiScript extends GhidraScript {
|
public class BinaryToAsciiScript extends GhidraScript {
|
||||||
|
|
||||||
|
@ -37,12 +35,13 @@ public class BinaryToAsciiScript extends GhidraScript {
|
||||||
File outAsciiFile = askFile("Select Ascii File", "Ascii File");
|
File outAsciiFile = askFile("Select Ascii File", "Ascii File");
|
||||||
|
|
||||||
if (inputBinaryFile.equals(outAsciiFile)) {
|
if (inputBinaryFile.equals(outAsciiFile)) {
|
||||||
popup("Input file and output file are the same. "+inputBinaryFile.getAbsolutePath());
|
popup("Input file and output file are the same. " + inputBinaryFile.getAbsolutePath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outAsciiFile.exists()) {
|
if (outAsciiFile.exists()) {
|
||||||
if (!askYesNo("Ascii File Already Exists", "The ascii file already exists.\nDo you want to overwrite it?")) {
|
if (!askYesNo("Ascii File Already Exists",
|
||||||
|
"The ascii file already exists.\nDo you want to overwrite it?")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +58,7 @@ public class BinaryToAsciiScript extends GhidraScript {
|
||||||
|
|
||||||
PrintWriter out = new PrintWriter(outAsciiFile);
|
PrintWriter out = new PrintWriter(outAsciiFile);
|
||||||
|
|
||||||
byte [] buffer = new byte[4096];
|
byte[] buffer = new byte[4096];
|
||||||
|
|
||||||
int bytesWritten = 0;
|
int bytesWritten = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -73,7 +72,7 @@ public class BinaryToAsciiScript extends GhidraScript {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0 ; i < nRead ; ++i) {
|
for (int i = 0; i < nRead; ++i) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +81,7 @@ public class BinaryToAsciiScript extends GhidraScript {
|
||||||
out.append('\n');
|
out.append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
out.write( Conv.toHexString(buffer[i]) );
|
out.write(Conv.toHexString(buffer[i]));
|
||||||
|
|
||||||
++bytesWritten;
|
++bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// Produces a list of instructions whose pcode contains a CALLOTHER pcode op. The list is
|
// Produces a list of instructions whose pcode contains a CALLOTHER pcode op. The list is
|
||||||
// sorted by number of occurrences of an instruction. When run headlessly, the list is displayed
|
// sorted by number of occurrences of an instruction. When run headlessly, the list is displayed
|
||||||
// each time a program is processed and the counts are cumulative.
|
// each time a program is processed and the counts are cumulative.
|
||||||
// @category sleigh
|
// @category Sleigh
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
*/
|
*/
|
||||||
//Counts the number of defined strings in the current selection, or current program if no selection is made,
|
//Counts the number of defined strings in the current selection, or current program if no selection is made,
|
||||||
//and saves the results to a file.
|
//and saves the results to a file.
|
||||||
//@category CustomerSubmission.Strings
|
//@category Customer Submission.Strings
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public class CountAndSaveStrings extends GhidraScript {
|
public class CountAndSaveStrings extends GhidraScript {
|
||||||
private Listing listing;
|
private Listing listing;
|
||||||
private File saveFile;
|
private File saveFile;
|
||||||
|
@ -46,8 +46,8 @@ public class CountAndSaveStrings extends GhidraScript {
|
||||||
private File getSaveFile() throws Exception {
|
private File getSaveFile() throws Exception {
|
||||||
File file = askFile("Choose File Location", "Save");
|
File file = askFile("Choose File Location", "Save");
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (!askYesNo("File Already Exists", "A file already exists with the name you "
|
if (!askYesNo("File Already Exists", "A file already exists with the name you " +
|
||||||
+ "chose.\nDo you want to overwrite it?")) {
|
"chose.\nDo you want to overwrite it?")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
//
|
//
|
||||||
// The name of the .exports file will be printed when the script finishes.
|
// The name of the .exports file will be printed when the script finishes.
|
||||||
//
|
//
|
||||||
//@category Windows
|
//@category
|
||||||
//@keybinding
|
//@keybinding
|
||||||
//@menupath
|
//@menupath
|
||||||
//@toolbar
|
//@toolbar
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//finds and creates strings that end with '\n'
|
//finds and creates strings that end with '\n'
|
||||||
//@category Memory
|
//@category Data Types
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
|
|
@ -15,13 +15,12 @@
|
||||||
*/
|
*/
|
||||||
// Attempt to parse single instruction from memory bytes at current location.
|
// Attempt to parse single instruction from memory bytes at current location.
|
||||||
// Parse trace output written to Tool Console.
|
// Parse trace output written to Tool Console.
|
||||||
// @category sleigh
|
// @category Sleigh
|
||||||
import ghidra.app.plugin.processors.sleigh.SleighDebugLogger;
|
import ghidra.app.plugin.processors.sleigh.SleighDebugLogger;
|
||||||
import ghidra.app.plugin.processors.sleigh.SleighDebugLogger.SleighDebugMode;
|
import ghidra.app.plugin.processors.sleigh.SleighDebugLogger.SleighDebugMode;
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.util.StringUtilities;
|
import ghidra.util.StringUtilities;
|
||||||
|
|
||||||
|
|
||||||
public class DebugSleighInstructionParse extends GhidraScript {
|
public class DebugSleighInstructionParse extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,7 +31,8 @@ public class DebugSleighInstructionParse extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SleighDebugLogger logger = new SleighDebugLogger(currentProgram, currentAddress, SleighDebugMode.VERBOSE);
|
SleighDebugLogger logger =
|
||||||
|
new SleighDebugLogger(currentProgram, currentAddress, SleighDebugMode.VERBOSE);
|
||||||
|
|
||||||
if (!logger.parseFailed()) {
|
if (!logger.parseFailed()) {
|
||||||
logger.append("\n");
|
logger.append("\n");
|
||||||
|
@ -48,12 +48,14 @@ public class DebugSleighInstructionParse extends GhidraScript {
|
||||||
for (int i = 0; i < logger.getNumOperands(); i++) {
|
for (int i = 0; i < logger.getNumOperands(); i++) {
|
||||||
mask = logger.getOperandValueMask(i);
|
mask = logger.getOperandValueMask(i);
|
||||||
logger.append("\nOp-" + i + " Mask: " + getFormattedBytes(mask));
|
logger.append("\nOp-" + i + " Mask: " + getFormattedBytes(mask));
|
||||||
logger.append("\nOp-" + i + " Value: " + getFormattedBytes(logger.getMaskedBytes(mask)));
|
logger.append(
|
||||||
|
"\nOp-" + i + " Value: " + getFormattedBytes(logger.getMaskedBytes(mask)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println(logger.toString());
|
println(logger.toString());
|
||||||
|
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e) {
|
||||||
println(e.getMessage());
|
println(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ public class DebugSleighInstructionParse extends GhidraScript {
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
String byteStr = StringUtilities.pad(Integer.toBinaryString(value[i] & 0xff), '0', 8);
|
String byteStr = StringUtilities.pad(Integer.toBinaryString(value[i] & 0xff), '0', 8);
|
||||||
buf.append(byteStr);
|
buf.append(byteStr);
|
||||||
if (i < (value.length-1)) {
|
if (i < (value.length - 1)) {
|
||||||
buf.append(".");
|
buf.append(".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Convenience script to quickly clear, edit, and recreate the code or data at the current cursor location.
|
//Convenience script to quickly clear, edit, and recreate the code or data at the current cursor location.
|
||||||
//@category Memory
|
//@category Update
|
||||||
//@keybinding
|
//@keybinding
|
||||||
//@menupath
|
//@menupath
|
||||||
//@toolbar
|
//@toolbar
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
//Looks for already defined graphic image data in the program
|
//Looks for already defined graphic image data in the program
|
||||||
//and writes all selected images to a directory.
|
//and writes all selected images to a directory.
|
||||||
//@category Images
|
//@category
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
|
@ -14,15 +14,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Rid us of those pesky FF's that become bad instructions
|
//Rid us of those pesky FF's that become bad instructions
|
||||||
//@category Cleanup
|
//@category
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.CategoryPath;
|
import ghidra.program.model.data.CategoryPath;
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class FFsBeGoneScript extends GhidraScript {
|
public class FFsBeGoneScript extends GhidraScript {
|
||||||
private Address addr;
|
private Address addr;
|
||||||
byte[] bytes = new byte[10];
|
byte[] bytes = new byte[10];
|
||||||
|
@ -83,11 +83,17 @@ public class FFsBeGoneScript extends GhidraScript {
|
||||||
if (!isUndefinedData(addr)) {
|
if (!isUndefinedData(addr)) {
|
||||||
if (currentProgram.getListing().getInstructionContaining(addr) != null) {
|
if (currentProgram.getListing().getInstructionContaining(addr) != null) {
|
||||||
addr =
|
addr =
|
||||||
currentProgram.getListing().getInstructionContaining(addr).getMaxAddress().next();
|
currentProgram.getListing()
|
||||||
|
.getInstructionContaining(addr)
|
||||||
|
.getMaxAddress()
|
||||||
|
.next();
|
||||||
}
|
}
|
||||||
else if (currentProgram.getListing().getDefinedDataContaining(addr) != null) {
|
else if (currentProgram.getListing().getDefinedDataContaining(addr) != null) {
|
||||||
addr =
|
addr =
|
||||||
currentProgram.getListing().getDefinedDataContaining(addr).getMaxAddress().next();
|
currentProgram.getListing()
|
||||||
|
.getDefinedDataContaining(addr)
|
||||||
|
.getMaxAddress()
|
||||||
|
.next();
|
||||||
}
|
}
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Finds programs containing various audio resources such as WAV's
|
//Finds programs containing various audio resources such as WAV's
|
||||||
//@category Resources
|
//@category Search
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -109,7 +109,8 @@ public class FindAudioInProgramScript extends GhidraScript {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
found =
|
found =
|
||||||
memory.findBytes(start, blocks[i].getEnd(), imageBytes, mask, true, monitor);
|
memory.findBytes(start, blocks[i].getEnd(), imageBytes, mask, true,
|
||||||
|
monitor);
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
foundImages.add(found);
|
foundImages.add(found);
|
||||||
start = found.add(1);
|
start = found.add(1);
|
||||||
|
|
|
@ -14,7 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Finds PNG and GIF images and applies data type if not already applied
|
//Finds PNG and GIF images and applies data type if not already applied
|
||||||
//@category Images
|
//@category Search
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.GifDataType;
|
import ghidra.program.model.data.GifDataType;
|
||||||
|
@ -23,9 +26,6 @@ import ghidra.program.model.listing.Data;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class FindImagesScript extends GhidraScript {
|
public class FindImagesScript extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -26,7 +25,7 @@
|
||||||
// problems with it. Still, it did a pretty good job of cleaning up after
|
// problems with it. Still, it did a pretty good job of cleaning up after
|
||||||
// FindUndefinedFunctionsScript.
|
// FindUndefinedFunctionsScript.
|
||||||
//
|
//
|
||||||
//@category CustomerSubmission.Analysis.Repair
|
//@category Customer Submission.Analysis.Repair
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.app.util.PseudoDisassembler;
|
import ghidra.app.util.PseudoDisassembler;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
//
|
//
|
||||||
// Script may be constrained by a selection.
|
// Script may be constrained by a selection.
|
||||||
//
|
//
|
||||||
//@category ELF Relocations
|
//@category DWARF
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
@ -82,7 +82,8 @@ public class FixElfExternalOffsetDataRelocationScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateExternalDataRelocation(Bookmark relocErrorBookmark, MessageLog log) throws Exception {
|
private boolean updateExternalDataRelocation(Bookmark relocErrorBookmark, MessageLog log)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
Address address = relocErrorBookmark.getAddress();
|
Address address = relocErrorBookmark.getAddress();
|
||||||
String bookmarkComment = relocErrorBookmark.getComment();
|
String bookmarkComment = relocErrorBookmark.getComment();
|
||||||
|
@ -112,12 +113,14 @@ public class FixElfExternalOffsetDataRelocationScript extends GhidraScript {
|
||||||
Memory memory = currentProgram.getMemory();
|
Memory memory = currentProgram.getMemory();
|
||||||
DumbMemBufferImpl buf = new DumbMemBufferImpl(memory, address);
|
DumbMemBufferImpl buf = new DumbMemBufferImpl(memory, address);
|
||||||
|
|
||||||
Address symbolAddr = PointerDataType.getAddressValue(buf, byteSize, address.getAddressSpace());
|
Address symbolAddr =
|
||||||
|
PointerDataType.getAddressValue(buf, byteSize, address.getAddressSpace());
|
||||||
if (symbolAddr == null) {
|
if (symbolAddr == null) {
|
||||||
return false; // invalid pointer data
|
return false; // invalid pointer data
|
||||||
}
|
}
|
||||||
|
|
||||||
String symbolName = bookmarkComment.substring(EXT_RELO_BOOKMARK_TEXT_PREFIX.length(), index - 1).trim();
|
String symbolName =
|
||||||
|
bookmarkComment.substring(EXT_RELO_BOOKMARK_TEXT_PREFIX.length(), index - 1).trim();
|
||||||
if (currentProgram.getSymbolTable().getSymbol(symbolName, symbolAddr, null) == null) {
|
if (currentProgram.getSymbolTable().getSymbol(symbolName, symbolAddr, null) == null) {
|
||||||
return false; // EXTERNAL block symbol not found at stored address
|
return false; // EXTERNAL block symbol not found at stored address
|
||||||
}
|
}
|
||||||
|
@ -146,7 +149,8 @@ public class FixElfExternalOffsetDataRelocationScript extends GhidraScript {
|
||||||
|
|
||||||
currentProgram.getBookmarkManager().removeBookmark(relocErrorBookmark);
|
currentProgram.getBookmarkManager().removeBookmark(relocErrorBookmark);
|
||||||
|
|
||||||
ElfRelocationHandler.warnExternalOffsetRelocation(currentProgram, address, symbolAddr, symbolName, offset, log);
|
ElfRelocationHandler.warnExternalOffsetRelocation(currentProgram, address, symbolAddr,
|
||||||
|
symbolName, offset, log);
|
||||||
|
|
||||||
DataType offsetPtrDt =
|
DataType offsetPtrDt =
|
||||||
currentProgram.getDataTypeManager()
|
currentProgram.getDataTypeManager()
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//
|
//
|
||||||
//Example script illustrating how to launch the Instruction Pattern Search dialog from a script.
|
//Example script illustrating how to launch the Instruction Pattern Search dialog from a script.
|
||||||
//
|
//
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Iterates over all defined data in the current program.
|
//Iterates over all defined data in the current program.
|
||||||
//@category Iteration
|
//@category Examples
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.listing.Data;
|
import ghidra.program.model.listing.Data;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//Iterates over all functions in the current program
|
//Iterates over all functions in the current program
|
||||||
//starting at the minimum address of the program.
|
//starting at the minimum address of the program.
|
||||||
//
|
//
|
||||||
//@category Iteration
|
//@category Examples
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -29,7 +29,8 @@ public class IterateFunctionsByAddressScript extends GhidraScript {
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
boolean forward =
|
boolean forward =
|
||||||
askYesNo("Iterate Function", "Do you want to iterate from low address to high address?");
|
askYesNo("Iterate Function",
|
||||||
|
"Do you want to iterate from low address to high address?");
|
||||||
|
|
||||||
if (forward) {
|
if (forward) {
|
||||||
iterateForward();
|
iterateForward();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Iterates over all functions in the current program.
|
//Iterates over all functions in the current program.
|
||||||
//@category Iteration
|
//@category Examples
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
|
@ -26,7 +25,8 @@ public class IterateFunctionsScript extends GhidraScript {
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
boolean forward =
|
boolean forward =
|
||||||
askYesNo("Iterate Function", "Do you want to iterate from low address to high address?");
|
askYesNo("Iterate Function",
|
||||||
|
"Do you want to iterate from low address to high address?");
|
||||||
|
|
||||||
if (forward) {
|
if (forward) {
|
||||||
iterateForward();
|
iterateForward();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Iterates over all instructions in the current program.
|
//Iterates over all instructions in the current program.
|
||||||
//@category Iteration
|
//@category Examples
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.listing.Instruction;
|
import ghidra.program.model.listing.Instruction;
|
||||||
|
@ -46,7 +45,7 @@ public class IterateInstructionsScript extends GhidraScript {
|
||||||
|
|
||||||
int nOperands = instruction.getNumOperands();
|
int nOperands = instruction.getNumOperands();
|
||||||
|
|
||||||
for (int i = 0 ; i < nOperands ; ++i) {
|
for (int i = 0; i < nOperands; ++i) {
|
||||||
String operand = instruction.getDefaultOperandRepresentation(i);
|
String operand = instruction.getDefaultOperandRepresentation(i);
|
||||||
buffer.append(operand);
|
buffer.append(operand);
|
||||||
buffer.append(' ');
|
buffer.append(' ');
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
// /proc/ksyms eliminates the middle column, and may add the name of the module
|
// /proc/ksyms eliminates the middle column, and may add the name of the module
|
||||||
// in square brackets at the end of the line.
|
// in square brackets at the end of the line.
|
||||||
|
|
||||||
//@category CustomerSubmission.Linux
|
//@category Customer Submission.Linux
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,7 +19,7 @@
|
||||||
// specified data type and symbol name and converts all "offset(base_register)"
|
// specified data type and symbol name and converts all "offset(base_register)"
|
||||||
// references to "symbol_name(base_register)" references.
|
// references to "symbol_name(base_register)" references.
|
||||||
//
|
//
|
||||||
//@category CustomerSubmission.Analysis
|
//@category Customer Submission.Analysis
|
||||||
//@keybinding alt S
|
//@keybinding alt S
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// Generate WARNING Bookmarks at instructions whose pcode contains a CALLOTHER op.
|
// Generate WARNING Bookmarks at instructions whose pcode contains a CALLOTHER op.
|
||||||
// This is useful to find PseudoOps that need to be implemented to yield better
|
// This is useful to find PseudoOps that need to be implemented to yield better
|
||||||
// emulation or decompilation.
|
// emulation or decompilation.
|
||||||
// @category sleigh
|
// @category Sleigh
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.disassemble.Disassembler;
|
import ghidra.program.disassemble.Disassembler;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// Generate WARNING Bookmarks on instructions which have unimplemented pcode.
|
// Generate WARNING Bookmarks on instructions which have unimplemented pcode.
|
||||||
// Similar to disassembler's built-in marking but allows for refresh after
|
// Similar to disassembler's built-in marking but allows for refresh after
|
||||||
// language update.
|
// language update.
|
||||||
// @category sleigh
|
// @category Sleigh
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.disassemble.Disassembler;
|
import ghidra.program.disassemble.Disassembler;
|
||||||
import ghidra.program.model.address.AddressSetView;
|
import ghidra.program.model.address.AddressSetView;
|
||||||
|
@ -60,7 +60,8 @@ public class MarkUnimplementedPcode extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markUnimplementedPcode(Instruction instr) {
|
private void markUnimplementedPcode(Instruction instr) {
|
||||||
currentProgram.getBookmarkManager().setBookmark(instr.getAddress(), BookmarkType.WARNING,
|
currentProgram.getBookmarkManager()
|
||||||
|
.setBookmark(instr.getAddress(), BookmarkType.WARNING,
|
||||||
Disassembler.UNIMPL_BOOKMARK_CATEGORY,
|
Disassembler.UNIMPL_BOOKMARK_CATEGORY,
|
||||||
"Instruction pcode is unimplemented: " + instr.getMnemonicString());
|
"Instruction pcode is unimplemented: " + instr.getMnemonicString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,35 +14,25 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//This script applies labels and comments to the WallaceSrc.exe program for use with GhidraClass exercises
|
//This script applies labels and comments to the WallaceSrc.exe program for use with GhidraClass exercises
|
||||||
//@category Training.GhidraClass
|
//@category Training.Ghidra Class
|
||||||
|
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.ArrayDataType;
|
import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.data.BooleanDataType;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.data.CharDataType;
|
|
||||||
import ghidra.program.model.data.IntegerDataType;
|
|
||||||
import ghidra.program.model.data.PointerDataType;
|
|
||||||
import ghidra.program.model.data.Structure;
|
|
||||||
import ghidra.program.model.data.StructureDataType;
|
|
||||||
import ghidra.program.model.listing.Function;
|
|
||||||
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
import ghidra.program.model.listing.Function.FunctionUpdateType;
|
||||||
import ghidra.program.model.listing.Parameter;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.model.listing.ParameterImpl;
|
|
||||||
import ghidra.program.model.symbol.Namespace;
|
|
||||||
import ghidra.program.model.symbol.SourceType;
|
|
||||||
import ghidra.program.model.symbol.SymbolTable;
|
|
||||||
import ghidra.util.exception.InvalidInputException;
|
import ghidra.util.exception.InvalidInputException;
|
||||||
|
|
||||||
public class MarkupWallaceSrcScript extends GhidraScript {
|
public class MarkupWallaceSrcScript extends GhidraScript {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
if(!currentProgram.getName().contains("WallaceSrc") || (!currentProgram.getExecutableMD5().equals("2527c463a079c81af7b3bc1d26bd3b5d"))) {
|
if (!currentProgram.getName().contains("WallaceSrc") ||
|
||||||
println("This script is only meant to work on the WallaceSrc executable with md5 hash 2527c463a079c81af7b3bc1d26bd3b5d.");
|
(!currentProgram.getExecutableMD5().equals("2527c463a079c81af7b3bc1d26bd3b5d"))) {
|
||||||
|
println(
|
||||||
|
"This script is only meant to work on the WallaceSrc executable with md5 hash 2527c463a079c81af7b3bc1d26bd3b5d.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,63 +48,77 @@ public class MarkupWallaceSrcScript extends GhidraScript {
|
||||||
//Create Gadget structure
|
//Create Gadget structure
|
||||||
Structure gadgetStruct = new StructureDataType("Gadget", 0);
|
Structure gadgetStruct = new StructureDataType("Gadget", 0);
|
||||||
PointerDataType charPtr = new PointerDataType(new CharDataType());
|
PointerDataType charPtr = new PointerDataType(new CharDataType());
|
||||||
gadgetStruct.add(charPtr,"name","");
|
gadgetStruct.add(charPtr, "name", "");
|
||||||
gadgetStruct.add(new IntegerDataType(),"type", "");
|
gadgetStruct.add(new IntegerDataType(), "type", "");
|
||||||
gadgetStruct.add(new BooleanDataType(), "deployed","");
|
gadgetStruct.add(new BooleanDataType(), "deployed", "");
|
||||||
gadgetStruct.add(ptrPersonStruct, "workingOn","");
|
gadgetStruct.add(ptrPersonStruct, "workingOn", "");
|
||||||
|
|
||||||
//apply data types to function parameters, locals, and returns
|
//apply data types to function parameters, locals, and returns
|
||||||
|
|
||||||
//Gadget::Gadget(Gadget * this, undefined4 param_1)
|
//Gadget::Gadget(Gadget * this, undefined4 param_1)
|
||||||
Function gadgetFunction = getFunctionAt(toAddr(0x00411440));
|
Function gadgetFunction = getFunctionAt(toAddr(0x00411440));
|
||||||
Parameter[] parameters = gadgetFunction.getParameters();
|
Parameter[] parameters = gadgetFunction.getParameters();
|
||||||
parameters[0] = new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
parameters[0] =
|
||||||
gadgetFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
||||||
|
gadgetFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
|
SourceType.USER_DEFINED, parameters);
|
||||||
|
|
||||||
//deployGadget - return type = Gadget *
|
//deployGadget - return type = Gadget *
|
||||||
Function deployGadgetFunction = getFunctionAt(toAddr(0x004118f0));
|
Function deployGadgetFunction = getFunctionAt(toAddr(0x004118f0));
|
||||||
deployGadgetFunction.setReturnType(new PointerDataType(gadgetStruct), SourceType.USER_DEFINED);
|
deployGadgetFunction.setReturnType(new PointerDataType(gadgetStruct),
|
||||||
|
SourceType.USER_DEFINED);
|
||||||
|
|
||||||
//initializePeople(Person *)
|
//initializePeople(Person *)
|
||||||
Function initPeopleFunction = getFunctionAt(toAddr(0x004117c0));
|
Function initPeopleFunction = getFunctionAt(toAddr(0x004117c0));
|
||||||
parameters = initPeopleFunction.getParameters();
|
parameters = initPeopleFunction.getParameters();
|
||||||
parameters[0] = new ParameterImpl("people", new PointerDataType(personStruct), currentProgram);
|
parameters[0] =
|
||||||
initPeopleFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
new ParameterImpl("people", new PointerDataType(personStruct), currentProgram);
|
||||||
|
initPeopleFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
|
SourceType.USER_DEFINED, parameters);
|
||||||
|
|
||||||
//use(Gadget *this, Person *person)
|
//use(Gadget *this, Person *person)
|
||||||
Function useFunction = getFunctionAt(toAddr(0x00411570));
|
Function useFunction = getFunctionAt(toAddr(0x00411570));
|
||||||
parameters = useFunction.getParameters();
|
parameters = useFunction.getParameters();
|
||||||
parameters[0] = new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
parameters[0] =
|
||||||
parameters[1] = new ParameterImpl("person", new PointerDataType(personStruct), currentProgram);
|
new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
||||||
useFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
parameters[1] =
|
||||||
|
new ParameterImpl("person", new PointerDataType(personStruct), currentProgram);
|
||||||
|
useFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
|
SourceType.USER_DEFINED, parameters);
|
||||||
|
|
||||||
//addPerson(Person ** list, char * name)
|
//addPerson(Person ** list, char * name)
|
||||||
Function addPersonFunction = getFunctionAt(toAddr(0x00411860));
|
Function addPersonFunction = getFunctionAt(toAddr(0x00411860));
|
||||||
parameters = addPersonFunction.getParameters();
|
parameters = addPersonFunction.getParameters();
|
||||||
parameters[0] = new ParameterImpl("list", new PointerDataType(new PointerDataType(personStruct)), currentProgram);
|
parameters[0] = new ParameterImpl("list",
|
||||||
parameters[1] = new ParameterImpl("name", new PointerDataType(new CharDataType()), currentProgram);
|
new PointerDataType(new PointerDataType(personStruct)), currentProgram);
|
||||||
addPersonFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
parameters[1] =
|
||||||
|
new ParameterImpl("name", new PointerDataType(new CharDataType()), currentProgram);
|
||||||
|
addPersonFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
|
SourceType.USER_DEFINED, parameters);
|
||||||
|
|
||||||
//addPeople(Person ** list)
|
//addPeople(Person ** list)
|
||||||
Function addPeopleFunction = getFunctionAt(toAddr(0x00411700));
|
Function addPeopleFunction = getFunctionAt(toAddr(0x00411700));
|
||||||
parameters = addPeopleFunction.getParameters();
|
parameters = addPeopleFunction.getParameters();
|
||||||
parameters[0] = new ParameterImpl("list", new PointerDataType(new PointerDataType(personStruct)), currentProgram);
|
parameters[0] = new ParameterImpl("list",
|
||||||
addPeopleFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
new PointerDataType(new PointerDataType(personStruct)), currentProgram);
|
||||||
|
addPeopleFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
|
SourceType.USER_DEFINED, parameters);
|
||||||
|
|
||||||
//print(Gadget * pGadget)
|
//print(Gadget * pGadget)
|
||||||
Function printFunction = getFunctionAt(toAddr(0x004115d0));
|
Function printFunction = getFunctionAt(toAddr(0x004115d0));
|
||||||
parameters = printFunction.getParameters();
|
parameters = printFunction.getParameters();
|
||||||
parameters[0] = new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
parameters[0] =
|
||||||
printFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS,true, SourceType.USER_DEFINED, parameters);
|
new ParameterImpl("this", new PointerDataType(gadgetStruct), currentProgram);
|
||||||
|
printFunction.replaceParameters(FunctionUpdateType.DYNAMIC_STORAGE_ALL_PARAMS, true,
|
||||||
|
SourceType.USER_DEFINED, parameters);
|
||||||
|
|
||||||
// Create labels for some of the functions
|
// Create labels for some of the functions
|
||||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||||
|
|
||||||
|
|
||||||
//create the Class "Gadget" to put most function symbols in
|
//create the Class "Gadget" to put most function symbols in
|
||||||
Namespace namespace = null;
|
Namespace namespace = null;
|
||||||
namespace = symbolTable.getNamespace("Gadget", null);
|
namespace = symbolTable.getNamespace("Gadget", null);
|
||||||
if(namespace == null) {
|
if (namespace == null) {
|
||||||
namespace = symbolTable.createClass(null, "Gadget", SourceType.USER_DEFINED);
|
namespace = symbolTable.createClass(null, "Gadget", SourceType.USER_DEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,29 +138,34 @@ public class MarkupWallaceSrcScript extends GhidraScript {
|
||||||
// Add other labels
|
// Add other labels
|
||||||
Function function = currentProgram.getFunctionManager().getFunctionAt(toAddr(0x004117c0));
|
Function function = currentProgram.getFunctionManager().getFunctionAt(toAddr(0x004117c0));
|
||||||
createNewLabel(toAddr(0x004117e5), "LoopOverPeople", function, SourceType.USER_DEFINED);
|
createNewLabel(toAddr(0x004117e5), "LoopOverPeople", function, SourceType.USER_DEFINED);
|
||||||
if(getSymbolAt(toAddr(0x00418138)).getSource().equals(SourceType.DEFAULT)){
|
if (getSymbolAt(toAddr(0x00418138)).getSource().equals(SourceType.DEFAULT)) {
|
||||||
createLabel(toAddr(0x00418138),"personList", true);
|
createLabel(toAddr(0x00418138), "personList", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add comments
|
// Add comments
|
||||||
setPlateComment(toAddr(0x00411440), "This is the init method for the Gadget class");
|
setPlateComment(toAddr(0x00411440), "This is the init method for the Gadget class");
|
||||||
setPlateComment(toAddr(0x004115d0), "This method prints the status of a Person -- whether they are deployed or not and who they are deployed on. ");
|
setPlateComment(toAddr(0x004115d0),
|
||||||
setPlateComment(toAddr(0x00411700), "This function adds all the people to the Person list.");
|
"This method prints the status of a Person -- whether they are deployed or not and who they are deployed on. ");
|
||||||
setPlateComment(toAddr(0x004117c0), "This function initializes each person's record with whether or not they like cheese, their id, and a pointer to the next person.");
|
setPlateComment(toAddr(0x00411700),
|
||||||
|
"This function adds all the people to the Person list.");
|
||||||
|
setPlateComment(toAddr(0x004117c0),
|
||||||
|
"This function initializes each person's record with whether or not they like cheese, their id, and a pointer to the next person.");
|
||||||
setPlateComment(toAddr(0x00411860), "This function adds a person to the Person list.");
|
setPlateComment(toAddr(0x00411860), "This function adds a person to the Person list.");
|
||||||
setPlateComment(toAddr(0x004118f0), "This function checks to see if the person on the list is Wallace and if so, it deploys the Infrared Garden Gnome.");
|
setPlateComment(toAddr(0x004118f0),
|
||||||
setEOLComment(toAddr(0x004117e7), "Randomly assign whether each person likes cheese or not.");
|
"This function checks to see if the person on the list is Wallace and if so, it deploys the Infrared Garden Gnome.");
|
||||||
|
setEOLComment(toAddr(0x004117e7),
|
||||||
|
"Randomly assign whether each person likes cheese or not.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void createNewLabel(Address address, String name, Namespace namespace, SourceType sourceType) {
|
void createNewLabel(Address address, String name, Namespace namespace, SourceType sourceType) {
|
||||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||||
if(getSymbolAt(address).getSource().equals(SourceType.DEFAULT)){
|
if (getSymbolAt(address).getSource().equals(SourceType.DEFAULT)) {
|
||||||
try {
|
try {
|
||||||
symbolTable.createLabel(address, name, namespace, sourceType);
|
symbolTable.createLabel(address, name, namespace, sourceType);
|
||||||
} catch (InvalidInputException e) {
|
}
|
||||||
|
catch (InvalidInputException e) {
|
||||||
println("Invalid input to create label.");
|
println("Invalid input to create label.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
// Edit -> Tool Options -> Eclipse Integration
|
// Edit -> Tool Options -> Eclipse Integration
|
||||||
//
|
//
|
||||||
// from the Ghidra Project Manager.
|
// from the Ghidra Project Manager.
|
||||||
//@category SourceMapping
|
//@category Source Mapping
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
// Edit -> Tool Options -> Visual Studio Code Integration
|
// Edit -> Tool Options -> Visual Studio Code Integration
|
||||||
//
|
//
|
||||||
// from the Ghidra Project Manager.
|
// from the Ghidra Project Manager.
|
||||||
//@category SourceMapping
|
//@category Source Mapping
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// This script displays data about Microsoft development tools (compilers, linkers, etc.)
|
// This script displays data about Microsoft development tools (compilers, linkers, etc.)
|
||||||
// used to build objects within program as stored in the Rich header and table.
|
// used to build objects within program as stored in the Rich header and table.
|
||||||
//
|
//
|
||||||
//@category Windows
|
//@category
|
||||||
//@keybinding
|
//@keybinding
|
||||||
//@menupath
|
//@menupath
|
||||||
//@toolbar
|
//@toolbar
|
||||||
|
@ -81,7 +81,11 @@ public class PortableExecutableRichPrintScript extends GhidraScript {
|
||||||
MSProductType prodType = prod == null ? MSProductType.Unknown : prod.getProductType();
|
MSProductType prodType = prod == null ? MSProductType.Unknown : prod.getProductType();
|
||||||
|
|
||||||
if (prodType != MSProductType.Unknown) {
|
if (prodType != MSProductType.Unknown) {
|
||||||
sb.append(prodType).append(" from ").append(prodVersion).append(", build ").append(
|
sb.append(prodType)
|
||||||
|
.append(" from ")
|
||||||
|
.append(prodVersion)
|
||||||
|
.append(", build ")
|
||||||
|
.append(
|
||||||
compid.getBuildNumber());
|
compid.getBuildNumber());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
#Given a function, find all strings used within all called funtions.
|
#Given a function, find all strings used within all called funtions.
|
||||||
# @category: Strings
|
# @category: Functions
|
||||||
# @runtime Jython
|
# @runtime Jython
|
||||||
|
|
||||||
# Handles only functions, not subroutines, as of now. Hopefully this will change later
|
# Handles only functions, not subroutines, as of now. Hopefully this will change later
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
// Reloads the language specification associated with a program at runtime.
|
// Reloads the language specification associated with a program at runtime.
|
||||||
// @category sleigh
|
// @category Sleigh
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
// Select and remove a source map entry at the current address.
|
// Select and remove a source map entry at the current address.
|
||||||
//@category SourceMapping
|
//@category Source Mapping
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Script to allow repository admins the ability to terminate multiple file checkouts belonging to a single user.
|
//Script to allow repository admins the ability to terminate multiple file checkouts belonging to a single user.
|
||||||
//@category MultiUser
|
//@category Update
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public class RemoveUserCheckoutsScript extends GhidraScript {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String uname = askString("Remove User Checkouts" , "Enter user ID to be cleared");
|
String uname = askString("Remove User Checkouts", "Enter user ID to be cleared");
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (User u : repository.getUserList()) {
|
for (User u : repository.getUserList()) {
|
||||||
|
@ -61,13 +61,15 @@ public class RemoveUserCheckoutsScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if (OptionDialog.showYesNoDialogWithNoAsDefaultButton(null, "User Name Confirmation",
|
if (OptionDialog.showYesNoDialogWithNoAsDefaultButton(null, "User Name Confirmation",
|
||||||
"User '" + uname + "' not a registered server user.\nDo you still want to search for and remove checkouts for this user?") != OptionDialog.YES_OPTION) {
|
"User '" + uname +
|
||||||
|
"' not a registered server user.\nDo you still want to search for and remove checkouts for this user?") != OptionDialog.YES_OPTION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectData.getFileCount() > 1000) {
|
if (projectData.getFileCount() > 1000) {
|
||||||
if (OptionDialog.showYesNoDialogWithNoAsDefaultButton(null, "Large Repository Confirmation",
|
if (OptionDialog.showYesNoDialogWithNoAsDefaultButton(null,
|
||||||
|
"Large Repository Confirmation",
|
||||||
"Repository contains a large number of failes and could be slow to search.\nDo you still want to search for and remove checkouts?") != OptionDialog.YES_OPTION) {
|
"Repository contains a large number of failes and could be slow to search.\nDo you still want to search for and remove checkouts?") != OptionDialog.YES_OPTION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +87,8 @@ public class RemoveUserCheckoutsScript extends GhidraScript {
|
||||||
return folderPath + childName;
|
return folderPath + childName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int removeCheckouts(RepositoryAdapter repository, String folderPath, String uid, TaskMonitor monitor) throws IOException, CancelledException {
|
private int removeCheckouts(RepositoryAdapter repository, String folderPath, String uid,
|
||||||
|
TaskMonitor monitor) throws IOException, CancelledException {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (RepositoryItem item : repository.getItemList(folderPath)) {
|
for (RepositoryItem item : repository.getItemList(folderPath)) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
@ -97,15 +100,19 @@ public class RemoveUserCheckoutsScript extends GhidraScript {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int removeCheckouts(RepositoryAdapter repository, RepositoryItem item, String uid) throws IOException {
|
private int removeCheckouts(RepositoryAdapter repository, RepositoryItem item, String uid)
|
||||||
|
throws IOException {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
ItemCheckoutStatus[] checkouts = repository.getCheckouts(item.getParentPath(), item.getName());
|
ItemCheckoutStatus[] checkouts =
|
||||||
|
repository.getCheckouts(item.getParentPath(), item.getName());
|
||||||
for (ItemCheckoutStatus checkout : checkouts) {
|
for (ItemCheckoutStatus checkout : checkouts) {
|
||||||
if (uid.equals(checkout.getUser())) {
|
if (uid.equals(checkout.getUser())) {
|
||||||
try {
|
try {
|
||||||
repository.terminateCheckout(item.getParentPath(), item.getName(), checkout.getCheckoutId(), false);
|
repository.terminateCheckout(item.getParentPath(), item.getName(),
|
||||||
|
checkout.getCheckoutId(), false);
|
||||||
++count;
|
++count;
|
||||||
} catch (IOException e) {
|
}
|
||||||
|
catch (IOException e) {
|
||||||
printerr("Failed to remove checkout: " + e.getMessage());
|
printerr("Failed to remove checkout: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -23,14 +22,14 @@
|
||||||
// Note: Script does not verify that no other member within the structure
|
// Note: Script does not verify that no other member within the structure
|
||||||
// is already using the new name.
|
// is already using the new name.
|
||||||
//
|
//
|
||||||
//@category CustomerSubmission.Search
|
//@category Customer Submission.Search
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.data.DataTypeComponent;
|
import ghidra.program.model.data.DataTypeComponent;
|
||||||
import ghidra.program.model.data.Structure;
|
import ghidra.program.model.data.Structure;
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class RenameStructMembers extends GhidraScript {
|
public class RenameStructMembers extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,12 +19,10 @@
|
||||||
// Note: Script does not verify that no other variable within the
|
// Note: Script does not verify that no other variable within the
|
||||||
// function is already using the new name.
|
// function is already using the new name.
|
||||||
//
|
//
|
||||||
//@category CustomerSubmission.Search
|
//@category Customer Submission.Search
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.listing.FunctionIterator;
|
|
||||||
import ghidra.program.model.listing.Variable;
|
|
||||||
import ghidra.program.model.symbol.SourceType;
|
import ghidra.program.model.symbol.SourceType;
|
||||||
|
|
||||||
public class RenameVariable extends GhidraScript {
|
public class RenameVariable extends GhidraScript {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,7 +18,10 @@
|
||||||
// Function Definition. This resolves variable size errors which
|
// Function Definition. This resolves variable size errors which
|
||||||
// result from this bad data state.
|
// result from this bad data state.
|
||||||
//
|
//
|
||||||
//@category Repair
|
//@category
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
@ -28,9 +30,6 @@ import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.exception.InvalidInputException;
|
import ghidra.util.exception.InvalidInputException;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class RepairFuncDefinitionUsageScript extends GhidraScript {
|
public class RepairFuncDefinitionUsageScript extends GhidraScript {
|
||||||
|
|
||||||
private static class MyVariableOffsetComparator implements Comparator<Variable> {
|
private static class MyVariableOffsetComparator implements Comparator<Variable> {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -30,13 +29,11 @@
|
||||||
// - Script scans every address within the program, so it is slow.
|
// - Script scans every address within the program, so it is slow.
|
||||||
// - Script doesn't scan param comments.
|
// - Script doesn't scan param comments.
|
||||||
//
|
//
|
||||||
//@category CustomerSubmission.Search
|
//@category Customer Submission.Search
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.listing.FunctionIterator;
|
|
||||||
import ghidra.program.model.listing.Variable;
|
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
|
|
||||||
public class ReplaceInComments extends GhidraScript {
|
public class ReplaceInComments extends GhidraScript {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
// the script will optionally list any existing checkouts prior to starting
|
// the script will optionally list any existing checkouts prior to starting
|
||||||
// the batch upgrade.
|
// the batch upgrade.
|
||||||
//
|
//
|
||||||
//@category Upgrade
|
//@category Program
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
# 2. The user has imported the file into Ghidra and the user has since deleted the file. This Ghidra script attempts to
|
# 2. The user has imported the file into Ghidra and the user has since deleted the file. This Ghidra script attempts to
|
||||||
# generate the original bytes of the imported file and asks the user to provide a filename to store the bytes. YARA then runs on that file.
|
# generate the original bytes of the imported file and asks the user to provide a filename to store the bytes. YARA then runs on that file.
|
||||||
|
|
||||||
#@category Memory.YARA
|
#@category Search.YARA
|
||||||
#@runtime Jython
|
#@runtime Jython
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//that called it) and build a combined mask/value buffer.
|
//that called it) and build a combined mask/value buffer.
|
||||||
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
||||||
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//The script will use a selection of multiple instructions and build a combined mask/value buffer.
|
//The script will use a selection of multiple instructions and build a combined mask/value buffer.
|
||||||
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
||||||
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//The script will use the first instructions in a selection and build a combined mask/value buffer.
|
//The script will use the first instructions in a selection and build a combined mask/value buffer.
|
||||||
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
||||||
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
@ -56,10 +56,12 @@ public class SearchGuiSingle extends SearchBaseExtended {
|
||||||
GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
|
GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
|
||||||
jPanel1.setLayout(jPanel1Layout);
|
jPanel1.setLayout(jPanel1Layout);
|
||||||
jPanel1Layout.setHorizontalGroup(
|
jPanel1Layout.setHorizontalGroup(
|
||||||
jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 100,
|
jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 100,
|
||||||
Short.MAX_VALUE));
|
Short.MAX_VALUE));
|
||||||
jPanel1Layout.setVerticalGroup(
|
jPanel1Layout.setVerticalGroup(
|
||||||
jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGap(0, 100,
|
jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 100,
|
||||||
Short.MAX_VALUE));
|
Short.MAX_VALUE));
|
||||||
|
|
||||||
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
@ -81,10 +83,15 @@ public class SearchGuiSingle extends SearchBaseExtended {
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) //
|
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) //
|
||||||
.addGroup(layout.createSequentialGroup() //
|
.addGroup(layout.createSequentialGroup() //
|
||||||
.addContainerGap() //
|
.addContainerGap() //
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) //
|
.addGroup(layout
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) //
|
.createParallelGroup(GroupLayout.Alignment.LEADING) //
|
||||||
|
.addGroup(layout
|
||||||
|
.createParallelGroup(
|
||||||
|
GroupLayout.Alignment.TRAILING) //
|
||||||
.addComponent(opTwoCheckBox) //
|
.addComponent(opTwoCheckBox) //
|
||||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) //
|
.addGroup(layout
|
||||||
|
.createParallelGroup(
|
||||||
|
GroupLayout.Alignment.LEADING) //
|
||||||
.addComponent(mnemonicCheckBox) //
|
.addComponent(mnemonicCheckBox) //
|
||||||
.addComponent(opOneCheckBox) //
|
.addComponent(opOneCheckBox) //
|
||||||
) //
|
) //
|
||||||
|
@ -113,7 +120,8 @@ public class SearchGuiSingle extends SearchBaseExtended {
|
||||||
.addComponent(opTwoCheckBox) //
|
.addComponent(opTwoCheckBox) //
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) //
|
.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) //
|
||||||
.addComponent(constCheckBox) //
|
.addComponent(constCheckBox) //
|
||||||
.addGap(18, 18, 18).addComponent(searchButton) //
|
.addGap(18, 18, 18)
|
||||||
|
.addComponent(searchButton) //
|
||||||
.addContainerGap(27, Short.MAX_VALUE) //
|
.addContainerGap(27, Short.MAX_VALUE) //
|
||||||
) //
|
) //
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//The script will use the selected instructions and build a combined mask/value buffer.
|
//The script will use the selected instructions and build a combined mask/value buffer.
|
||||||
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
||||||
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
|
|
||||||
public class SearchMnemonicsNoOpsNoConstScript extends SearchBaseExtended {
|
public class SearchMnemonicsNoOpsNoConstScript extends SearchBaseExtended {
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//The script will use the selected instructions and build a combined mask/value buffer.
|
//The script will use the selected instructions and build a combined mask/value buffer.
|
||||||
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
||||||
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
public class SearchMnemonicsOpsConstScript extends SearchBaseExtended {
|
public class SearchMnemonicsOpsConstScript extends SearchBaseExtended {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
//The script will use the selected instructions and build a combined mask/value buffer.
|
//The script will use the selected instructions and build a combined mask/value buffer.
|
||||||
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
//Memory is then searched looking for this combined value buffer that represents the selected instructions.
|
||||||
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
//This automates the process of searching through memory for a particular ordering of instructions by hand.
|
||||||
//@category Search.InstructionPattern
|
//@category Search.Instruction Pattern
|
||||||
public class SearchMnemonicsOpsNoConstScript extends SearchBaseExtended {
|
public class SearchMnemonicsOpsNoConstScript extends SearchBaseExtended {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
// Sets the current selection based on source file and line number parameters
|
// Sets the current selection based on source file and line number parameters
|
||||||
//@category SourceMapping
|
//@category Source Mapping
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
//Creates a selection in the current program consisting of the sum
|
//Creates a selection in the current program consisting of the sum
|
||||||
//of all function bodies.
|
//of all function bodies.
|
||||||
//@category Selection
|
//@category
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.AddressSet;
|
import ghidra.program.model.address.AddressSet;
|
||||||
|
@ -33,9 +33,9 @@ public class SelectFunctionsScript extends GhidraScript {
|
||||||
functionCount++;
|
functionCount++;
|
||||||
Function f = iter.next();
|
Function f = iter.next();
|
||||||
set.add(f.getBody());
|
set.add(f.getBody());
|
||||||
println("Function Entry: "+f.getEntryPoint());
|
println("Function Entry: " + f.getEntryPoint());
|
||||||
}
|
}
|
||||||
println("Function Count: "+functionCount);
|
println("Function Count: " + functionCount);
|
||||||
createSelection(set);
|
createSelection(set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
// This script displays a table showing the base address of each source map entry
|
// This script displays a table showing the base address of each source map entry
|
||||||
// in the program along with a count of the number of entries starting at the address.
|
// in the program along with a count of the number of entries starting at the address.
|
||||||
// @category SourceMapping
|
// @category Source Mapping
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
@ -28,7 +28,6 @@ import ghidra.program.model.sourcemap.SourceMapEntry;
|
||||||
import ghidra.program.model.sourcemap.SourceMapEntryIterator;
|
import ghidra.program.model.sourcemap.SourceMapEntryIterator;
|
||||||
import ghidra.util.datastruct.Counter;
|
import ghidra.util.datastruct.Counter;
|
||||||
|
|
||||||
|
|
||||||
public class ShowSourceMapEntryStartsScript extends GhidraScript {
|
public class ShowSourceMapEntryStartsScript extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Example skeleton script that iterates over all strings and sets the translation value for each
|
//Example skeleton script that iterates over all strings and sets the translation value for each
|
||||||
//@category Strings
|
//@category Data Types
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.data.StringDataInstance;
|
import ghidra.program.model.data.StringDataInstance;
|
||||||
|
|
|
@ -14,13 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//XOR's the memory of the current program.
|
//XOR's the memory of the current program.
|
||||||
//@category Memory
|
//@category Analysis
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.address.AddressIterator;
|
|
||||||
import ghidra.program.model.address.AddressSet;
|
|
||||||
import ghidra.program.model.address.AddressSetView;
|
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
|
|
||||||
|
@ -32,7 +29,7 @@ public class XorMemoryScript extends GhidraScript {
|
||||||
// default to the current memory block
|
// default to the current memory block
|
||||||
Memory memory = currentProgram.getMemory();
|
Memory memory = currentProgram.getMemory();
|
||||||
MemoryBlock block = memory.getBlock(currentAddress);
|
MemoryBlock block = memory.getBlock(currentAddress);
|
||||||
AddressSetView set = new AddressSet(block.getStart(),block.getEnd());
|
AddressSetView set = new AddressSet(block.getStart(), block.getEnd());
|
||||||
|
|
||||||
if (currentSelection != null && !currentSelection.isEmpty()) {
|
if (currentSelection != null && !currentSelection.isEmpty()) {
|
||||||
set = currentSelection;
|
set = currentSelection;
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
//
|
//
|
||||||
// NOTE: Adresses must be hex values -- without "0x" prefixes.
|
// NOTE: Adresses must be hex values -- without "0x" prefixes.
|
||||||
//
|
//
|
||||||
//@category CustomerSubmission.Analysis
|
//@category Customer Submission.Analysis
|
||||||
//@keybinding alt Z
|
//@keybinding alt Z
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -60,7 +60,8 @@ public class ZapBCTRScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
// first try input as class and search for symbol "<class>::__vtbl"
|
// first try input as class and search for symbol "<class>::__vtbl"
|
||||||
List<Symbol> symbols = currentProgram.getSymbolTable().getSymbols("__vtbl",
|
List<Symbol> symbols = currentProgram.getSymbolTable()
|
||||||
|
.getSymbols("__vtbl",
|
||||||
getNamespace(null, classNameOrAddr));
|
getNamespace(null, classNameOrAddr));
|
||||||
// if symbol found, then vtblAddr is the symbol's address
|
// if symbol found, then vtblAddr is the symbol's address
|
||||||
if (symbols.size() == 1) {
|
if (symbols.size() == 1) {
|
||||||
|
@ -100,7 +101,8 @@ public class ZapBCTRScript extends GhidraScript {
|
||||||
// insert funcName as EOL comment and
|
// insert funcName as EOL comment and
|
||||||
// add a mnemonic ref from instAddr to funcAddr
|
// add a mnemonic ref from instAddr to funcAddr
|
||||||
listing.setComment(instAddr, CommentType.EOL, funcName);
|
listing.setComment(instAddr, CommentType.EOL, funcName);
|
||||||
listing.getInstructionAt(instAddr).addMnemonicReference(funcAddr, RefType.COMPUTED_CALL,
|
listing.getInstructionAt(instAddr)
|
||||||
|
.addMnemonicReference(funcAddr, RefType.COMPUTED_CALL,
|
||||||
SourceType.USER_DEFINED);
|
SourceType.USER_DEFINED);
|
||||||
|
|
||||||
/* old code that replaces the 'bctr' with a 'bl'
|
/* old code that replaces the 'bctr' with a 'bl'
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
##
|
##
|
||||||
# Sets up IOPORT IN/OUT references for the Program
|
# Sets up IOPORT IN/OUT references for the Program
|
||||||
#@category Instructions
|
#@category
|
||||||
#@runtime Jython
|
#@runtime Jython
|
||||||
# Before running this script, you should have created an OVERLAY memory
|
# Before running this script, you should have created an OVERLAY memory
|
||||||
# space called IOMEM, starting at address 0, size 0x10000.
|
# space called IOMEM, starting at address 0, size 0x10000.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
//Use this script to dump the information about the function bit patterns for the
|
//Use this script to dump the information about the function bit patterns for the
|
||||||
// current function to the ghidra console.
|
// current function to the ghidra console.
|
||||||
//@category FunctionStartPatterns
|
//@category Functions
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
//This script dumps information about byte and instructions in neighborhoods around function starts
|
//This script dumps information about byte and instructions in neighborhoods around function starts
|
||||||
//and returns to an XML file
|
//and returns to an XML file
|
||||||
//@category FunctionStartPatterns
|
//@category Functions
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//@category CodeAnalysis
|
//@category
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
//
|
//
|
||||||
// You can also pre-add the COMPUTED_JUMP references to the branch instruction before running the
|
// You can also pre-add the COMPUTED_JUMP references to the branch instruction before running the
|
||||||
// script, and simply put the cursor on the computed branching instruction.
|
// script, and simply put the cursor on the computed branching instruction.
|
||||||
//@category Repair
|
//@category
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -37,10 +37,11 @@ import ghidra.program.model.symbol.*;
|
||||||
|
|
||||||
public class SwitchOverride extends GhidraScript {
|
public class SwitchOverride extends GhidraScript {
|
||||||
|
|
||||||
private Address collectSelectedJumpData(Listing listing,AddressSetView select,ArrayList<Address> destlist) {
|
private Address collectSelectedJumpData(Listing listing, AddressSetView select,
|
||||||
|
ArrayList<Address> destlist) {
|
||||||
Address branchind = null;
|
Address branchind = null;
|
||||||
AddressIterator iter = select.getAddresses(true);
|
AddressIterator iter = select.getAddresses(true);
|
||||||
while(iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Address addr = iter.next();
|
Address addr = iter.next();
|
||||||
Instruction inst = listing.getInstructionAt(addr);
|
Instruction inst = listing.getInstructionAt(addr);
|
||||||
if (isComputedBranchInstruction(inst)) {
|
if (isComputedBranchInstruction(inst)) {
|
||||||
|
@ -91,7 +92,8 @@ public class SwitchOverride extends GhidraScript {
|
||||||
Reference[] referencesFrom = instr.getReferencesFrom();
|
Reference[] referencesFrom = instr.getReferencesFrom();
|
||||||
for (Reference reference : referencesFrom) {
|
for (Reference reference : referencesFrom) {
|
||||||
if (reference.getReferenceType().isCall()) {
|
if (reference.getReferenceType().isCall()) {
|
||||||
Function func = currentProgram.getFunctionManager().getFunctionAt(reference.getToAddress());
|
Function func =
|
||||||
|
currentProgram.getFunctionManager().getFunctionAt(reference.getToAddress());
|
||||||
if (func != null && func.getCallFixup() != null) {
|
if (func != null && func.getCallFixup() != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -101,29 +103,33 @@ public class SwitchOverride extends GhidraScript {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
ArrayList<Address> destlist = new ArrayList<Address>();
|
ArrayList<Address> destlist = new ArrayList<Address>();
|
||||||
Address branchind = null;
|
Address branchind = null;
|
||||||
|
|
||||||
if (currentSelection != null && !currentSelection.isEmpty()) {
|
if (currentSelection != null && !currentSelection.isEmpty()) {
|
||||||
branchind = collectSelectedJumpData(currentProgram.getListing(),currentSelection,destlist);
|
branchind =
|
||||||
} else {
|
collectSelectedJumpData(currentProgram.getListing(), currentSelection, destlist);
|
||||||
branchind = collectPointJumpData(currentProgram.getListing(),currentLocation.getAddress(),destlist);
|
}
|
||||||
|
else {
|
||||||
|
branchind = collectPointJumpData(currentProgram.getListing(),
|
||||||
|
currentLocation.getAddress(), destlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (branchind==null) {
|
if (branchind == null) {
|
||||||
println("Please highlight or place the cursor on the instruction performing the computed jump");
|
println(
|
||||||
|
"Please highlight or place the cursor on the instruction performing the computed jump");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (destlist.size()==0) {
|
if (destlist.size() == 0) {
|
||||||
println("Please highlight destination instructions in addition to instruction performing switch");
|
println(
|
||||||
|
"Please highlight destination instructions in addition to instruction performing switch");
|
||||||
println(" Or put CONDITIONAL_JUMP destination references at the branching instruction");
|
println(" Or put CONDITIONAL_JUMP destination references at the branching instruction");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Function function = this.getFunctionContaining(branchind);
|
Function function = this.getFunctionContaining(branchind);
|
||||||
if (function==null) {
|
if (function == null) {
|
||||||
println("Computed jump instruction must be in a Function body.");
|
println("Computed jump instruction must be in a Function body.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +140,7 @@ public class SwitchOverride extends GhidraScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate an override jumptable
|
// Allocate an override jumptable
|
||||||
JumpTable jumpTab = new JumpTable(branchind,destlist,true);
|
JumpTable jumpTab = new JumpTable(branchind, destlist, true);
|
||||||
jumpTab.writeOverride(function);
|
jumpTab.writeOverride(function);
|
||||||
|
|
||||||
// fixup the body now that there are jump references
|
// fixup the body now that there are jump references
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Annotates an HFS+ attributes b-Tree file.
|
//Annotates an HFS+ attributes b-Tree file.
|
||||||
//@category iOS
|
//@category Apple.iOS
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.app.util.bin.*;
|
import ghidra.app.util.bin.*;
|
||||||
|
@ -180,7 +180,8 @@ public class BTreeAnnotationScript extends GhidraScript {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Data createBTreeHeaderRecord(Program program, BTreeHeaderRecord headerRecord, int offset)
|
private Data createBTreeHeaderRecord(Program program, BTreeHeaderRecord headerRecord,
|
||||||
|
int offset)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Address address = toAddr(offset);
|
Address address = toAddr(offset);
|
||||||
DataType dataType = headerRecord.toDataType();
|
DataType dataType = headerRecord.toDataType();
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
//This script cleans up the disassembly for kext files by locating "Bad Instruction" bookmarks caused by incorrectly defined data in valid code flows.
|
//This script cleans up the disassembly for kext files by locating "Bad Instruction" bookmarks caused by incorrectly defined data in valid code flows.
|
||||||
//@author
|
//@author
|
||||||
//@category iOS
|
//@category Apple.iOS
|
||||||
//@keybinding
|
//@keybinding
|
||||||
//@menupath
|
//@menupath
|
||||||
//@toolbar
|
//@toolbar
|
||||||
|
@ -56,7 +56,7 @@ public class BadInstructionCleanup extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup(Address ba) throws Exception {
|
public void cleanup(Address ba) throws Exception {
|
||||||
|
|
||||||
Program p = currentProgram;
|
Program p = currentProgram;
|
||||||
BookmarkManager bmgr = p.getBookmarkManager();
|
BookmarkManager bmgr = p.getBookmarkManager();
|
||||||
|
@ -79,7 +79,8 @@ public void cleanup(Address ba) throws Exception {
|
||||||
Address paddr = listing.getInstructionBefore(ba).getAddress();
|
Address paddr = listing.getInstructionBefore(ba).getAddress();
|
||||||
RegisterValue rv;
|
RegisterValue rv;
|
||||||
if (paddr != null) {
|
if (paddr != null) {
|
||||||
rv = p.getProgramContext().getRegisterValue(contextReg,
|
rv = p.getProgramContext()
|
||||||
|
.getRegisterValue(contextReg,
|
||||||
paddr);
|
paddr);
|
||||||
p.getProgramContext().setRegisterValue(ba, ba_end, rv);
|
p.getProgramContext().setRegisterValue(ba, ba_end, rv);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +90,8 @@ public void cleanup(Address ba) throws Exception {
|
||||||
Function f = getFunctionBefore(ba);
|
Function f = getFunctionBefore(ba);
|
||||||
if (f != null) {
|
if (f != null) {
|
||||||
CreateFunctionCmd cf = new CreateFunctionCmd(f.getName(), f
|
CreateFunctionCmd cf = new CreateFunctionCmd(f.getName(), f
|
||||||
.getEntryPoint(), null, f.getSymbol().getSource(),
|
.getEntryPoint(),
|
||||||
|
null, f.getSymbol().getSource(),
|
||||||
true, true);
|
true, true);
|
||||||
cf.applyTo(p);
|
cf.applyTo(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//@category iOS
|
//@category Apple.iOS
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Processes Mach-O BIND information.
|
//Processes Mach-O BIND information.
|
||||||
//@category Mac OS X
|
//@category Apple.Mac OS X
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -35,28 +35,29 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
File file = new File( currentProgram.getExecutablePath() );
|
File file = new File(currentProgram.getExecutablePath());
|
||||||
if ( !file.exists() ) {
|
if (!file.exists()) {
|
||||||
file = askFile( "Please select original file used to import this program:", "Original File" );
|
file = askFile("Please select original file used to import this program:",
|
||||||
|
"Original File");
|
||||||
}
|
}
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
popup("File cannot be null");
|
popup("File cannot be null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( !file.exists() ) {
|
if (!file.exists()) {
|
||||||
popup( "Cannot find original binary at \n" + file.getAbsolutePath() );
|
popup("Cannot find original binary at \n" + file.getAbsolutePath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ByteProvider provider = new RandomAccessByteProvider( file ) ;
|
ByteProvider provider = new RandomAccessByteProvider(file);
|
||||||
try {
|
try {
|
||||||
MachHeader header = new MachHeader(provider);
|
MachHeader header = new MachHeader(provider);
|
||||||
header.parse();
|
header.parse();
|
||||||
List<DyldInfoCommand> commands = header.getLoadCommands( DyldInfoCommand.class );
|
List<DyldInfoCommand> commands = header.getLoadCommands(DyldInfoCommand.class);
|
||||||
for ( DyldInfoCommand command : commands ) {
|
for (DyldInfoCommand command : commands) {
|
||||||
if ( monitor.isCancelled() ) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
processCommand( header, provider, command );
|
processCommand(header, provider, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -64,7 +65,8 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processCommand( MachHeader header, ByteProvider provider, DyldInfoCommand command ) throws Exception {
|
private void processCommand(MachHeader header, ByteProvider provider, DyldInfoCommand command)
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
BindState bind = new BindState();
|
BindState bind = new BindState();
|
||||||
bind.header = header;
|
bind.header = header;
|
||||||
|
@ -72,18 +74,19 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
try {
|
try {
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
|
||||||
byte [] commandBytes = provider.readBytes( command.getBindOffset(), command.getBindSize() );
|
byte[] commandBytes =
|
||||||
ByteArrayInputStream byteServer = new ByteArrayInputStream( commandBytes );
|
provider.readBytes(command.getBindOffset(), command.getBindSize());
|
||||||
|
ByteArrayInputStream byteServer = new ByteArrayInputStream(commandBytes);
|
||||||
|
|
||||||
while ( !done ) {
|
while (!done) {
|
||||||
|
|
||||||
if ( monitor.isCancelled() ) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int value = byteServer.read();
|
int value = byteServer.read();
|
||||||
|
|
||||||
if ( value == -1 ) {
|
if (value == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,9 +95,9 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
int opcode = b & DyldInfoCommandConstants.BIND_OPCODE_MASK;
|
int opcode = b & DyldInfoCommandConstants.BIND_OPCODE_MASK;
|
||||||
int immediate = b & DyldInfoCommandConstants.BIND_IMMEDIATE_MASK;
|
int immediate = b & DyldInfoCommandConstants.BIND_IMMEDIATE_MASK;
|
||||||
|
|
||||||
switch ( opcode ) {
|
switch (opcode) {
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_ADD_ADDR_ULEB: {
|
case DyldInfoCommandConstants.BIND_OPCODE_ADD_ADDR_ULEB: {
|
||||||
bind.segmentOffset += uleb128( byteServer );
|
bind.segmentOffset += uleb128(byteServer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND: {
|
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND: {
|
||||||
|
@ -104,18 +107,20 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: {
|
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED: {
|
||||||
bind.doBind();
|
bind.doBind();
|
||||||
bind.segmentOffset += ( immediate * currentProgram.getDefaultPointerSize() ) + currentProgram.getDefaultPointerSize();
|
bind.segmentOffset += (immediate * currentProgram.getDefaultPointerSize()) +
|
||||||
|
currentProgram.getDefaultPointerSize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: {
|
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: {
|
||||||
bind.doBind();
|
bind.doBind();
|
||||||
bind.segmentOffset += uleb128( byteServer ) + currentProgram.getDefaultPointerSize();
|
bind.segmentOffset +=
|
||||||
|
uleb128(byteServer) + currentProgram.getDefaultPointerSize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: {
|
case DyldInfoCommandConstants.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: {
|
||||||
long count = uleb128( byteServer );
|
long count = uleb128(byteServer);
|
||||||
long skip = uleb128( byteServer );
|
long skip = uleb128(byteServer);
|
||||||
for ( int i = 0 ; i < count ; ++i ) {
|
for (int i = 0; i < count; ++i) {
|
||||||
bind.doBind();
|
bind.doBind();
|
||||||
bind.segmentOffset += skip + currentProgram.getDefaultPointerSize();
|
bind.segmentOffset += skip + currentProgram.getDefaultPointerSize();
|
||||||
}
|
}
|
||||||
|
@ -126,41 +131,43 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_ADDEND_SLEB: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_ADDEND_SLEB: {
|
||||||
bind.addend = sleb128( byteServer );
|
bind.addend = sleb128(byteServer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: {
|
||||||
bind.libraryOrdinal = immediate;
|
bind.libraryOrdinal = immediate;
|
||||||
bind.fromDylib = getOrdinalName( bind );
|
bind.fromDylib = getOrdinalName(bind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: {
|
||||||
bind.libraryOrdinal = (int) uleb128( byteServer );
|
bind.libraryOrdinal = (int) uleb128(byteServer);
|
||||||
bind.fromDylib = getOrdinalName( bind );
|
bind.fromDylib = getOrdinalName(bind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: {
|
||||||
//the special ordinals are negative numbers
|
//the special ordinals are negative numbers
|
||||||
if ( immediate == 0 ) {
|
if (immediate == 0) {
|
||||||
bind.libraryOrdinal = 0;
|
bind.libraryOrdinal = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
byte signExtended = (byte) ( DyldInfoCommandConstants.BIND_OPCODE_MASK | immediate );
|
byte signExtended =
|
||||||
|
(byte) (DyldInfoCommandConstants.BIND_OPCODE_MASK | immediate);
|
||||||
bind.libraryOrdinal = signExtended;
|
bind.libraryOrdinal = signExtended;
|
||||||
}
|
}
|
||||||
bind.fromDylib = getOrdinalName( bind );
|
bind.fromDylib = getOrdinalName(bind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: {
|
||||||
bind.segmentIndex = immediate;
|
bind.segmentIndex = immediate;
|
||||||
bind.segmentStartAddress = getSegmentStartAddress( bind );
|
bind.segmentStartAddress = getSegmentStartAddress(bind);
|
||||||
bind.segmentName = getSegmentName( bind );
|
bind.segmentName = getSegmentName(bind);
|
||||||
bind.segmentOffset = uleb128( byteServer );
|
bind.segmentOffset = uleb128(byteServer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: {
|
||||||
bind.symbolName = readString( byteServer );
|
bind.symbolName = readString(byteServer);
|
||||||
if ( ( immediate & DyldInfoCommandConstants.BIND_SYMBOL_FLAGS_WEAK_IMPORT ) != 0 ) {
|
if ((immediate &
|
||||||
|
DyldInfoCommandConstants.BIND_SYMBOL_FLAGS_WEAK_IMPORT) != 0) {
|
||||||
bind.weak = true;
|
bind.weak = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -170,11 +177,11 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
case DyldInfoCommandConstants.BIND_OPCODE_SET_TYPE_IMM: {
|
case DyldInfoCommandConstants.BIND_OPCODE_SET_TYPE_IMM: {
|
||||||
bind.type = immediate;
|
bind.type = immediate;
|
||||||
bind.typeName = getTypeName( bind );
|
bind.typeName = getTypeName(bind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
popup( "unknown bind opcode " + Integer.toHexString( opcode ) );
|
popup("unknown bind opcode " + Integer.toHexString(opcode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,37 +191,37 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readString( ByteArrayInputStream byteServer ) {
|
private String readString(ByteArrayInputStream byteServer) {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
while ( !monitor.isCancelled() ) {
|
while (!monitor.isCancelled()) {
|
||||||
int value = byteServer.read();
|
int value = byteServer.read();
|
||||||
if ( value == -1 ) {
|
if (value == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
byte b = (byte) value;
|
byte b = (byte) value;
|
||||||
if ( b == '\0' ) {
|
if (b == '\0') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer.append( (char) ( b & 0xff ) );
|
buffer.append((char) (b & 0xff));
|
||||||
}
|
}
|
||||||
System.out.println( buffer.toString() );
|
System.out.println(buffer.toString());
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getSegmentStartAddress( BindState bind ) {
|
private long getSegmentStartAddress(BindState bind) {
|
||||||
List<SegmentCommand> segments = bind.header.getLoadCommands( SegmentCommand.class );
|
List<SegmentCommand> segments = bind.header.getLoadCommands(SegmentCommand.class);
|
||||||
SegmentCommand segment = segments.get( bind.segmentIndex );
|
SegmentCommand segment = segments.get(bind.segmentIndex);
|
||||||
return segment.getVMaddress();
|
return segment.getVMaddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSegmentName( BindState bind ) {
|
private String getSegmentName(BindState bind) {
|
||||||
List<SegmentCommand> segments = bind.header.getLoadCommands( SegmentCommand.class );
|
List<SegmentCommand> segments = bind.header.getLoadCommands(SegmentCommand.class);
|
||||||
SegmentCommand segment = segments.get( bind.segmentIndex );
|
SegmentCommand segment = segments.get(bind.segmentIndex);
|
||||||
return segment.getSegmentName();
|
return segment.getSegmentName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTypeName( BindState bind ) {
|
private String getTypeName(BindState bind) {
|
||||||
switch ( bind.type ) {
|
switch (bind.type) {
|
||||||
case DyldInfoCommandConstants.BIND_TYPE_POINTER: {
|
case DyldInfoCommandConstants.BIND_TYPE_POINTER: {
|
||||||
return "pointer";
|
return "pointer";
|
||||||
}
|
}
|
||||||
|
@ -225,11 +232,11 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
return "text_pcrel32";
|
return "text_pcrel32";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException( "unknown type: " + Integer.toHexString( bind.type ) );
|
throw new RuntimeException("unknown type: " + Integer.toHexString(bind.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getOrdinalName( BindState bind ) {
|
private String getOrdinalName(BindState bind) {
|
||||||
switch ( bind.libraryOrdinal ) {
|
switch (bind.libraryOrdinal) {
|
||||||
case DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_SELF: {
|
case DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_SELF: {
|
||||||
return "this-image";
|
return "this-image";
|
||||||
}
|
}
|
||||||
|
@ -240,14 +247,15 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
return "flat-namespace";
|
return "flat-namespace";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( bind.libraryOrdinal < DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_FLAT_LOOKUP ) {
|
if (bind.libraryOrdinal < DyldInfoCommandConstants.BIND_SPECIAL_DYLIB_FLAT_LOOKUP) {
|
||||||
return "unknown special ordinal" + Integer.toHexString( bind.libraryOrdinal );
|
return "unknown special ordinal" + Integer.toHexString(bind.libraryOrdinal);
|
||||||
}
|
}
|
||||||
List<DynamicLibraryCommand> dylibCommands = bind.header.getLoadCommands( DynamicLibraryCommand.class );
|
List<DynamicLibraryCommand> dylibCommands =
|
||||||
if ( bind.libraryOrdinal > dylibCommands.size() ) {
|
bind.header.getLoadCommands(DynamicLibraryCommand.class);
|
||||||
return "library ordinal out of range" + Integer.toHexString( bind.libraryOrdinal );
|
if (bind.libraryOrdinal > dylibCommands.size()) {
|
||||||
|
return "library ordinal out of range" + Integer.toHexString(bind.libraryOrdinal);
|
||||||
}
|
}
|
||||||
DynamicLibraryCommand dylibCommand = dylibCommands.get( bind.libraryOrdinal - 1 );
|
DynamicLibraryCommand dylibCommand = dylibCommands.get(bind.libraryOrdinal - 1);
|
||||||
DynamicLibrary dynamicLibrary = dylibCommand.getDynamicLibrary();
|
DynamicLibrary dynamicLibrary = dylibCommand.getDynamicLibrary();
|
||||||
LoadCommandString name = dynamicLibrary.getName();
|
LoadCommandString name = dynamicLibrary.getName();
|
||||||
return name.getString();
|
return name.getString();
|
||||||
|
@ -256,15 +264,15 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
/**
|
/**
|
||||||
* Unsigned Little-endian Base-128
|
* Unsigned Little-endian Base-128
|
||||||
*/
|
*/
|
||||||
private long uleb128( ByteArrayInputStream byteServer ) throws Exception {
|
private long uleb128(ByteArrayInputStream byteServer) throws Exception {
|
||||||
long result = 0;
|
long result = 0;
|
||||||
int bit = 0;
|
int bit = 0;
|
||||||
|
|
||||||
while ( !monitor.isCancelled() ) {
|
while (!monitor.isCancelled()) {
|
||||||
|
|
||||||
int value = byteServer.read();
|
int value = byteServer.read();
|
||||||
|
|
||||||
if ( value == -1 ) {
|
if (value == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,16 +280,16 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
|
|
||||||
long slice = b & 0x7f;
|
long slice = b & 0x7f;
|
||||||
|
|
||||||
if ( ( b & 0x80 ) == 0x80 ) {//if upper bit is set
|
if ((b & 0x80) == 0x80) {//if upper bit is set
|
||||||
if ( bit >= 64 || slice << bit >> bit != slice ) {//then left shift and right shift
|
if (bit >= 64 || slice << bit >> bit != slice) {//then left shift and right shift
|
||||||
throw new RuntimeException( "uleb128 too big" );
|
throw new RuntimeException("uleb128 too big");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result |= ( slice << bit );
|
result |= (slice << bit);
|
||||||
bit += 7;
|
bit += 7;
|
||||||
|
|
||||||
if ( ( b & 0x80 ) == 0 ) {//if upper bit NOT set, then we are done
|
if ((b & 0x80) == 0) {//if upper bit NOT set, then we are done
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,23 +299,23 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
/**
|
/**
|
||||||
* Signed Little-endian Base-128
|
* Signed Little-endian Base-128
|
||||||
*/
|
*/
|
||||||
private long sleb128( ByteArrayInputStream byteServer ) throws Exception {
|
private long sleb128(ByteArrayInputStream byteServer) throws Exception {
|
||||||
long result = 0;
|
long result = 0;
|
||||||
int bit = 0;
|
int bit = 0;
|
||||||
while ( !monitor.isCancelled() ) {
|
while (!monitor.isCancelled()) {
|
||||||
|
|
||||||
int value = byteServer.read();
|
int value = byteServer.read();
|
||||||
|
|
||||||
if ( value == -1 ) {
|
if (value == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte nextByte = (byte) value;
|
byte nextByte = (byte) value;
|
||||||
|
|
||||||
result |= ( ( nextByte & 0x7f ) << bit );
|
result |= ((nextByte & 0x7f) << bit);
|
||||||
bit += 7;
|
bit += 7;
|
||||||
|
|
||||||
if ( ( nextByte & 0x80 ) == 0 ) {
|
if ((nextByte & 0x80) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,51 +347,51 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
|
|
||||||
String sectionName = "no section";
|
String sectionName = "no section";
|
||||||
List<Section> sections = header.getAllSections();
|
List<Section> sections = header.getAllSections();
|
||||||
for ( Section section : sections ) {
|
for (Section section : sections) {
|
||||||
long start = section.getAddress();
|
long start = section.getAddress();
|
||||||
long end = section.getAddress() + section.getSize();
|
long end = section.getAddress() + section.getSize();
|
||||||
if ( sectionAddress.getOffset() >= start && sectionAddress.getOffset() < end ) {
|
if (sectionAddress.getOffset() >= start && sectionAddress.getOffset() < end) {
|
||||||
sectionName = section.getSectionName();
|
sectionName = section.getSectionName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = new File( fromDylib );
|
File file = new File(fromDylib);
|
||||||
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
buffer.append( segmentName );
|
buffer.append(segmentName);
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append(StringUtilities.pad(sectionName, ' ', -20));
|
buffer.append(StringUtilities.pad(sectionName, ' ', -20));
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( sectionAddress );
|
buffer.append(sectionAddress);
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( typeName );
|
buffer.append(typeName);
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( weak );
|
buffer.append(weak);
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( addend );
|
buffer.append(addend);
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append(StringUtilities.pad(file.getName(), ' ', -20));
|
buffer.append(StringUtilities.pad(file.getName(), ' ', -20));
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( symbolName );
|
buffer.append(symbolName);
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
buffer.append( ' ' );
|
buffer.append(' ');
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void doBind() throws Exception {
|
void doBind() throws Exception {
|
||||||
monitor.setMessage( "Performing bind: " + symbolName );
|
monitor.setMessage("Performing bind: " + symbolName);
|
||||||
|
|
||||||
SymbolIterator symbolIterator = currentProgram.getSymbolTable().getSymbols( symbolName );
|
SymbolIterator symbolIterator = currentProgram.getSymbolTable().getSymbols(symbolName);
|
||||||
|
|
||||||
if ( !symbolIterator.hasNext() ) {
|
if (!symbolIterator.hasNext()) {
|
||||||
printerr( "Not found: " + symbolName );
|
printerr("Not found: " + symbolName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,22 +399,25 @@ public class MachoProcessBindScript extends GhidraScript {
|
||||||
|
|
||||||
long offset = symbol.getAddress().getOffset();
|
long offset = symbol.getAddress().getOffset();
|
||||||
|
|
||||||
DataConverter converter = DataConverter.getInstance(currentProgram.getLanguage().isBigEndian());
|
DataConverter converter =
|
||||||
|
DataConverter.getInstance(currentProgram.getLanguage().isBigEndian());
|
||||||
|
|
||||||
if ( currentProgram.getDefaultPointerSize() == 8 ) {
|
if (currentProgram.getDefaultPointerSize() == 8) {
|
||||||
setBytes( getAddress(), converter.getBytes( offset ) );
|
setBytes(getAddress(), converter.getBytes(offset));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setBytes( getAddress(), converter.getBytes( (int)offset ) );
|
setBytes(getAddress(), converter.getBytes((int) offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference reference = currentProgram.getReferenceManager().addMemoryReference( getAddress(), symbol.getAddress(), RefType.READ, SourceType.IMPORTED, 0 );
|
Reference reference = currentProgram.getReferenceManager()
|
||||||
currentProgram.getReferenceManager().setPrimary( reference, true );
|
.addMemoryReference(getAddress(), symbol.getAddress(), RefType.READ,
|
||||||
|
SourceType.IMPORTED, 0);
|
||||||
|
currentProgram.getReferenceManager().setPrimary(reference, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address getAddress() {
|
Address getAddress() {
|
||||||
long result = segmentStartAddress + segmentOffset;//TODO
|
long result = segmentStartAddress + segmentOffset;//TODO
|
||||||
Address sectionAddress = toAddr( result & 0xffffffffL );
|
Address sectionAddress = toAddr(result & 0xffffffffL);
|
||||||
return sectionAddress;
|
return sectionAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Pulls symbol name through pointer references.
|
//Pulls symbol name through pointer references.
|
||||||
//@category Mac OS X
|
//@category Apple.Mac OS X
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -97,7 +97,8 @@ public class PointerPullerScript extends GhidraScript {
|
||||||
}
|
}
|
||||||
Namespace nameSpace = getNamespace(null, nameSpaceName);
|
Namespace nameSpace = getNamespace(null, nameSpaceName);
|
||||||
if (nameSpace == null) {
|
if (nameSpace == null) {
|
||||||
nameSpace = currentProgram.getSymbolTable().createNameSpace(null, nameSpaceName,
|
nameSpace = currentProgram.getSymbolTable()
|
||||||
|
.createNameSpace(null, nameSpaceName,
|
||||||
SourceType.ANALYSIS);
|
SourceType.ANALYSIS);
|
||||||
}
|
}
|
||||||
return nameSpace;
|
return nameSpace;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -14,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//@category References
|
//@category
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -23,14 +22,14 @@ import ghidra.program.model.listing.CodeUnit;
|
||||||
import ghidra.program.model.listing.Listing;
|
import ghidra.program.model.listing.Listing;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
|
|
||||||
|
|
||||||
public class RemoveAllOffcutReferencesScript extends GhidraScript {
|
public class RemoveAllOffcutReferencesScript extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
Listing listing = currentProgram.getListing();
|
Listing listing = currentProgram.getListing();
|
||||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||||
AddressIterator iterator = referenceManager.getReferenceDestinationIterator(currentProgram.getMinAddress(), true);
|
AddressIterator iterator =
|
||||||
|
referenceManager.getReferenceDestinationIterator(currentProgram.getMinAddress(), true);
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
|
@ -39,7 +38,7 @@ public class RemoveAllOffcutReferencesScript extends GhidraScript {
|
||||||
CodeUnit codeUnit = listing.getCodeUnitContaining(address);
|
CodeUnit codeUnit = listing.getCodeUnitContaining(address);
|
||||||
if (codeUnit != null) {
|
if (codeUnit != null) {
|
||||||
if (!codeUnit.getMinAddress().equals(address)) {
|
if (!codeUnit.getMinAddress().equals(address)) {
|
||||||
monitor.setMessage("Removing offcut reference at "+address);
|
monitor.setMessage("Removing offcut reference at " + address);
|
||||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||||
while (referencesTo.hasNext()) {
|
while (referencesTo.hasNext()) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
//Removes any offcut references to the current code unit.
|
//Removes any offcut references to the current code unit.
|
||||||
//@category References
|
//@category
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -29,38 +28,38 @@ public class RemoveOffcutReferenceToCurrentInstructionScript extends GhidraScrip
|
||||||
|
|
||||||
Instruction instruction = getInstructionAt(currentAddress);
|
Instruction instruction = getInstructionAt(currentAddress);
|
||||||
|
|
||||||
if ( instruction != null ) {
|
if (instruction != null) {
|
||||||
removeReferences( instruction );
|
removeReferences(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
Data data = getDataAt(currentAddress);
|
Data data = getDataAt(currentAddress);
|
||||||
|
|
||||||
if ( data != null ) {
|
if (data != null) {
|
||||||
removeReferences( data );
|
removeReferences(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeReferences(CodeUnit codeUnit) {
|
private void removeReferences(CodeUnit codeUnit) {
|
||||||
Address address = currentAddress.add( 1 );
|
Address address = currentAddress.add(1);
|
||||||
|
|
||||||
while ( address.compareTo( codeUnit.getMaxAddress() ) <= 0) {
|
while (address.compareTo(codeUnit.getMaxAddress()) <= 0) {
|
||||||
|
|
||||||
if ( monitor.isCancelled() ) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference [] referencesTo = getReferencesTo(address);
|
Reference[] referencesTo = getReferencesTo(address);
|
||||||
|
|
||||||
for ( Reference reference : referencesTo ) {
|
for (Reference reference : referencesTo) {
|
||||||
|
|
||||||
if ( monitor.isCancelled() ) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeReference(reference);
|
removeReference(reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
address = address.add( 1 );
|
address = address.add(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
//Resolves relative references computed off EBX.
|
//Resolves relative references computed off EBX.
|
||||||
//This will resolve references to strings in the "__cstring" section.
|
//This will resolve references to strings in the "__cstring" section.
|
||||||
//@category Mac OS X
|
//@category Apple.Mac OS X
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -38,19 +37,19 @@ public class ResolveReferencesRelativeToEbxScript extends GhidraScript {
|
||||||
|
|
||||||
FunctionIterator functions = currentProgram.getListing().getFunctions(true);
|
FunctionIterator functions = currentProgram.getListing().getFunctions(true);
|
||||||
|
|
||||||
while ( functions.hasNext() ) {
|
while (functions.hasNext()) {
|
||||||
|
|
||||||
if ( monitor.isCancelled() ) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Function function = functions.next();
|
Function function = functions.next();
|
||||||
|
|
||||||
monitor.setMessage( function.getName() );
|
monitor.setMessage(function.getName());
|
||||||
|
|
||||||
loopOverInstructionsInFunction( function );
|
loopOverInstructionsInFunction(function);
|
||||||
|
|
||||||
function = getFunctionAfter( function );
|
function = getFunctionAfter(function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,49 +58,53 @@ public class ResolveReferencesRelativeToEbxScript extends GhidraScript {
|
||||||
|
|
||||||
long ebx = -1;
|
long ebx = -1;
|
||||||
|
|
||||||
InstructionIterator instructions = currentProgram.getListing().getInstructions( function.getBody(), true ) ;
|
InstructionIterator instructions =
|
||||||
|
currentProgram.getListing().getInstructions(function.getBody(), true);
|
||||||
|
|
||||||
while ( instructions.hasNext() ) {
|
while (instructions.hasNext()) {
|
||||||
|
|
||||||
Instruction instruction = instructions.next();
|
Instruction instruction = instructions.next();
|
||||||
|
|
||||||
if ( monitor.isCancelled() ) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ebx == -1 ) {
|
if (ebx == -1) {
|
||||||
ebx = getValueForEBX( instruction );
|
ebx = getValueForEBX(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ebx == -1 ) {
|
if (ebx == -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0 ; i < instruction.getNumOperands() ; ++i ) {
|
for (int i = 0; i < instruction.getNumOperands(); ++i) {
|
||||||
|
|
||||||
Object [] opObjects = instruction.getOpObjects(i);
|
Object[] opObjects = instruction.getOpObjects(i);
|
||||||
|
|
||||||
if ( opObjects.length == 2 ) {
|
if (opObjects.length == 2) {
|
||||||
|
|
||||||
if (opObjects[ 0 ] instanceof Scalar && opObjects[ 1 ] instanceof Register ) {
|
if (opObjects[0] instanceof Scalar && opObjects[1] instanceof Register) {
|
||||||
|
|
||||||
Scalar scalar = (Scalar) opObjects[ 0 ];
|
Scalar scalar = (Scalar) opObjects[0];
|
||||||
|
|
||||||
Register register = (Register) opObjects[ 1 ];
|
Register register = (Register) opObjects[1];
|
||||||
|
|
||||||
if ( register.equals( EBX ) ) {
|
if (register.equals(EBX)) {
|
||||||
|
|
||||||
Address address = toAddr( (ebx + scalar.getUnsignedValue()) & Conv.INT_MASK );
|
Address address =
|
||||||
|
toAddr((ebx + scalar.getUnsignedValue()) & Conv.INT_MASK);
|
||||||
|
|
||||||
if ( isValid( address ) ) {
|
if (isValid(address)) {
|
||||||
|
|
||||||
removeReferencesFrom(instruction);
|
removeReferencesFrom(instruction);
|
||||||
|
|
||||||
Reference reference = createMemoryReference( instruction, 1, address, RefType.DATA );
|
Reference reference =
|
||||||
|
createMemoryReference(instruction, 1, address, RefType.DATA);
|
||||||
|
|
||||||
setReferencePrimary( reference );
|
setReferencePrimary(reference);
|
||||||
|
|
||||||
println( "Creating reference from " + instruction.getMinAddress() + " to " + address );
|
println("Creating reference from " + instruction.getMinAddress() +
|
||||||
|
" to " + address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,43 +115,43 @@ public class ResolveReferencesRelativeToEbxScript extends GhidraScript {
|
||||||
|
|
||||||
private boolean isValid(Address address) {
|
private boolean isValid(Address address) {
|
||||||
|
|
||||||
Instruction instruction = getInstructionContaining( address );
|
Instruction instruction = getInstructionContaining(address);
|
||||||
if ( instruction != null ) {
|
if (instruction != null) {
|
||||||
Address min = instruction.getMinAddress();
|
Address min = instruction.getMinAddress();
|
||||||
if ( address.compareTo( min ) > 0 ) {
|
if (address.compareTo(min) > 0) {
|
||||||
return false; //off-cut
|
return false; //off-cut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Data data = getDataContaining( address );
|
Data data = getDataContaining(address);
|
||||||
if ( data != null ) {
|
if (data != null) {
|
||||||
Address min = data.getMinAddress();
|
Address min = data.getMinAddress();
|
||||||
if ( address.compareTo( min ) > 0 ) {
|
if (address.compareTo(min) > 0) {
|
||||||
return false; //off-cut
|
return false; //off-cut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentProgram.getMemory().contains( address );
|
return currentProgram.getMemory().contains(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeReferencesFrom(Instruction instruction) {
|
private void removeReferencesFrom(Instruction instruction) {
|
||||||
Reference [] referencesFrom = instruction.getReferencesFrom();
|
Reference[] referencesFrom = instruction.getReferencesFrom();
|
||||||
for (Reference reference : referencesFrom) {
|
for (Reference reference : referencesFrom) {
|
||||||
removeReference( reference );
|
removeReference(reference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getValueForEBX(Instruction instruction) {
|
private long getValueForEBX(Instruction instruction) {
|
||||||
|
|
||||||
if ( instruction.getMnemonicString().equals( "CALL" ) ) {
|
if (instruction.getMnemonicString().equals("CALL")) {
|
||||||
|
|
||||||
Address nextInstructionAddress = instruction.getMaxAddress().add( 1 );
|
Address nextInstructionAddress = instruction.getMaxAddress().add(1);
|
||||||
|
|
||||||
Reference [] referencesFrom = instruction.getReferencesFrom();
|
Reference[] referencesFrom = instruction.getReferencesFrom();
|
||||||
|
|
||||||
if ( referencesFrom.length == 1) {
|
if (referencesFrom.length == 1) {
|
||||||
|
|
||||||
if ( referencesFrom[0].getToAddress().equals( nextInstructionAddress ) ) {
|
if (referencesFrom[0].getToAddress().equals(nextInstructionAddress)) {
|
||||||
|
|
||||||
return nextInstructionAddress.getOffset();
|
return nextInstructionAddress.getOffset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
/* ###
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
//Upgrade DEX program(s) that have function prototypes layed down prior to Ghidra 7.1
|
|
||||||
//@category Upgrade
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
|
|
||||||
import ghidra.app.script.GhidraScript;
|
|
||||||
import ghidra.framework.model.*;
|
|
||||||
import ghidra.framework.plugintool.PluginTool;
|
|
||||||
import ghidra.program.model.address.AddressSpace;
|
|
||||||
import ghidra.program.model.data.FunctionDefinitionDataType;
|
|
||||||
import ghidra.program.model.lang.*;
|
|
||||||
import ghidra.program.model.listing.*;
|
|
||||||
import ghidra.program.model.pcode.Varnode;
|
|
||||||
import ghidra.program.model.symbol.SourceType;
|
|
||||||
import ghidra.util.exception.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* There was a major rearrangement of registers in the Dalvik.slaspec from 7.0 -> 7.1 which invalidates function prototypes
|
|
||||||
* laid down by "Android DEX Header Format" analyzer. This script repairs the prototypes to match the new register layout
|
|
||||||
* If run with a Program already up, the script will make all the changes, letting the user decide if they want to
|
|
||||||
* save (or undo) the changes. If the script is run from an empty code browser, it will search for all Dalvik programs
|
|
||||||
* in the current project and automatically upgrade and save the function prototypes.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class UpgradeDexToGhidra71Script extends GhidraScript {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() throws Exception {
|
|
||||||
|
|
||||||
if ( currentProgram != null ) {
|
|
||||||
processProgram(currentProgram);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginTool tool = state.getTool();
|
|
||||||
Project project = tool.getProject();
|
|
||||||
ProjectData projectData = project.getProjectData();
|
|
||||||
DomainFolder rootFolder = projectData.getRootFolder();
|
|
||||||
recurseProjectFolder( rootFolder );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recurseProjectFolder( DomainFolder domainFolder ) throws Exception {
|
|
||||||
DomainFile[] files = domainFolder.getFiles();
|
|
||||||
for ( DomainFile domainFile : files ) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
try {
|
|
||||||
processDomainFile( domainFile );
|
|
||||||
} catch(Exception ex) {
|
|
||||||
printerr(ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DomainFolder[] folders = domainFolder.getFolders();
|
|
||||||
for ( DomainFolder folder : folders ) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
recurseProjectFolder( folder );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processDomainFile(DomainFile domainFile ) throws Exception {
|
|
||||||
Map<String, String> metadata = domainFile.getMetadata();
|
|
||||||
if (metadata == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String formatString = metadata.get("Executable Format");
|
|
||||||
if (formatString == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!formatString.equals("Dalvik Executable (DEX)")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DomainObject domainObject = domainFile.getDomainObject(this, true, true, monitor);
|
|
||||||
try {
|
|
||||||
Program program = (Program) domainObject;
|
|
||||||
processProgram(program);
|
|
||||||
saveProgram(program);
|
|
||||||
} finally {
|
|
||||||
domainObject.release(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processProgram(Program program) throws CancelledException {
|
|
||||||
println("Updating program: "+program.getName());
|
|
||||||
int id = program.startTransaction("Update DEX parameters");
|
|
||||||
boolean success = false;
|
|
||||||
try {
|
|
||||||
for (Function func : program.getFunctionManager().getFunctions(true)) {
|
|
||||||
monitor.checkCancelled();
|
|
||||||
processFunction(func);
|
|
||||||
}
|
|
||||||
success = true;
|
|
||||||
} finally {
|
|
||||||
program.endTransaction(id, success);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processFunction(Function func) {
|
|
||||||
monitor.setMessage("Updating: "+func.getName());
|
|
||||||
FunctionDefinitionDataType sig = new FunctionDefinitionDataType(func,false);
|
|
||||||
try {
|
|
||||||
sig.setCallingConvention(CompilerSpec.CALLING_CONVENTION_stdcall);
|
|
||||||
}
|
|
||||||
catch (InvalidInputException e) {
|
|
||||||
throw new AssertException(e);
|
|
||||||
}
|
|
||||||
func.setCustomVariableStorage(false);
|
|
||||||
ApplyFunctionSignatureCmd cmd = new ApplyFunctionSignatureCmd(func.getEntryPoint(),sig,SourceType.ANALYSIS);
|
|
||||||
cmd.applyTo(func.getProgram());
|
|
||||||
|
|
||||||
Program program = func.getProgram();
|
|
||||||
Language language = program.getLanguage();
|
|
||||||
AddressSpace registerSpace = program.getAddressFactory().getRegisterSpace();
|
|
||||||
Variable[] localVariables = func.getLocalVariables();
|
|
||||||
|
|
||||||
for (Variable var : localVariables) {
|
|
||||||
Varnode varnode = var.getFirstStorageVarnode();
|
|
||||||
if (!varnode.isRegister()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (varnode.getOffset() >= 0x1000)
|
|
||||||
{
|
|
||||||
continue; // Already converted
|
|
||||||
}
|
|
||||||
long offset = varnode.getOffset() + 0x1000 - 8;
|
|
||||||
int size = varnode.getSize();
|
|
||||||
Register localRegister = language.getRegister(registerSpace, offset, size);
|
|
||||||
try {
|
|
||||||
LocalVariableImpl newlocal = new LocalVariableImpl( var.getName(), 0, var.getDataType(), localRegister, func.getProgram() );
|
|
||||||
func.removeVariable(var);
|
|
||||||
func.addLocalVariable(newlocal, SourceType.ANALYSIS);
|
|
||||||
} catch (InvalidInputException e) {
|
|
||||||
} catch (DuplicateNameException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,7 +18,7 @@
|
||||||
// See binutils' c++filt for more information on supported options.
|
// See binutils' c++filt for more information on supported options.
|
||||||
|
|
||||||
//
|
//
|
||||||
//@category Examples.Demangler
|
//@category Demangler
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.app.util.demangler.DemangledObject;
|
import ghidra.app.util.demangler.DemangledObject;
|
||||||
import ghidra.app.util.demangler.MangledContext;
|
import ghidra.app.util.demangler.MangledContext;
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
// script needs the address of that value to calculate
|
// script needs the address of that value to calculate
|
||||||
// the symbol table's start address.
|
// the symbol table's start address.
|
||||||
//
|
//
|
||||||
// @category CustomerSubmission.vxWorks
|
// @category Customer Submission.vxWorks
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
// script needs the address of that value to calculate
|
// script needs the address of that value to calculate
|
||||||
// the symbol table's start address.
|
// the symbol table's start address.
|
||||||
//
|
//
|
||||||
// @category CustomerSubmission.vxWorks
|
// @category Customer Submission.vxWorks
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
// - Modify getVxSymbolClass() to recognize your program's VxWorks
|
// - Modify getVxSymbolClass() to recognize your program's VxWorks
|
||||||
// symbol table entry structure, if necessary
|
// symbol table entry structure, if necessary
|
||||||
//
|
//
|
||||||
// @category VxWorks
|
// @category Customer Submission.vxWorks
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
# - MEMORY_REGION:0x1234abcd
|
# - MEMORY_REGION:0x1234abcd
|
||||||
# Omitting the address space or memory region specifier from the address will result in the function or label being created in the default address space.
|
# Omitting the address space or memory region specifier from the address will result in the function or label being created in the default address space.
|
||||||
# @author unkown; edited by matedealer <git@matedealer.de>
|
# @author unkown; edited by matedealer <git@matedealer.de>
|
||||||
# @category Data
|
# @category Import
|
||||||
# @runtime Jython
|
# @runtime Jython
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
//Loads the same file as binary using each of the DATA languages.
|
//Loads the same file as binary using each of the DATA languages.
|
||||||
//Any DATA language can be used with any size file.
|
//Any DATA language can be used with any size file.
|
||||||
//The only issues are the POINTER sizes and does the file fit in the memory space.
|
//The only issues are the POINTER sizes and does the file fit in the memory space.
|
||||||
//@category Processor.DATA
|
//@category Languages
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import ghidra.app.script.GhidraScript;
|
import ghidra.app.script.GhidraScript;
|
||||||
import ghidra.language.data.DataLanguageHelper;
|
import ghidra.language.data.DataLanguageHelper;
|
||||||
|
@ -24,37 +26,41 @@ import ghidra.program.model.lang.LanguageCompilerSpecPair;
|
||||||
import ghidra.program.model.lang.LanguageService;
|
import ghidra.program.model.lang.LanguageService;
|
||||||
import ghidra.program.util.DefaultLanguageService;
|
import ghidra.program.util.DefaultLanguageService;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class LoadDataScript extends GhidraScript {
|
public class LoadDataScript extends GhidraScript {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run( ) throws Exception {
|
public void run() throws Exception {
|
||||||
|
|
||||||
LanguageService languageService = DefaultLanguageService.getLanguageService( );
|
LanguageService languageService = DefaultLanguageService.getLanguageService();
|
||||||
|
|
||||||
LanguageCompilerSpecPair dataBE16 = DataLanguageHelper.getLanguage( languageService, 16, true );
|
LanguageCompilerSpecPair dataBE16 =
|
||||||
LanguageCompilerSpecPair dataBE32 = DataLanguageHelper.getLanguage( languageService, 32, true );
|
DataLanguageHelper.getLanguage(languageService, 16, true);
|
||||||
LanguageCompilerSpecPair dataBE64 = DataLanguageHelper.getLanguage( languageService, 64, true );
|
LanguageCompilerSpecPair dataBE32 =
|
||||||
|
DataLanguageHelper.getLanguage(languageService, 32, true);
|
||||||
|
LanguageCompilerSpecPair dataBE64 =
|
||||||
|
DataLanguageHelper.getLanguage(languageService, 64, true);
|
||||||
|
|
||||||
LanguageCompilerSpecPair dataLE16 = DataLanguageHelper.getLanguage( languageService, 16, false );
|
LanguageCompilerSpecPair dataLE16 =
|
||||||
LanguageCompilerSpecPair dataLE32 = DataLanguageHelper.getLanguage( languageService, 32, false );
|
DataLanguageHelper.getLanguage(languageService, 16, false);
|
||||||
LanguageCompilerSpecPair dataLE64 = DataLanguageHelper.getLanguage( languageService, 64, false );
|
LanguageCompilerSpecPair dataLE32 =
|
||||||
|
DataLanguageHelper.getLanguage(languageService, 32, false);
|
||||||
|
LanguageCompilerSpecPair dataLE64 =
|
||||||
|
DataLanguageHelper.getLanguage(languageService, 64, false);
|
||||||
|
|
||||||
File file = askFile( "Select DATA File", "OK" );
|
File file = askFile("Select DATA File", "OK");
|
||||||
if ( file == null ) {
|
if (file == null) {
|
||||||
printerr( "No file selected, ending script." );
|
printerr("No file selected, ending script.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
openProgram( importFileAsBinary( file, dataBE16.getLanguage( ), dataBE16.getCompilerSpec( ) ) );
|
openProgram(importFileAsBinary(file, dataBE16.getLanguage(), dataBE16.getCompilerSpec()));
|
||||||
openProgram( importFileAsBinary( file, dataLE16.getLanguage( ), dataLE16.getCompilerSpec( ) ) );
|
openProgram(importFileAsBinary(file, dataLE16.getLanguage(), dataLE16.getCompilerSpec()));
|
||||||
|
|
||||||
openProgram( importFileAsBinary( file, dataBE32.getLanguage( ), dataBE32.getCompilerSpec( ) ) );
|
openProgram(importFileAsBinary(file, dataBE32.getLanguage(), dataBE32.getCompilerSpec()));
|
||||||
openProgram( importFileAsBinary( file, dataLE32.getLanguage( ), dataLE32.getCompilerSpec( ) ) );
|
openProgram(importFileAsBinary(file, dataLE32.getLanguage(), dataLE32.getCompilerSpec()));
|
||||||
|
|
||||||
openProgram( importFileAsBinary( file, dataBE64.getLanguage( ), dataBE64.getCompilerSpec( ) ) );
|
openProgram(importFileAsBinary(file, dataBE64.getLanguage(), dataBE64.getCompilerSpec()));
|
||||||
openProgram( importFileAsBinary( file, dataLE64.getLanguage( ), dataLE64.getCompilerSpec( ) ) );
|
openProgram(importFileAsBinary(file, dataLE64.getLanguage(), dataLE64.getCompilerSpec()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue