Skip to main content

A Pythonic Ghidra standard library

Project description

ghidralib

This library is an attempt to provide a Pythonic standard library for Ghidra.

The main goal is to make writing quick&dirty scripts actually quick, and not that dirty.

Installation

Just copy the ghidralib.py file to your ghidra_scripts directory. Later just from ghidralib import *.

Usage

Check out the documentation or official examples. A short demonstration of a basic ghidralib usage first:

  1. Get all function instructions (similarly for basic blocks, low and high pcode, calls and xrefs):
print(Function("main").instructions)
For comparison, plain Ghidra equivalent:
function_manager = currentProgram.getFunctionManager()
symbol_table = currentProgram.getSymbolTable()
main = list(symbol_table.getSymbols('main'))[0].getAddress()
function = function_manager.getFunctionAt(main)
instructions = currentProgram.getListing().getInstructions(function.getBody(), True)
print(list(instructions))
  1. You have a structure uint8_t *data; uint32_t len; at 0x1000 and you want to read it:
pos, len_bytes = get_u32(0x10000), get_u32(0x10000 + 4)
print(get_bytes(pos, len_bytes))
For comparison, plain Ghidra equivalent:
start_address = toAddr(0x10000)
pos = currentProgram.getMemory().getInt(start_address)
len_bytes = currentProgram.getMemory().getInt(start_address.add(4))
data = getBytes(toAddr(pos), len_bytes)
print(" ".join(chr(c % 256) for byte in data))  # signed bytes <3
  1. Find all calls to a string deobfuscation function and get call parameters:
for call in Function("MyCustomCrypto").calls:
    ctx = call.infer_context()
    key, data = ctx["eax"], ctx["edx"]
    datalen = get_u32(data - 4)
    print(call.address, decode(get_bytes(data, datalen)))
For comparison, plain Ghidra equivalent:

Just joking! Too long to fit in this README.

You can also emulate a function call and read the result:

ctx = Function("GetFuncNameByHash").emulate(0x698766968)
print(ctx.read_cstring(ctx["eax"]))
  1. Tons more QoL features:
DataType("_NT_TIB")  # Get a datatype by name
DataType.from_c("typedef void* HINTERNET;")  # Quickly parse structs and typedefs

func = Function("main")  # Work at various abstract levels
print(function.instructions)  # Get instructions...
print(function.basicblocks)  # ..basic blocks...
print(function.pcode)  # ...low pcode...
print(function.high_pcode)  # ...high pcode...
print(function.decompile())  # ...or decompile a whole function

for xref in Symbol("PTR_GetProcAddress").xrefs_to:
  Instruction(xref.from_address).highlight()  # highlight symbol xrefs
  1. There are also some flashy (but not necessarily useful) features that might grab your attention.

Get the control flow graph of the main function, and display it:

Function("main").control_flow.show()

Find the shortest path from source to target in the program control flow graph. If it exists, highlight all basic blocks along the way.

source, target = BasicBlock("entry"), BasicBlock(0x00405073)
path = Program.control_flow().bfs(source)
while path.get(target):
    target.highlight()
    target = path[target]

  1. Thanks to type hints, scripting gets much easier if your IDE supports that.

Finally, ghidralib doesn't lock you in - you can always retreat to familiar Ghidra types - just get them from the .raw property. For example instruction.raw is a Ghidra Instruction object, similarly function.raw is a Ghidra Function. So you can do the routine stuff in ghidralib, and fall back to Java if something is not implemented.

Learn more

Check out the documentation, especially the getting started page.

More detailed tutorial about specific features is in development. Completed chapters:

If you prefer to learn by example, you can also browse the examples directory.

A fair warning: ghidralib is still actively developed and the API may change slightly in the future. But this doesn't matter for your one-off scripts, does it?

Contributing

PRs are welcome. Feel free to open PRs to add things you need.

You can also just report issues and send feature requests. I started this library to cover my own needs, but I'm interested in learning what other people use it for.

Dragon icon at the top created by cube29, flaticon

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ghidralib-0.2.0.tar.gz (36.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ghidralib-0.2.0-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file ghidralib-0.2.0.tar.gz.

File metadata

  • Download URL: ghidralib-0.2.0.tar.gz
  • Upload date:
  • Size: 36.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ghidralib-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5a7ea7efa630c84d6812189597b018824a3d5399ff6bf747c5142ffc52c3af58
MD5 2a7d09e9c3b444c013f5749ec2c3250a
BLAKE2b-256 c81a14c086f55c81f11a80ea766bb6b16c57597c134fa43ac0f760c6f0c5d002

See more details on using hashes here.

File details

Details for the file ghidralib-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ghidralib-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ghidralib-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8bc58a4cc245cd1f4ecbf7a90d15142563adca0ddbd2db00226f713d2029355c
MD5 2d797e8d690657aba97521c6abe9a767
BLAKE2b-256 b3366545d5e5d90aa83329f9e46942fbd7a4da4e8573ca80c8f8b45f9cc2f034

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page