Skip to content

Instantly share code, notes, and snippets.

@bruce30262
Created November 14, 2020 09:39
Show Gist options
  • Select an option

  • Save bruce30262/c075e7ea623b8997f98c8137b8216b46 to your computer and use it in GitHub Desktop.

Select an option

Save bruce30262/c075e7ea623b8997f98c8137b8216b46 to your computer and use it in GitHub Desktop.

Revisions

  1. bruce30262 created this gist Nov 14, 2020.
    67 changes: 67 additions & 0 deletions fix_riscv_decompile.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    # Check out the issue for more detail : https://github.com/NationalSecurityAgency/ghidra/issues/2466
    # The script will calculate the value of gp register base on the code in entry(), then apply the value to all the functions
    # This only work in the `RV64I` language though, since other language like `RV64GC` won't set the gp register in entry()

    from java.math import BigInteger

    def newAddress(offset):
    """
    Helper function to get a Ghidra Address type
    """
    return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset)

    # get entry() function code unit
    listing = currentProgram.getListing()
    entry_func = getGlobalFunctions("entry")[0] # one entry function, just get it from index
    addrSet = entry_func.getBody() # get the body address range
    codeUnits = listing.getCodeUnits(addrSet, True) # get code units ( instructions and their addresses...). true means 'forward'

    gp = None

    def cal_gp():
    """
    Calculate the value of gp ( global pointer register )
    """
    global codeUnits, gp
    if gp != None:
    return
    gp = 0
    for codeUnit in codeUnits:
    # print codeUnit info
    # from binascii import hexlify
    # print("0x{} : {:16} {}".format(codeUnit.getAddress(), hexlify(codeUnit.getBytes()), codeUnit.toString()))
    asm = codeUnit.toString()
    # gp = (<auipc's imm> << 12) + <pc_of_auipc> + <addi's imm>
    if "auipc gp" in asm:
    imm = int(asm.split(",")[-1], 16)
    gp = (imm << 12) + codeUnit.getAddress().getOffset() # getOffset so it returns a integer
    elif "addi gp,gp" in asm:
    imm = int(asm.split(",")[-1], 16)
    gp += imm
    return

    cal_gp() # calculate gp
    print("gp value: {:#x}".format(gp))

    # Get all functions
    # Modify all the gp register in those functions ( except "entry()" )
    gp_reg = currentProgram.getRegister("gp") # get Register type of gp
    fm = currentProgram.getFunctionManager()
    funcs = fm.getFunctions(True) # True means 'forward'
    for func in funcs:
    if(func.getName() == "entry"): # skip entry()
    continue

    print("===================================")
    print("Function: {} @ 0x{}".format(func.getName(), func.getEntryPoint()))
    addrSet = func.getBody()
    addrStart = addrSet.getMinAddress()
    addrEnd = addrSet.getMaxAddress()
    print("Address start: 0x{}".format(addrStart))
    print("Address end: 0x{}".format(addrEnd))
    print("Modify the value of gp register...")
    currentProgram.programContext.setValue(gp_reg, addrStart, addrEnd, BigInteger.valueOf(gp))
    print("OK !")
    print("===================================")

    print("All done !")