-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathsample_python.py
More file actions
107 lines (83 loc) · 4.16 KB
/
Copy pathsample_python.py
File metadata and controls
107 lines (83 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import cutter
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QVBoxLayout, QLabel, QWidget, QSizePolicy, QPushButton
class FortuneWidget(cutter.CutterDockWidget):
def __init__(self, parent):
super(FortuneWidget, self).__init__(parent)
self.setObjectName("FancyDockWidgetFromCoolPlugin")
self.setWindowTitle("Sample Python Plugin")
content = QWidget()
self.setWidget(content)
# Create layout and label
layout = QVBoxLayout(content)
content.setLayout(layout)
self.text = QLabel(content)
self.text.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.text.setFont(cutter.Configuration.instance().getFont())
layout.addWidget(self.text)
button = QPushButton(content)
button.setText("Want a fortune?")
button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
button.setMaximumHeight(50)
button.setMaximumWidth(200)
layout.addWidget(button)
layout.setAlignment(button, Qt.AlignHCenter)
button.clicked.connect(self.generate_fortune)
cutter.core().seekChanged.connect(self.generate_fortune)
self.show()
def generate_fortune(self):
fortune = cutter.cmd("fortune").replace("\n", "")
res = cutter.core().cmdRaw(f"?E {fortune}")
self.text.setText(res)
class CutterSamplePlugin(cutter.CutterPlugin):
name = "Sample Plugin"
description = "A sample plugin written in python."
version = "1.2"
author = "Cutter developers"
# Override CutterPlugin methods
def __init__(self):
super(CutterSamplePlugin, self).__init__()
self.disassembly_actions = []
self.addressable_item_actions = []
self.disas_action = None
self.addr_submenu = None
self.main = None
def setupPlugin(self):
pass
def setupInterface(self, main):
# Dock widget
widget = FortuneWidget(main)
main.addPluginDockWidget(widget)
# Dissassembly context menu
menu = main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Disassembly)
self.disas_action = menu.addAction("CutterSamplePlugin dissassembly action")
self.disas_action.triggered.connect(self.handle_disassembler_action)
self.main = main
# Context menu for tables with addressable items like Flags,Functions,Strings,Search results,...
addressable_item_menu = main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Addressable)
self.addr_submenu = addressable_item_menu.addMenu("CutterSamplePlugin") # create submenu
adrr_action = self.addr_submenu.addAction("Action 1")
self.addr_submenu.addSeparator() # can use separator and other qt functionality
adrr_action2 = self.addr_submenu.addAction("Action 2")
adrr_action.triggered.connect(self.handle_addressable_item_action)
adrr_action2.triggered.connect(self.handle_addressable_item_action)
def terminate(self): # optional
print("CutterSamplePlugin shutting down")
if self.main:
menu = self.main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Disassembly)
menu.removeAction(self.disas_action)
addressable_item_menu = self.main.getContextMenuExtensions(cutter.MainWindow.ContextMenuType.Addressable)
submenu_action = self.addr_submenu.menuAction()
addressable_item_menu.removeAction(submenu_action)
print("CutterSamplePlugin finished clean up")
# Plugin methods
def handle_addressable_item_action(self):
# for actions in plugin menu Cutter sets data to current item address
submenu_action = self.addr_submenu.menuAction()
cutter.message("Context menu action callback 0x{:x}".format(submenu_action.data()))
def handle_disassembler_action(self):
# for actions in plugin menu Cutter sets data to address for current dissasembly line
cutter.message("Dissasembly menu action callback 0x{:x}".format(self.disas_action.data()))
# This function will be called by Cutter and should return an instance of the plugin.
def create_cutter_plugin():
return CutterSamplePlugin()