ghidra/Ghidra/Features/Pyhidra/ghidra_scripts/PyhidraBasics.py
2024-09-09 09:58:05 -04:00

77 lines
2.7 KiB
Python

# Examples of Pyhidra-specific functionality
# @category: Examples.Python
# @runtime Pyhidra
# we can import java libraries just as if they were python libraries
from java.util import LinkedList
# and then use them like they are natural classes
java_list = LinkedList([1,2,3])
print(f"linked list object class: {java_list.__class__}")
# importing and using Ghidra modules is the same
from ghidra.program.flatapi import FlatProgramAPI
print(f"max references to a flat program api: {FlatProgramAPI.MAX_REFERENCES_TO}")
# we can also do normal python-ish things on our Java objects, like:
# indexing
print(f"first element of the list: {java_list[0]}")
# slicing
print(f"first two elements of the list: {java_list[0:2]}")
# list comprehension
java_list_double = [i * 2 for i in java_list]
print(f"list comprehension result: {java_list_double}")
# automatic calls to getters
print(f"current program name: {currentProgram.name}") # calls currentProgram.getName()
# here's an example of how this stuff might come in handy with Ghidra:
print('current program memory blocks:\n')
for block in currentProgram.memory.blocks:
print(block.name)
# many Ghidra functions need a Java-native array to pass or receive values
# JPype provides objects of JByte, JChar, etc. to meet this need
# this example demonstrates how you would create an array of bytes to get
# the first 10 bytes of memory from the .text section
# we need this import to get at the helper classes
import jpype
# get the block we need
block = currentProgram.memory.getBlock('.text')
if block:
# the verbose way of getting the array
byte_array_maker = jpype.JArray(jpype.JByte)
byte_array = byte_array_maker(10)
# we also could have taken a shortcut with just:
# byte_array = jpype.JByte[10]
# let's have a look at our new object
print(f"array class: {byte_array.__class__}")
# will be <java class 'byte[]'>
print(f"array length: {len(byte_array)}")
# we can now use this array wherever a Java method requires a byte[] type
# the signature of getBytes is getBytes(Address addr, byte[] b)
block.getBytes(block.start, byte_array)
# after the call, we can get the bytes out as desired
# we just put them in a list comprehension here
print(f"first 10 bytes of .text: {['%#x' % ((b+256)%256) for b in byte_array]}")
# if the data isn't being changed, a bytes-like objct may be used
data = b"Hello"
clearListing(block.start, block.start.add(len(data) - 1))
block.putBytes(block.start, data)
else:
print('no block named .text in this program.')
# see the user manual of JPype for more details on interoperability:
# https://jpype.readthedocs.io/en/latest/userguide.html