diff --git a/src/gui/dialogs/write_form.py b/src/gui/dialogs/write_form.py
new file mode 100644
index 0000000..9693f39
--- /dev/null
+++ b/src/gui/dialogs/write_form.py
@@ -0,0 +1,25 @@
+# This file is part of ot-project.
+#
+# ot-project 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.
+#
+# ot-project 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 Foobar. If not, see .
+#
+
+from PyQt5.Qt import QDialog
+
+from gui.ui.dialogs.write_form import Ui_WriteForm
+
+
+class WriteForm(QDialog, Ui_WriteForm):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.setupUi(self)
diff --git a/src/gui/main_window.py b/src/gui/main_window.py
index c041dae..4458bea 100644
--- a/src/gui/main_window.py
+++ b/src/gui/main_window.py
@@ -14,13 +14,17 @@
# along with Foobar. If not, see .
#
import operator
+import struct
from PyQt5.Qt import QMainWindow, QHeaderView, QMessageBox
from PyQt5.QtCore import pyqtSlot, QModelIndex
from psutil import NoSuchProcess
from gui.dialogs.process_view import ProcessView
+from gui.dialogs.write_form import WriteForm
+from gui.items.tree_item import TreeItem
from gui.models.found_address_model import FoundAddressModel
+from gui.models.saved_address_model import SavedAddressHeaderEnum
from gui.ui.widgets.mainwindow import Ui_MainWindow
from memory.memory import Memory
from memory.type import Type
@@ -41,6 +45,7 @@ def __init__(self):
self.next_scan.clicked.connect(self.next_scan_clicked)
self.actionAttach.triggered.connect(self.attach_triggered)
self.found_table.doubleClicked.connect(self.found_table_double_clicked)
+ self.saved_results.doubleClicked.connect(self.saved_model_double_clicked)
@pyqtSlot()
def new_scan_clicked(self):
@@ -84,3 +89,32 @@ def found_table_double_clicked(self, index: QModelIndex):
return
clicked_value = self.found_table.model().get_value(index.row())
self.saved_results.model().append_row(clicked_value)
+
+ @pyqtSlot(QModelIndex)
+ def saved_model_double_clicked(self, index: QModelIndex):
+ if not index.isValid():
+ return
+ column = index.column()
+
+ if column == SavedAddressHeaderEnum.VALUE:
+ form = WriteForm(self)
+ x = form.exec_()
+ text = form.value.text()
+ if x and len(text) != 0:
+ item: TreeItem = self.saved_results.model().get_item(index)
+ value = item.get_internal_pointer()
+ try:
+ value.write(value.type.parse_value(text, form.ishex.isChecked()))
+ except struct.error:
+ QMessageBox(QMessageBox.NoIcon, "Error", "You can't write a larger number to "
+ "memory than you currently have set "
+ "as a type.\nSee limits.h for more "
+ "information",
+ QMessageBox.Ok, self).exec_()
+ except ValueError:
+ # this is a kinda temporary fix, I'm planning on adding a validator or some
+ # shit later, not entirely sure how to add them yet so this will do
+ QMessageBox(QMessageBox.NoIcon, "Error", "Error parsing value, you probably "
+ "entered text when trying to write "
+ "an integer...",
+ QMessageBox.Ok, self).exec_()
diff --git a/src/gui/ui/dialogs/write_form.py b/src/gui/ui/dialogs/write_form.py
new file mode 100644
index 0000000..393ab05
--- /dev/null
+++ b/src/gui/ui/dialogs/write_form.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'write_form.ui'
+#
+# Created by: PyQt5 UI code generator 5.15.4
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_WriteForm(object):
+ def setupUi(self, WriteForm):
+ WriteForm.setObjectName("WriteForm")
+ WriteForm.resize(238, 107)
+ WriteForm.setModal(True)
+ self.verticalLayout = QtWidgets.QVBoxLayout(WriteForm)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.ishex = QtWidgets.QCheckBox(WriteForm)
+ self.ishex.setObjectName("ishex")
+ self.horizontalLayout.addWidget(self.ishex)
+ self.value = QtWidgets.QLineEdit(WriteForm)
+ self.value.setObjectName("value")
+ self.horizontalLayout.addWidget(self.value)
+ self.verticalLayout.addLayout(self.horizontalLayout)
+ self.buttonBox = QtWidgets.QDialogButtonBox(WriteForm)
+ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.verticalLayout.addWidget(self.buttonBox)
+
+ self.retranslateUi(WriteForm)
+ self.buttonBox.accepted.connect(WriteForm.accept)
+ self.buttonBox.rejected.connect(WriteForm.reject)
+ QtCore.QMetaObject.connectSlotsByName(WriteForm)
+
+ def retranslateUi(self, WriteForm):
+ _translate = QtCore.QCoreApplication.translate
+ WriteForm.setWindowTitle(_translate("WriteForm", "Write"))
+ self.ishex.setText(_translate("WriteForm", "Hex"))
diff --git a/src/gui/ui/dialogs/write_form.ui b/src/gui/ui/dialogs/write_form.ui
new file mode 100644
index 0000000..731ee2d
--- /dev/null
+++ b/src/gui/ui/dialogs/write_form.ui
@@ -0,0 +1,81 @@
+
+
+ WriteForm
+
+
+
+ 0
+ 0
+ 238
+ 107
+
+
+
+ Write
+
+
+ true
+
+
+ -
+
+
-
+
+
+ Hex
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ WriteForm
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ WriteForm
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/gui/views/saved_address_view.py b/src/gui/views/saved_address_view.py
index 9aab5b6..90facb3 100644
--- a/src/gui/views/saved_address_view.py
+++ b/src/gui/views/saved_address_view.py
@@ -14,15 +14,13 @@
# along with Foobar. If not, see .
#
-from PyQt5.Qt import QTreeView, QComboBox, QWidget
-from PyQt5.QtCore import QModelIndex, pyqtSlot, QMutexLocker
+from PyQt5.Qt import QTreeView
+from PyQt5.QtCore import QModelIndex, pyqtSlot
-from gui.models.saved_address_model import SavedAddressModel
-from gui.threads.saved_results_thread import mutex, SavedResultsThread
-from gui.items.tree_item import SavedAddressHeaderEnum, TreeItem
from gui.delegates.type_delegate import TypeDelegate
+from gui.items.tree_item import SavedAddressHeaderEnum, TreeItem
+from gui.models.saved_address_model import SavedAddressModel
from memory.type import Type
-from memory.value import Value
class SavedAddressView(QTreeView):
@@ -35,7 +33,6 @@ def __init__(self, parent=None):
self.setItemDelegateForColumn(SavedAddressHeaderEnum.TYPE, type_delegate)
self._datamodel.layoutChanged.connect(self.__init_comboboxes)
-
def append_row(self, value):
"""
Places a value at the end of the root item
diff --git a/src/memory/binary_io.py b/src/memory/binary_io.py
index 4cb6ed3..35a5fcf 100644
--- a/src/memory/binary_io.py
+++ b/src/memory/binary_io.py
@@ -41,3 +41,16 @@ def _read(self, address: int, value_type: Type):
bytes_read = mem.read(size)
return value_type.get_format().unpack(bytes_read)[0]
+
+ def _write(self, address: int, data: bytes):
+ """
+ writes data to a given address
+
+ :param address: address to write to
+ :param data: data in bytes to write
+ :return: bytes written
+ """
+
+ with open(f"/proc/{self.pid}/mem", "r+b") as mem:
+ mem.seek(address)
+ return mem.write(data)
diff --git a/src/memory/value.py b/src/memory/value.py
index e845e8c..9b98bad 100644
--- a/src/memory/value.py
+++ b/src/memory/value.py
@@ -64,8 +64,8 @@ def read(self):
self.value = super()._read(self.address, self.type)
return self.value
- def write(self, address):
- pass
+ def write(self, new_value):
+ self._write(self.address, self.type.get_format().pack(new_value))
def change_type(self, typeof: Type):
print("Swapping type")