Ejemplo n.º 1
0
class Robo(object):
    def __init__(self):
        self.bus = EventBus()
        self.bus.add_event(self.extract_1, "login_finish")
        self.bus.add_event(self.extract_2, "login_finish")
        self.bus.add_event(self.extract_3, "login_finish")
        pass

    def login(self):
        print("Iniciando login")
        sleep(1)
        self.bus.emit("login_finish")
        print("Fim login")

    def extract_1(self):
        print("Iniciando extract_1")
        sleep(2)
        print("Fim extract_1")

    def extract_2(self):
        print("Iniciando extract_2")
        sleep(2)
        print("Fim extract_2")

    def extract_3(self):
        print("Iniciando extract_3")
        sleep(2)
        print("Fim extract_3")

    def finish(self):
        print("Fim !!")

    def exec(self):
        self.login()
Ejemplo n.º 2
0
Archivo: core.py Proyecto: zbx91/Dwarf
class Dwarf(object):
    def __init__(self, app_window):
        self.app_window = app_window
        self.app = app_window.get_app_instance()

        self.java_available = False
        self.loading_library = False

        # frida device
        self.device = None

        # process
        self.pid = 0
        self.process = None
        self.script = None

        # kernel
        self.kernel = Kernel(self)

        # hooks
        self.hooks = {}
        self.on_loads = {}
        self.java_hooks = {}
        self.temporary_input = ''
        self.native_pending_args = None
        self.java_pending_args = None

        # context
        self.arch = ''
        self.pointer_size = 0
        self.contexts = {}
        self.context_tid = 0

        # tracers
        self.native_traced_tid = 0

        # core utils
        self.bus = EventBus()
        self.emulator = Emulator(self)
        self.git = Git()
        self.prefs = Prefs()
        self.script_manager = ScriptsManager(self)

        self.keystone_installed = False
        try:
            import keystone.keystone_const
            self.keystone_installed = True
        except:
            pass

    def _get_device(self):
        try:
            self.device = frida.get_usb_device()
        except frida.TimedOutError:
            self.device = None

        if self.device is None:
            # now check for a local device
            try:
                self.device = frida.get_local_device()
            except frida.TimedOutError:
                self.device = None

            if self.device is None:
                return 1
        return 0

    def _reinitialize(self):
        self.java_available = False
        self.loading_library = False

        # frida device
        self.device = None

        # process
        self._spawned = False
        self.pid = 0
        self.process = None
        self.script = None

        # hooks
        self.hooks = {}
        self.on_loads = {}
        self.java_hooks = {}
        self.temporary_input = ''
        self.native_pending_args = None
        self.java_pending_args = None

        # tracers
        self.native_traced_tid = 0

    def device_picked(self, device):
        self.device = device

    def attach(self, pid_or_package, script=None, print_debug_error=True):
        if self.device is None:
            # fallback to usb device
            # can come from -p in args
            err = self._get_device()
            if err > 0:
                return err

        if self.process is not None:
            self.detach()

        try:
            self.process = self.device.attach(pid_or_package)
            self.pid = self.process._impl.pid
            self._spawned = False
        except Exception as e:
            if print_debug_error:
                utils.show_message_box('Failed to attach to %s' % str(pid_or_package), str(e))
            return 2

        self.load_script(script)
        return 0

    def detach(self):
        if self.script is not None:
            self.dwarf_api('_detach')
            self.script.unload()
        if self.process is not None:
            self.process.detach()

    def load_script(self, script=None):
        with open('lib/script.js', 'r') as f:
            s = f.read()
        self.script = self.process.create_script(s)
        self.script.on('message', self.on_message)
        self.script.on('destroyed', self.on_destroyed)
        self.script.load()

        if script is not None:
            self.dwarf_api('evaluateFunction', script)

        self.app_window.on_script_loaded()

    def spawn(self, package, script=None):
        if self.device is None:
            # fallback to usb device
            # can come from -p in args
            err = self._get_device()
            if err > 0:
                return err

        if self.process is not None:
            self.detach()

        try:
            self.pid = self.device.spawn(package)
            self.process = self.device.attach(self.pid)
            self._spawned = True
        except Exception as e:
            utils.show_message_box('Failed to spawn to %s' % package, str(e))
            return 2
        self.load_script(script)
        return 0

    def on_message(self, message, data):
        if 'payload' not in message:
            print(message)
            return

        what = message['payload']
        parts = what.split(':::')
        if len(parts) < 2:
            print(what)
            return

        cmd = parts[0]
        if cmd == 'backtrace':
            if self.app.get_session_ui() is not None and self.app.get_backtrace_panel() is not None:
                try:
                    self.app.get_backtrace_panel().set_backtrace(json.loads(parts[1]))
                except:
                    pass
        elif cmd == 'emulator':
            # on a separate thread to allow js api recursion
            Thread(target=self.emulator.api, args=(parts[1:],)).start()
        elif cmd == 'enumerate_java_classes_start':
            if self.app.get_java_classes_panel() is not None:
                self.app.get_java_classes_panel().on_enumeration_start()
            if self.app.get_java_trace_panel() is not None:
                self.app.get_java_trace_panel().on_enumeration_start()
        elif cmd == 'enumerate_java_classes_match':
            if self.app.get_java_classes_panel() is not None:
                self.app.get_java_classes_panel().on_enumeration_match(parts[1])
            if self.app.get_java_trace_panel() is not None:
                self.app.get_java_trace_panel().on_enumeration_match(parts[1])
        elif cmd == 'enumerate_java_classes_complete':
            self.app_window.get_menu().on_java_classes_enumeration_complete()
            if self.app.get_java_classes_panel() is not None:
                self.app.get_java_classes_panel().on_enumeration_complete()
            if self.app.get_java_trace_panel() is not None:
                self.app.get_java_trace_panel().on_enumeration_complete()
        elif cmd == 'enumerate_java_methods_complete':
            self.bus.emit(parts[1], json.loads(parts[2]), parts[1])
        elif cmd == 'ftrace':
            if self.app.get_ftrace_panel() is not None:
                self.app.get_ftrace_panel().append_data(parts[1])
        elif cmd == 'enable_kernel':
            self.app_window.get_menu().enable_kernel_menu()
        elif cmd == 'hook_java_callback':
            h = Hook(Hook.HOOK_JAVA)
            h.set_ptr(1)
            h.set_input(parts[1])
            if self.java_pending_args:
                h.set_condition(self.java_pending_args['condition'])
                h.set_logic(self.java_pending_args['logic'])
                self.java_pending_args = None
            self.java_hooks[h.get_input()] = h
            self.app.get_hooks_panel().hook_java_callback(h)
        elif cmd == 'hook_native_callback':
            h = Hook(Hook.HOOK_NATIVE)
            h.set_ptr(int(parts[1], 16))
            h.set_input(self.temporary_input)
            h.set_bytes(binascii.unhexlify(parts[2]))
            self.temporary_input = ''
            if self.native_pending_args:
                h.set_condition(self.native_pending_args['condition'])
                h.set_logic(self.native_pending_args['logic'])
                self.native_pending_args = None
            self.hooks[h.get_ptr()] = h
            self.app.get_hooks_panel().hook_native_callback(h)
        elif cmd == 'hook_onload_callback':
            h = Hook(Hook.HOOK_ONLOAD)
            h.set_ptr(0)
            h.set_input(parts[1])

            self.on_loads[parts[1]] = h
            if self.app.session_ui is not None and self.app.get_hooks_panel() is not None:
                self.app.get_hooks_panel().hook_onload_callback(h)
        elif cmd == 'java_trace':
            panel = self.app.get_java_trace_panel()
            if panel is None:
                panel = self.app.get_session_ui().add_dwarf_tab(SessionUi.TAB_JAVA_TRACE)
            panel.on_event(parts[1], parts[2], parts[3])
        elif cmd == 'log':
            self.app.get_console_panel().get_js_console().log(parts[1])
        elif cmd == 'memory_scan_match':
            self.bus.emit(parts[1], parts[2], json.loads(parts[3]))
        elif cmd == 'memory_scan_complete':
            self.app_window.get_menu().on_bytes_search_complete()
            self.bus.emit(parts[1] + ' complete', 0, 0)
        elif cmd == 'onload_callback':
            self.loading_library = parts[1]
            self.app.get_console_panel().get_js_console().log('hook onload %s @thread := %s' % (
                parts[1], parts[3]))
            self.app.get_hooks_panel().hit_onload(parts[1], parts[2])
        elif cmd == 'release':
            if parts[1] in self.contexts:
                del self.contexts[parts[1]]
            self.app.on_tid_resumed(int(parts[1]))
        elif cmd == 'set_context':
            data = json.loads(parts[1])
            if 'context' in data:
                context = Context(data['context'])
                self.contexts[str(data['tid'])] = context

                sym = ''
                if 'pc' in context.__dict__:
                    name = data['ptr']
                    if context.pc.symbol_name is not None:
                        sym = '(%s - %s)' % (context.pc.symbol_module_name, context.pc.symbol_name)
                else:
                    name = data['ptr']
                self.app.get_contexts_lists_panel().add_context(data, library_onload=self.loading_library)
                # check if data['reason'] is 0 (REASON_HOOK)
                if self.loading_library is None and data['reason'] == 0:
                    self.log('hook %s %s @thread := %d' % (name, sym, data['tid']))
                if len(self.contexts.keys()) > 1 and self.app.get_context_panel().have_context():
                    return
                self.app.get_session_ui().request_session_ui_focus()
            else:
                self.arch = data['arch']
                self.pointer_size = data['pointerSize']
                self.java_available = data['java']
                self.app.get_console_panel().get_js_console().log('injected into := ' + str(self.pid))
                self.app_window.on_context_info()

            self.context_tid = data['tid']
            self.app.apply_context(data)
            if self.loading_library is not None:
                self.loading_library = None
        elif cmd == 'set_data':
            key = parts[1]
            if data:
                self.app.get_data_panel().append_data(key, hexdump(data, result='return'))
            else:
                self.app.get_data_panel().append_data(key, str(parts[2]))
        elif cmd == 'script_loaded':
            if self._spawned:
                self.device.resume(self.pid)
        elif cmd == 'tracer':
            panel = self.app.get_trace_panel()
            if panel is None:
                panel = self.app.get_session_ui().add_dwarf_tab(SessionUi.TAB_TRACE)
            if panel is not None:
                # safely checked later
                panel.start()

                trace_events_parts = parts[1].split(',')
                while len(trace_events_parts) > 0:
                    t = TraceEvent(trace_events_parts.pop(0),
                                   trace_events_parts.pop(0),
                                   trace_events_parts.pop(0),
                                   trace_events_parts.pop(0))
                    panel.event_queue.append(t)
        elif cmd == 'unhandled_exception':
            # todo
            pass
        elif cmd == 'update_modules':
            self.app.apply_context({'tid': parts[1], 'modules': json.loads(parts[2])})
        elif cmd == 'update_ranges':
            self.app.apply_context({'tid': parts[1], 'ranges': json.loads(parts[2])})
        elif cmd == 'watcher':
            exception = json.loads(parts[1])
            self.log('watcher hit op %s address %s @thread := %s' %
                     (exception['memory']['operation'], exception['memory']['address'], parts[2]))
        elif cmd == 'watcher_added':
            if self.app.get_watchers_panel() is not None:
                self.app.get_watchers_panel().add_watcher_callback(parts[1])
        elif cmd == 'watcher_removed':
            if self.app.get_watchers_panel() is not None:
                self.app.get_watchers_panel().remove_watcher_callback(parts[1])
        else:
            print(what)

    def on_destroyed(self):
        self._reinitialize()

        if self.app.get_console_panel() is not None:
            self.app.get_console_panel().get_js_console().log('detached from %d. script destroyed' % self.pid)
        self.app_window.on_script_destroyed()

    def add_watcher(self, ptr=None):
        if ptr is None:
            ptr, input = InputDialog.input_pointer(self.app)
            if ptr == 0:
                return
        return self.dwarf_api('addWatcher', ptr)

    def dump_memory(self, file_path=None, ptr=0, length=0):
        if ptr == 0:
            ptr, inp = InputDialog.input_pointer(self.app)
        if ptr > 0:
            if length == 0:
                accept, length = InputDialog.input(
                    self.app, hint='insert length', placeholder='1024')
                if not accept:
                    return
                try:
                    if length.startswith('0x'):
                        length = int(length, 16)
                    else:
                        length = int(length)
                except:
                    return
            if file_path is None:
                r = QFileDialog.getSaveFileName(self.app, caption='Save binary dump to file')
                if len(r) == 0 or len(r[0]) == 0:
                    return
                file_path = r[0]
            data = self.read_memory(ptr, length)
            with open(file_path, 'wb') as f:
                f.write(data)

    def dwarf_api(self, api, args=None, tid=0):
        if tid == 0:
            tid = self.context_tid
        if args is not None and not isinstance(args, list):
            args = [args]
        if self.script is None:
            return None
        try:
            return self.script.exports.api(tid, api, args)
        except Exception as e:
            self.app.get_console_panel().get_js_console().log(str(e))
            return None

    def hook_java(self, input=None, pending_args=None):
        if input is None or not isinstance(input, str):
            accept, input = InputDialog.input(
                self.app, hint='insert java class or methos',
                placeholder='com.package.class or com.package.class.method')
            if not accept:
                return
        self.java_pending_args = pending_args
        input = input.replace(' ', '')
        self.app.dwarf_api('hookJava', input)

    def hook_native(self, input=None, pending_args=None):
        if input is None or not isinstance(input, str):
            ptr, input = InputDialog.input_pointer(self.app)
        else:
            ptr = utils.parse_ptr(self.app.dwarf_api('evaluatePtr', input))
        if ptr > 0:
            self.temporary_input = input
            self.native_pending_args = pending_args
            self.app.dwarf_api('hookNative', ptr)

    def hook_onload(self, input=None):
        if input is None or not isinstance(input, str):
            accept, input = InputDialog.input(self.app, hint='insert module name', placeholder='libtarget.so')
            if not accept:
                return
            if len(input) == 0:
                return

        if not input.endswith('.so'):
            input += '.so'

        if input in self.app.get_dwarf().on_loads:
            return

        self.dwarf_api('hookOnLoad', input)

    def log(self, what):
        if self.app.get_console_panel() is not None:
            self.app.get_console_panel().get_js_console().log(what)

    def native_tracer_start(self, tid=0):
        if self.native_traced_tid > 0:
            return
        if tid == 0:
            accept, tid = InputDialog.input(self.app, hint='insert thread id to trace', placeholder=str(self.pid))
            if not accept:
                return
            try:
                if tid.startswith('0x'):
                    tid = int(tid, 16)
                else:
                    tid = int(tid)
            except:
                return
        self.native_traced_tid = tid
        self.app.dwarf_api('startNativeTracer', [tid, True])
        if self.app.get_trace_panel() is None:
            self.app.get_session_ui().add_dwarf_tab('trace', request_focus=True)
        self.app_window.get_menu().on_native_tracer_change(True)

    def native_tracer_stop(self):
        if self.native_traced_tid == 0:
            return
        self.dwarf_api('stopNativeTracer')
        if self.app.get_trace_panel() is not None:
            self.app.get_trace_panel().stop()
        self.native_traced_tid = 0
        self.app_window.get_menu().on_native_tracer_change(False)

    def read_memory(self, ptr, len):
        if len > 1024 * 1024:
            position = 0
            next_size = 1024 * 1024
            data = bytearray()
            while True:
                try:
                    data += self.dwarf_api('readBytes', [ptr + position, next_size])
                except:
                    return None
                position += next_size
                diff = len - position
                if diff > 1024 * 1024:
                    next_size = 1024 * 1024
                elif diff > 0:
                    next_size = diff
                else:
                    break
            ret = bytes(data)
            del data
            return ret
        else:
            return self.dwarf_api('readBytes', [ptr, len])

    def remove_watcher(self, ptr):
        return self.dwarf_api('removeWatcher', ptr)

    ###########
    #         #
    # getters #
    #         #
    ###########

    def get_bus(self):
        return self.bus

    def get_emulator(self):
        return self.emulator

    def get_git(self):
        return self.git

    def get_kernel(self):
        return self.kernel

    def get_loading_library(self):
        return self.loading_library

    def get_native_traced_tid(self):
        return self.native_traced_tid

    def get_prefs(self):
        return self.prefs

    def get_scripts_manager(self):
        return self.script_manager
Ejemplo n.º 3
0
            else:
                return fib(n - 1) + fib(n - 2)


print("\n" "CPU Heavy Tests:" "\n")

create_event_one()

# ------------------------------------------
# Single Threaded Code Execution.
# ------------------------------------------
TEST_TYPE = 'Single-threaded'

start = timer()

bus.emit(EVENT_ONE, 30)

finish = timer() - start
print("{} ran the code in {} seconds.".format(TEST_TYPE, finish))

# ------------------------------------------
# Multi-Threaded Code Execution.
# ------------------------------------------
TEST_TYPE = 'Multi-threaded'

start = timer()

events = [Thread(target=func, args=[30]) for func in bus._events[EVENT_ONE]]
for func in events:
    func.start()
Ejemplo n.º 4
0
from event_bus import EventBus
from sample_event import SampleEvent

KEY_ESCAPE = 27

event_bus = EventBus()
assert event_bus is not None


def onEventKey(event: SampleEvent):
    assert event is not None
    assert event.key == KEY_ESCAPE


assert len(event_bus.getHandlers(SampleEvent)) == 0

event_bus.unregister(onEventKey)
assert len(event_bus.getHandlers(SampleEvent)) == 0

event_bus.register(onEventKey)
assert len(event_bus.getHandlers(SampleEvent)) == 1

event_bus.unregister(onEventKey)
assert len(event_bus.getHandlers(SampleEvent)) == 0

event_bus.register(onEventKey)
assert len(event_bus.getHandlers(SampleEvent)) == 1

event_bus.emit(SampleEvent(KEY_ESCAPE))