示例#1
0
 def test_address_comparison(self):
     with ghidra_bridge.GhidraBridge(
             namespace=globals(),
             connect_to_port=ghidra_bridge_port.DEFAULT_SERVER_PORT):
         test_address = currentAddress.add(1)
         self.assertFalse(test_address < currentAddress)
         self.assertTrue(test_address > currentAddress)
    def __init__(self) -> None:
        import ghidra_bridge

        namespace = {}
        self._bridge = ghidra_bridge.GhidraBridge(namespace)
        self._cuf = ghidra.program.model.listing.CodeUnitFormat.DEFAULT
        self._diss = ghidra.app.util.PseudoDisassembler(currentProgram)
示例#3
0
    def test_interactive_getState_fix(self):
        """ confirm that getState is updated, and doesn't cause a reset to old values when interactive mode is enabled """
        with ghidra_bridge.GhidraBridge(
                namespace=globals(),
                connect_to_port=bridge.DEFAULT_SERVER_PORT,
                interactive_mode=True):
            if state.getTool() is None:
                self.skipTest(
                    "Interactive mode tests not supported against headless (no tool)"
                )
            else:
                # record the current address as an int
                curr_addr = currentAddress.getOffset()

                # move the current address
                state.setCurrentAddress(currentAddress.add(0x10))

                # call getState
                new_state = getState()

                # check the new address has changed (not sure exactly what it's changed to, because instruction alignments might change exactly where we go)
                self.assertNotEqual(curr_addr, currentAddress.getOffset())

                # check that the state address matches
                self.assertEqual(currentAddress.getOffset(),
                                 new_state.getCurrentAddress().getOffset())
示例#4
0
    def test_non_interactive_currentAddress(self):
        """ confirm that the current address (and ideally, the other current* vars - TODO) are NOT updated when
            interactive mode is disabled """
        with ghidra_bridge.GhidraBridge(
                namespace=globals(),
                connect_to_port=bridge.DEFAULT_SERVER_PORT,
                interactive_mode=False):
            if state.getTool() is None:
                self.skipTest(
                    "This test isn't supported against headless/no tool ghidra, because of how we try to get the most up to date addresses"
                )
            else:
                listing_panel = ghidra_bridge.ghidra_bridge.get_listing_panel(
                    state.getTool(), ghidra)
                # get the actual current address
                actual_current_addr = listing_panel.getProgramLocation(
                ).getAddress().getOffset()

                # record the "current" address as an int
                curr_addr = currentAddress.getOffset()

                # move the current address
                state.setCurrentAddress(currentAddress.add(0x10))

                # check the address has changed
                new_actual_current_addr = listing_panel.getProgramLocation(
                ).getAddress().getOffset()
                self.assertNotEqual(actual_current_addr,
                                    new_actual_current_addr)

                # check the currentAddress hasn't changed
                self.assertEqual(curr_addr, currentAddress.getOffset())
示例#5
0
    def test_namespace_cleanup(self):
        with ghidra_bridge.GhidraBridge(
                namespace=globals(),
                connect_to_port=bridge.DEFAULT_SERVER_PORT):
            self.assertTrue("currentAddress" in globals())

        self.assertTrue("currentAddress" not in globals())
示例#6
0
 def test_isinstance_fix(self):
     """ check that we automatically fix up isinstance when using namespace, so we can isinstance bridged objects """
     with ghidra_bridge.GhidraBridge(
             namespace=globals(),
             connect_to_port=bridge.DEFAULT_SERVER_PORT):
         self.assertTrue(
             isinstance(currentAddress,
                        ghidra.program.model.address.Address))
示例#7
0
    def test_array_creation_without_forced_unicode(self):
        """ Check that we can instatiate an array.array without the error about it wanting a plain string as the first argument. Depends on jfx_bridge 0.8.0 """
        b = ghidra_bridge.GhidraBridge(namespace=globals())
        array = b.remote_import("array")

        test = array.array("b", b"\0" * 10)

        self.assertIsNotNone(test)
示例#8
0
 def test_readme_remote_eval_example_backcompat(self):
     """ Test the example from the readme, in its old version, before we changed GhidraBridge to inherit BridgeClient """
     b = ghidra_bridge.GhidraBridge(namespace=globals())
     func = currentProgram.getFunctionManager().getFunctions(True).next()
     mnemonics = b.bridge.remote_eval(
         "[ i.getMnemonicString() for i in currentProgram.getListing().getInstructions(f.getBody(), True)]",
         f=func,
     )
示例#9
0
 def test_readme_remote_eval_example(self):
     """ Test the example from the readme """
     b = ghidra_bridge.GhidraBridge(namespace=globals())
     func = currentProgram.getFunctionManager().getFunctions(True).next()
     mnemonics = b.remote_eval(
         "[ i.getMnemonicString() for i in currentProgram.getListing().getInstructions(f.getBody(), True)]",
         f=func,
     )
def run_script(server_host, server_port):
    import ghidra_bridge

    # load something ghidra doesn't have
    import networkx

    print("Running inside the bridge!")

    # create the bridge and load the flat API/ghidra modules into the namespace
    with ghidra_bridge.GhidraBridge(connect_to_host=server_host, connect_to_port=server_port, namespace=globals()):
        # grab the current function
        function = currentProgram.getFunctionManager().getFunctionContaining(currentAddress)

        if function is None:
            raise Exception(
                "Current address {} not within a function".format(currentAddress))

        print("Graphing {}:{}".format(function, function.getEntryPoint()))

        model = ghidra.program.model.block.BasicBlockModel(currentProgram)

        # get the first code block in the function
        code_block = model.getFirstCodeBlockContaining(
            function.getEntryPoint(), monitor)

        graph = networkx.DiGraph()

        # step through the code blocks, adding them to a networkx graph
        to_visit_list = [code_block]
        visited_list = []

        while len(to_visit_list) > 0:
            visit_block = to_visit_list.pop()
            src_block_address = visit_block.getFirstStartAddress().getOffset()

            # mark as visited
            visited_list.append(src_block_address)

            dest_it = visit_block.getDestinations(monitor)
            dest_ref = dest_it.next()
            while dest_ref is not None:
                dest_block = dest_ref.getDestinationBlock()

                dest_address = dest_block.getFirstStartAddress().getOffset()

                # add an edge
                graph.add_edge(src_block_address, dest_address)

                # add the destination to the visit list, if we haven't already visited it
                if dest_address not in visited_list and dest_address not in [block.getFirstStartAddress().getOffset() for block in to_visit_list]:
                    to_visit_list.append(dest_block)

                dest_ref = dest_it.next()

        # visits completed
        # can now perform graph analysis on the graph... or just print the edges
        print(graph.edges)
示例#11
0
    def test_namespace_cleanup_with_interactive(self):
        """ check that we can still remove if the values we add have been updated by interactive mode """
        with ghidra_bridge.GhidraBridge(namespace=globals(), connect_to_port=ghidra_bridge_port.DEFAULT_SERVER_PORT, interactive_mode=True):
            self.assertTrue("currentAddress" in globals())

            # cause currentAddress to change
            # move the current address
            state.setCurrentAddress(currentAddress.add(0x10))

            # add a little sleep, so there's enough time for the update to make it back to us (interactive_mode isn't meant to be scripted...)
            time.sleep(1)

        # make sure it's no longer present
        self.assertTrue("currentAddress" not in globals())
示例#12
0
    def test_hook_import(self):
        with ghidra_bridge.GhidraBridge(
                namespace=globals(),
                connect_to_port=ghidra_bridge_port.DEFAULT_SERVER_PORT,
                hook_import=True,
        ):
            import ghidra

            self.assertTrue("ghidra" in str(ghidra))
            from ghidra.framework.model import ToolListener
            import docking.widgets.indexedscrollpane.IndexScrollListener
            import java.math.BigInteger

            bi = java.math.BigInteger(str(10))
def main(mapdir):
    read_combined(mapdir)
    with ghidra_bridge.GhidraBridge(namespace=globals()) as b:
        print(hex(getState().getCurrentAddress().getOffset()))
        # Find all the functions whose name is a default name, i.e. FUN_BAADF00D (where BAADF00D is an 8-digit hexadecimal address)
        name_list = b.remote_eval(
            "[(f.getName(), int(str(f.getEntryPoint()), 16),) for f in currentProgram.getFunctionManager().getFunctionsNoStubs(True) if f.getName()[0:4] in ['FUN_', 'LAB_'] and f.getName().endswith(str(f.getEntryPoint()))]"
        )
        print(len(name_list))
        newnames = []
        count_addr, count_syms = 0, 0
        for _, addr in name_list:  # symbol name is "garbage" anyway
            if addr in bsp_addr:
                count_addr += 1
        print("addr: ", count_addr)
示例#14
0
    def test_interactive_currentAddress(self):
        """ confirm that the current address (and ideally, the other current* vars - TODO) are updated when
            interactive mode is enabled """
        with ghidra_bridge.GhidraBridge(namespace=globals(), connect_to_port=ghidra_bridge_port.DEFAULT_SERVER_PORT, interactive_mode=True):
            if state.getTool() is None:
                self.skipTest(
                    "Interactive mode tests not supported against headless (no tool)")
            else:
                # record the current address as an int
                curr_addr = currentAddress.getOffset()

                # move the current address
                state.setCurrentAddress(currentAddress.add(0x10))

                # add a little sleep, so there's enough time for the update to make it back to us (interactive_mode isn't meant to be scripted...)
                time.sleep(1)

                # check the new address has changed (not sure exactly what it's changed to, because instruction alignments might change exactly where we go)
                self.assertNotEqual(curr_addr, currentAddress.getOffset())
示例#15
0
    def __init__(self, widget, args):
        # Load configuration
        self.config_file = os.path.join(self.get_temp_dir(), "pe_tree_ghidra.ini")
        super(GhidraRuntime, self).__init__(widget, args)

        # Initialise Ghidra bridge
        try:
            self.bridge = ghidra_bridge.GhidraBridge(connect_to_host=self.args.server, connect_to_port=self.args.port, namespace=globals(), response_timeout=20)
        except ConnectionRefusedError:
            print("Please run ghidra_bridge_server_background.py under Ghidra -> Window -> Script Manager")
            exit()

        state = getState()
        currentProgram = state.getCurrentProgram()

        self.address_factory = currentProgram.getAddressFactory()
        self.function_manager = currentProgram.getFunctionManager()
        self.data_type_manager = currentProgram.getDataTypeManager()
        self.listing = currentProgram.getListing()
        self.memory = currentProgram.getMemory()
        self.address_space = currentProgram.getAddressFactory().getDefaultAddressSpace()
示例#16
0
def main(code_path,
         target_addr,
         shellcode_addr,
         amount,
         savefile=None,
         initial_storage_file=None,
         initial_balance=None,
         flags=None):
    savefilebase = savefile or code_path
    if code_path.endswith('.json'):
        with open(code_path, 'rb') as f:
            jd = json.load(f)
        p = Project.from_json(jd)
    else:
        with open(code_path) as infile:
            inbuffer = infile.read().rstrip()
        code = bytes.fromhex(inbuffer)
        p = Project(code)
        with open('%s.project.json' % savefilebase, 'w') as f:
            json.dump(p.to_json(), f)

    amount_check = '+'
    amount = amount.strip()
    if amount[0] in ('=', '+', '-'):
        amount_check = amount[0]
        amount = amount[1:]
    amount = int(amount)

    initial_storage = dict()
    if initial_storage_file:
        with open(initial_storage_file, 'rb') as f:
            initial_storage = {
                int(k, 16): int(v, 16)
                for k, v in json.load(f).items()
            }

    flags = flags or {'CALL', 'CALLCODE', 'DELEGATECALL', 'SELFDESTRUCT'}

    result = combined_exploit(p,
                              int(target_addr, 16),
                              int(shellcode_addr, 16),
                              amount,
                              amount_check,
                              initial_storage,
                              initial_balance,
                              flags=flags)
    if result:

        call, r, model = result

        print(model)

        with open('%s.exploit.json' % savefilebase, 'w') as f:
            json.dump(
                {
                    'paths': [{
                        'index':
                        i,
                        'path': [
                            ins for ins in res.state.trace if
                            ins in p.cfg.bb_addrs or ins == res.state.trace[-1]
                        ]
                    } for i, res in enumerate(r.results)],
                    'calls': [{
                        'index': i,
                        'call': hex_encode(c)
                    } for i, c in enumerate(call)]
                }, f)

        for i, res in enumerate(r.results):
            yes = query_yes_no("Found vulnerable path, mark it in Ghidra?")
            print('%d: %s' % (i, '->'.join(
                '%x' % i for i in res.state.trace
                if i in p.cfg.bb_addrs or i == res.state.trace[-1])))

            if (yes):

                b = ghidra_bridge.GhidraBridge(namespace=globals(),
                                               response_timeout=1000)

                tid = currentProgram.startTransaction("ghidrda evm")

                memory = currentProgram.getMemory()

                ram = memory.getBlock("ram")
                ram_size = ram.getSize()
                ram_addr = ram.getStart()

                for i in res.state.trace:
                    if i in p.cfg.bb_addrs or i == res.state.trace[-1]:
                        print(hex(i))
                        Color = b.remote_import("java.awt.Color")
                        setBackgroundColor(ram_addr.add(i), Color.YELLOW)

                currentProgram.endTransaction(tid, True)

        print(call)
        print
        for c in call:
            if c['caller'] == c['origin']:
                print(
                    'eth.sendTransaction({from:"0x%040x", data:"0x%s", to:"0x4000000000000000000000000000000000000000"%s, gasPrice:0})'
                    % (c['origin'], c.get('payload', b'').hex(),
                       ", value:%d" % c['value'] if c.get('value', 0) else ''))
            else:
                print(
                    'eth.sendTransaction({from:"0x%040x", data:"0x%s", to:"0x%040x"%s, gasPrice:0})'
                    % (c['origin'], c.get('payload', b'').hex(), c['caller'],
                       ", value:%d" % c['value'] if c.get('value', 0) else ''))

        return True
    return False
示例#17
0
文件: ghidra.py 项目: sthagen/ccrawl
        len(generic_name),
        generic_name,
        0,
    )
    archive = BytesIO()
    with ZipFile(archive, "w") as zfile:
        item = ZipInfo("FOLDER_ITEM")
        zfile.write(item, folder_item)
    length = len(archive.getbuffer())
    return header + struct.pack(">Q", length) + archive.getvalue()


try:
    import ghidra_bridge

    b = ghidra_bridge.GhidraBridge(namespace=locals())
except ImportError:
    secho("ghidra_bridge package not found", fg="red")
except AttributeError:
    secho("ghidra_bridge is not started", fg="red")
except ConnectionRefusedError:
    secho("ghidra_bridge connection error", fg="red")
else:
    if conf.config is None:
        conf.config = conf.Config()
    if conf.config.Ghidra.manager == "program":
        dtm = currentProgram.getDataTypeManager()
        if conf.VERBOSE:
            secho("ghidra_bridge connection with data type manager %s" % dtm,
                  fg="blue")
        tr = dtm.startTransaction("ccrawl")
示例#18
0
 def test_memory_callable_iterable(self):
     """ Test that we handle the ghidra.program.model.mem.Memory class - it's callable and iterable """
     with ghidra_bridge.GhidraBridge(
             namespace=globals(),
             connect_to_port=bridge.DEFAULT_SERVER_PORT):
         self.assertNotEqual(None, ghidra.program.model.mem.Memory)
示例#19
0
DANGEROUS_INSTRUCTIONS = ["CALL", "SELFDESTRUCT", "CALLCODE", "DELEGATECALL"]

# main

print("""\
       _     _     _                                      
  __ _| |__ (_) __| |_ __ __ _        _____   ___ __ ___  
 / _` | '_ \| |/ _` | '__/ _` |_____ / _ \ \ / / '_ ` _ \ 
| (_| | | | | | (_| | | | (_| |_____|  __/\ V /| | | | | |
 \__, |_| |_|_|\__,_|_|  \__,_|      \___| \_/ |_| |_| |_| v.0.1
 |___/                                                    
""")

# creates the bridge and loads the flat API into the global namespace
b = ghidra_bridge.GhidraBridge(namespace=globals(), response_timeout=1000)

tid = currentProgram.startTransaction("ghidrda evm")

memory = currentProgram.getMemory()

ram = memory.getBlock("ram")
ram_size = ram.getSize()
ram_addr = ram.getStart()

print("[*] Reading RAM:", ram_size, "bytes", "at", ram_addr)

i = getInstructionAt(ram_addr)

print("[*] Searching dangerous instructions...")
示例#20
0
 def test_str_javapackage(self):
     """ Test that we can now call str on javapackage objects """
     with ghidra_bridge.GhidraBridge(
             namespace=globals(),
             connect_to_port=bridge.DEFAULT_SERVER_PORT):
         self.assertTrue("java package ghidra" in str(ghidra))
示例#21
0
filename_input = sys.argv[1]

if filename_input.endswith('.evm'):
    with open(filename_input, 'rb') as f:
        evm_code = f.read()
    print(binascii.hexlify(evm_code))
elif filename_input.endswith('.evm_h'):
    with open(filename_input, 'r') as f:
        evm_code = f.read()
        print(evm_code)
else:
    print("[!] Imposible to read bytecode")
    exit(0)

b = ghidra_bridge.GhidraBridge(
    namespace=globals(), response_timeout=1000
)  # creates the bridge and loads the flat API into the global namespace

tid = currentProgram.startTransaction("ghidrda evm")

memory = currentProgram.getMemory()
ram = memory.getBlock("ram")
addr = ram.getStart()
size = ram.getSize()

print("[*] Setting analysis options....")

setAnalysisOption(currentProgram, "Embedded Media", "false")
setAnalysisOption(currentProgram, "ASCII Strings", "false")
setAnalysisOption(currentProgram, "Create Address Tables", "false")
示例#22
0
    logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s")
    rootLogger = logging.getLogger()
    rootLogger.setLevel(logging.DEBUG)

    #fileHandler = logging.FileHandler("{0}/{1}.log".format(logPath, fileName))
    #fileHandler.setFormatter(logFormatter)
    #rootLogger.addHandler(fileHandler)

    consoleHandler = logging.StreamHandler()
    consoleHandler.setFormatter(logFormatter)
    rootLogger.addHandler(consoleHandler)


if __name__ == '__main__':
    init_logger()
    b = ghidra_bridge.GhidraBridge(namespace=globals()) # creates the bridge and loads the flat API into the global namespace

    cfg = Control_Flow_Graph()
    cfg.print_cfg()



""" For tests in interpreter:

b = ghidra_bridge.GhidraBridge(namespace=globals())
block_model_iterator = ghidra.program.model.block.BasicBlockModel(currentProgram)
function = getFirstFunction()
function_addresses = function.getBody()
code_blocks_iterator = block_model_iterator.getCodeBlocksContaining(function_addresses, monitor)
block = code_blocks_iterator.next()
new_block = dict()
示例#23
0
def run_server(host=ghidra_bridge.bridge.DEFAULT_HOST, server_port=ghidra_bridge.bridge.DEFAULT_SERVER_PORT, client_port=ghidra_bridge.bridge.DEFAULT_CLIENT_PORT):
    server = ghidra_bridge.GhidraBridge(host=host, local_server_port=server_port, ghidra_server_port=client_port)
    server.bridge.start()
parser = argparse.ArgumentParser(
    description='Dirty script to parse headers into Ghidra Data Type Archives')
parser.add_argument('header_file', help='The header file to parse')
parser.add_argument('--output',
                    '-o',
                    help='Path of the output file (must not exist yet!)')
#parser.add_argument('--overwrite', '-f', help="Overwrite the output file if it already exists", action='store_true')

args = parser.parse_args()

import logging

print("Connecting to bridge")
import ghidra_bridge

b = ghidra_bridge.GhidraBridge(namespace=globals())

java = b.bridge.remote_import("java")
ghidra = b.bridge.remote_import("ghidra")

print("Creating parser")
if args.output:
    full_path = os.path.abspath(args.output)
    dtm = ghidra.program.model.data.FileDataTypeManager.createFileArchive(
        java.io.File(full_path))
    cparser = ghidra.app.util.cparser.C.CParser(dtm, True, None)
else:
    cparser = ghidra.app.util.cparser.C.CParser()

print("Finished parsing")