Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f5f2aad
Showing
11 changed files
with
2,171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__pycache__ |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## ucdwarf | ||
|
||
integrate unicorn emulator into dwarf. | ||
|
||
### Installation | ||
|
||
``` | ||
cd %Dwarf%/plugins/ | ||
git clone https://github.com/iGio90/ucdwarf | ||
~~~ | ||
# make sure unicorn is installed: | ||
pip3 install unicorn | ||
``` | ||
|
||
### Features | ||
|
||
* panel with emulator and console | ||
* visual widgets for executed instructions, registers and memory accesses | ||
* options | ||
|
||
``` | ||
Dwarf - Copyright (C) 2019 Giovanni Rocca (iGio90) | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <https://www.gnu.org/licenses/> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
function Emulator() { | ||
this.clean = function () { | ||
loggedSend('emulator:::clean') | ||
}; | ||
|
||
this.setup = function (tid, arch, mode) { | ||
if (typeof tid !== 'number') { | ||
tid = Process.getCurrentThreadId(); | ||
} | ||
var msg = 'emulator:::setup:::' + tid; | ||
if (isDefined(arch) && isDefined(mode)) { | ||
msg += ':::' + arch + ':::' + mode; | ||
} | ||
loggedSend(msg) | ||
}; | ||
|
||
this.start = function (until) { | ||
loggedSend('emulator:::start:::' + until) | ||
}; | ||
|
||
this.step = function () { | ||
loggedSend('emulator:::step:::1') | ||
}; | ||
|
||
this.stepFunction = function () { | ||
loggedSend('emulator:::step:::2') | ||
}; | ||
|
||
this.stepJump = function () { | ||
loggedSend('emulator:::step:::3') | ||
}; | ||
|
||
this.stop = function () { | ||
loggedSend('emulator:::stop') | ||
}; | ||
} | ||
|
||
global.emulator = new Emulator(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
""" | ||
Dwarf - Copyright (C) 2019 Giovanni Rocca (iGio90) | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <https://www.gnu.org/licenses/> | ||
""" | ||
import os | ||
|
||
from PyQt5.QtCore import QObject, pyqtSignal | ||
|
||
from plugins.ucdwarf.src.emulator import Emulator, EmulatorThread | ||
from plugins.ucdwarf.src.emulator_context_widget import EmulatorContextList | ||
from ui.widget_console import DwarfConsoleWidget | ||
|
||
|
||
EMULATOR_CALLBACKS_PATH = 'emulator_callbacks_path' | ||
EMULATOR_INSTRUCTIONS_DELAY = 'emulator_instructions_delay' | ||
|
||
|
||
class Plugin(QObject): | ||
onEmulatorApi = pyqtSignal(list, name='onEmulatorApi') | ||
|
||
@staticmethod | ||
def __get_plugin_info__(): | ||
return { | ||
'name': 'ucdwarf', | ||
'description': 'unicorn emulator in Dwarf', | ||
'version': '1.0.0', | ||
'author': 'iGio90', | ||
'homepage': 'https://github.com/iGio90/ucdwarf', | ||
'license': 'https://www.gnu.org/licenses/gpl-3.0', | ||
} | ||
|
||
def __get_top_menu_actions__(self): | ||
return [] | ||
|
||
def __get_agent__(self): | ||
self.app.dwarf.onReceiveCmd.connect(self._on_receive_cmd) | ||
|
||
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'agent.js'), 'r') as f: | ||
return f.read() | ||
|
||
def __init__(self, app): | ||
super().__init__() | ||
self.app = app | ||
|
||
self.console = None | ||
self.emulator_panel = None | ||
self.emulator = None | ||
self._emu_queue = [] | ||
self._emu_thread = None | ||
|
||
self.app.session_manager.sessionCreated.connect(self._on_session_created) | ||
self.app.session_manager.sessionStopped.connect(self._on_session_stopped) | ||
self.app.onUIElementCreated.connect(self._on_ui_element_created) | ||
|
||
def _on_session_created(self): | ||
self.emulator = Emulator(self.app.dwarf) | ||
self._emu_thread = EmulatorThread(self) | ||
self._emu_thread.onCmdCompleted.connect(self._on_emu_completed) | ||
self._emu_thread.onError.connect(self._on_emu_error) | ||
self._emu_thread.emulator = self.emulator | ||
|
||
self.onEmulatorApi.connect(self._on_emulator_api) | ||
|
||
self.create_widget() | ||
|
||
def _on_session_stopped(self): | ||
pass | ||
|
||
def _on_receive_cmd(self, args): | ||
message, data = args | ||
if 'payload' in message: | ||
what = message['payload'] | ||
parts = what.split(':::') | ||
if len(parts) < 2: | ||
return | ||
|
||
cmd = parts[0] | ||
if cmd == 'emulator': | ||
self.onEmulatorApi.emit(parts[1:]) | ||
|
||
def _on_emulator_api(self, data): | ||
if self.emulator and self._emu_thread: | ||
if not self._emu_thread.isRunning(): | ||
self._emu_thread.cmd = data | ||
self._emu_thread.start() | ||
else: | ||
self._emu_queue.append(data) | ||
|
||
def _on_emu_completed(self, result): | ||
self.log(result) # todo: send back to script??? | ||
if self._emu_queue: | ||
self._emu_thread.cmd = self._emu_queue[0] | ||
self._emu_queue = self._emu_queue[1:] | ||
self._emu_thread.start() | ||
else: | ||
self._emu_thread.cmd = '' | ||
|
||
def _on_emu_error(self, err_str): | ||
self.log(err_str) | ||
if self._emu_queue: | ||
self._emu_queue.clear() | ||
|
||
def _on_ui_element_created(self, elem, widget): | ||
if elem == 'console': | ||
self.console = DwarfConsoleWidget(self.app, has_input=False) | ||
widget.qtabs.addTab(self.console, 'emulator') | ||
elif elem == 'registers': | ||
self.context_widget = widget | ||
self.emulator_context_widget = EmulatorContextList(self.context_widget) | ||
self.context_widget.addTab(self.emulator_context_widget, 'emulator') | ||
|
||
def create_widget(self): | ||
from plugins.ucdwarf.src.panel_emulator import EmulatorPanel | ||
self.emulator_panel = EmulatorPanel(self) | ||
self.app.main_tabs.addTab(self.emulator_panel, 'Emulator') | ||
return self.emulator_panel | ||
|
||
def log(self, what): | ||
self.console.log(str(what)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
""" | ||
Dwarf - Copyright (C) 2019 Giovanni Rocca (iGio90) | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <https://www.gnu.org/licenses/> | ||
""" | ||
from PyQt5.QtWidgets import * | ||
|
||
from lib import prefs | ||
from lib.prefs import Prefs | ||
from plugins.ucdwarf.plugin import EMULATOR_INSTRUCTIONS_DELAY, EMULATOR_CALLBACKS_PATH | ||
|
||
|
||
class EmulatorConfigsDialog(QDialog): | ||
def __init__(self, dwarf, parent=None): | ||
super(EmulatorConfigsDialog, self).__init__(parent) | ||
self.dwarf = dwarf | ||
self._prefs = Prefs() | ||
|
||
layout = QVBoxLayout(self) | ||
|
||
self.setMinimumWidth(500) | ||
|
||
layout.addWidget(QLabel('callbacks path')) | ||
callbacks_layout = QHBoxLayout() | ||
pick_path = QPushButton('choose') | ||
pick_path.clicked.connect(self.pick_callbacks_path) | ||
current_callbacks_path = self._prefs.get(EMULATOR_CALLBACKS_PATH) | ||
if current_callbacks_path == '': | ||
current_callbacks_path = 'none' | ||
self.callbacks_path_label = QLabel(current_callbacks_path) | ||
callbacks_layout.addWidget(pick_path) | ||
callbacks_layout.addWidget(self.callbacks_path_label) | ||
layout.addLayout(callbacks_layout) | ||
|
||
layout.addWidget(QLabel('delay between instructions')) | ||
self.instructions_delay = QLineEdit() | ||
self.instructions_delay.setText(str(self._prefs.get(EMULATOR_INSTRUCTIONS_DELAY, 0.5))) | ||
layout.addWidget(self.instructions_delay) | ||
|
||
buttons = QHBoxLayout() | ||
cancel = QPushButton('cancel') | ||
cancel.clicked.connect(self.close) | ||
buttons.addWidget(cancel) | ||
accept = QPushButton('accept') | ||
accept.clicked.connect(self.accept) | ||
buttons.addWidget(accept) | ||
|
||
layout.addLayout(buttons) | ||
|
||
def pick_callbacks_path(self): | ||
r = QFileDialog.getOpenFileName() | ||
if len(r) > 0 and len(r[0]) > 0: | ||
self._prefs.put(EMULATOR_CALLBACKS_PATH, r[0]) | ||
self.callbacks_path_label.setText(r[0]) | ||
|
||
@staticmethod | ||
def show_dialog(dwarf): | ||
dialog = EmulatorConfigsDialog(dwarf) | ||
result = dialog.exec_() | ||
|
||
if result == QDialog.Accepted: | ||
try: | ||
dialog._prefs.put(EMULATOR_INSTRUCTIONS_DELAY, float(dialog.instructions_delay.text())) | ||
except: | ||
pass |
Oops, something went wrong.