Skip to content

Instantly share code, notes, and snippets.

@CallocGD
Created May 6, 2024 04:43
Show Gist options
  • Select an option

  • Save CallocGD/acaee6f5892093812bf7d90260d56695 to your computer and use it in GitHub Desktop.

Select an option

Save CallocGD/acaee6f5892093812bf7d90260d56695 to your computer and use it in GitHub Desktop.
Broma Delegates to Ghidra Importer
"""A Small python script for building ghidra header files for All Delegates"""
from pybroma import *
from argparse import ArgumentParser
from pathlib import Path
import os
# This Introduces a new way to parse the broma files that
# was implemented based off the Cython Compiler. It's tiny, compact, requires only very little code.
class DelegateVisitor(BromaTreeVisitor):
def __call__(self, file: str):
self.code = "/* Warning! This code was automatically generated via python script, DO NOT EDIT OR ELSE BAD THINGS CAN HAPPEN! */"
super().__call__(file)
return
def visit_Field(self, f: Field):
self.parent = f.parent
return super().visit_Field(f)
def write_typedef(self, name:str):
self.code += f"\n\ntypedef struct {name} {name}, *P{name};\n"
def declare_delegate_vtable(self, name:str):
self.write_typedef(name + "_vtable")
self.code += "struct %s_vtable {\n" % name
def close_declaration(self):
self.code += "};\n"
def visit_Class(self, node: Class):
if node.name.lower().endswith("delegate") and not node.name.startswith("cocos2d::"):
self.declare_delegate_vtable(node.name)
super().visit_Class(node)
self.close_declaration()
self.write_typedef(node.name)
self.code += "struct %s {\n" % node.name
self.code += f" {node.name}_vtable *vtable;\n"
self.code += "};\n"
def visit_MemberFunctionProto(self, node: MemberFunctionProto):
if node.is_virtual:
self.code += f" void* {node.name};\n"
def save_artifact(self, filename:str):
"""Saves artifact of code made to a header file or chosen filename"""
with open(filename, "w") as w:
w.write(self.code)
def generate_delegates(filename:str):
print("[...] Generating Delegates...")
visitor = DelegateVisitor()
visitor("_temp.bro")
visitor.save_artifact(filename)
print("[+] Delegates Saved!")
def main():
parser = ArgumentParser(description="Writes all geometry dash Delegates to a portable headerfile to be used with ghidra")
parser.add_argument("--version", default="2.205", help="The Version of geometry dash to parse")
parser.add_argument("--path", default=".", help="the path to the bindings, default is the current directory assuming \"git clone\" was used in the same folder as this script")
parser.add_argument("--output", "-o", default="delegates.h", help="the ouput location of the file to use [default: \"delegates.h\"] ")
args = parser.parse_args()
bindings_path = Path(args.path) / "bindings"
if not bindings_path.exists():
print(f"[X] Bindings Do not exist please check {bindings_path.as_posix()} again")
return
_dir = Path("bindings/bindings") / str(args.version)
if not _dir.exists():
print(f"[X] Bindings Do Not exist try installing the geode bindings with \"git clone https://github.com/geode-sdk/bindings\" or try downloading and unpacking it's zip folder")
return
code = open(_dir / "Cocos2d.bro", "r").read() + "\n"
code += open(_dir / "GeometryDash.bro", "r").read() + "\n"
code += open(_dir / "Extras.bro", "r").read() + "\n"
with open("_temp.bro", "w") as temp:
temp.write(code)
generate_delegates(args.output)
if os.path.exists("_temp.bro"):
os.remove("_temp.bro")
# Included for those clueless people that don't know how to move header files into ghidra.
print("Your Delegates are now ready for use with ghidra! here's how to move them")
print("Hint: Once in your ghidra project Do the Following steps")
print("Step 1. Go to [File -> Parse C Source]")
print("Step 2. Go to the [+] icon in [Source files to parse]")
print(f"Step 3. Find \"{args.output}\" and select it")
print("Step 4. hit the bottom of the window and select [Parse to Program]")
print("Step 5. Ignore any bullshit popups or files that were not found and then hit [dismiss]")
if __name__ == "__main__":
main()
# The only requirement is this magic library
https://github.com/CallocGD/PyBroma/archive/refs/heads/main.zip # PYBroma
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment