Created
January 20, 2025 11:07
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//decrypt keystream XOR data given the address of the key and of the cipher | |
//@author | |
//@category Functions | |
//@keybinding | |
//@menupath | |
//@toolbar | |
//@runtime Java | |
import ghidra.app.script.GhidraScript; | |
import ghidra.util.exception.InvalidInputException; | |
import ghidra.program.model.address.Address; | |
import ghidra.program.model.symbol.SourceType; | |
import ghidra.program.model.symbol.Symbol; | |
import javax.swing.JOptionPane; | |
import javax.swing.JPanel; | |
import javax.swing.JTextField; | |
import javax.swing.JLabel; | |
import javax.swing.JCheckBox; | |
import java.awt.GridLayout; | |
public class XORcustom extends GhidraScript { | |
@Override | |
public void run() throws Exception { | |
// Create a panel for the dialog box with separate fields | |
JPanel panel = new JPanel(new GridLayout(5, 2)); | |
// Add fields for key address and key length | |
JLabel keyAddressLabel = new JLabel("Key Address (Hex):"); | |
JTextField keyAddressField = new JTextField(currentLocation!=null?currentLocation.getAddress().toString():""); | |
JLabel keyLengthLabel = new JLabel("Key Length (Decimal):"); | |
JTextField keyLengthField = new JTextField("16"); // Default value | |
JLabel cipherAddressLabel = new JLabel("Cipher Address"); | |
JTextField cipherAddressField = new JTextField(); | |
JLabel cipherLengthLabel = new JLabel("Cipher Length (Decimal)"); | |
JTextField cipherLengthField = new JTextField("16"); // Default value | |
JCheckBox renameCheckBox = new JCheckBox("Rename symbol"); | |
// Add components to the panel | |
panel.add(keyAddressLabel); | |
panel.add(keyAddressField); | |
panel.add(keyLengthLabel); | |
panel.add(keyLengthField); | |
panel.add(cipherAddressLabel); | |
panel.add(cipherAddressField); | |
panel.add(cipherLengthLabel); | |
panel.add(cipherLengthField); | |
panel.add(renameCheckBox); | |
// Show dialog box to get user input | |
int result = JOptionPane.showConfirmDialog(null, panel, "Custom XOR decrypt", | |
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); | |
if (result == JOptionPane.OK_OPTION) { | |
try { | |
// Parse and validate | |
String keyAddressInput = keyAddressField.getText().trim(); | |
String keyLengthInput = keyLengthField.getText().trim(); | |
String cipherAddressInput = cipherAddressField.getText().trim(); | |
String cipherLengthInput = cipherLengthField.getText().trim(); | |
boolean rename = renameCheckBox.isSelected(); | |
// Convert fields | |
Address keyAddress = toAddr(parseHexAddress(keyAddressInput)); | |
Address cipherAddress = toAddr(parseHexAddress(cipherAddressInput)); | |
int keyLength = Integer.parseInt(keyLengthInput); | |
int cipherLength = Integer.parseInt(cipherLengthInput); | |
// Extract and display the key data from memory | |
byte[] keyData = getBytes(keyAddress, keyLength); | |
byte[] cipherData = getBytes(cipherAddress,cipherLength); | |
char[] res =new char[cipherData.length]; | |
for(int i=0;i<cipherData.length;++i) { | |
res[i]=(char)((cipherData[i]^keyData[i])); | |
} | |
setPreComment(cipherAddress,String.valueOf(res)); | |
if (rename) { | |
Symbol sym = currentProgram.getSymbolTable().getPrimarySymbol(cipherAddress); | |
sym.setName(String.valueOf(res),SourceType.USER_DEFINED); | |
} | |
} catch (NumberFormatException e) { | |
println("Error: Invalid length format."); | |
} catch (InvalidInputException e) { | |
println("Error: Invalid address format."); | |
} catch (Exception e) { | |
println("Unexpected error: " + e.getMessage()); | |
} | |
} | |
} | |
// Helper function to parse a hex string and return its long value | |
private long parseHexAddress(String hexAddress) throws InvalidInputException { | |
if (hexAddress.startsWith("0x")) { | |
hexAddress = hexAddress.substring(2); // Remove "0x" prefix | |
} | |
try { | |
return Long.parseLong(hexAddress, 16); | |
} catch (NumberFormatException e) { | |
throw new InvalidInputException("Invalid hexadecimal address format."); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment