2019-02-26 17:49:41 +00:00
2020-07-19 19:23:00 +00:00
Cutter Development Guidelines
===============================
2019-02-26 17:49:41 +00:00
2020-07-19 19:23:00 +00:00
.. note ::
New to Cutter development? Check out our :doc: `tutorial for new developers <getting-started>` .
2020-03-01 19:47:34 +00:00
2020-07-19 19:23:00 +00:00
Common Usage
--------------
2019-02-26 17:49:41 +00:00
2020-07-26 04:56:46 +00:00
CutterCore Class
2019-02-26 17:49:41 +00:00
~~~~~~~~~~~~~~~~
2020-12-15 08:49:50 +00:00
This is the main class where every link with Rizin is made. It is *unique*
2020-07-19 19:23:00 +00:00
across the whole process. To access it, simply call `` Core() `` .
2019-02-26 17:49:41 +00:00
Example:
.. code :: cpp
Core()->getOffset();
2020-12-15 08:49:50 +00:00
Calling a Rizin Command
2019-02-26 17:49:41 +00:00
~~~~~~~~~~~~~~~~~~~~~~~~~
2020-12-15 08:49:50 +00:00
There are multiple ways to call a Rizin command:
2020-03-21 13:30:23 +00:00
- `` CutterCore::cmdj(<command>) `` - To be used with json commands like `` cmdj("agj") `` or `` cmdj("aflj") `` .
2020-12-15 08:49:50 +00:00
This is the command we used to fetch structured data from Rizin.
2020-03-21 13:30:23 +00:00
2020-12-15 08:49:50 +00:00
- `` CutterCore::cmdRaw(<command>) `` - Executes a single Rizin command
without going through Rizin shell functionality like output redirects, grep, and multiple command parsing.
2020-07-19 19:23:00 +00:00
2020-07-26 04:56:46 +00:00
The command then returns its output. This should be used when a command doesn't have output or the output should be handled as-is. If possible, using the JSON variation with `` cmdj `` is always preferred.
2020-03-21 13:30:23 +00:00
2020-12-15 08:49:50 +00:00
- `` CutterCore::cmdRawAt(<command>, <address>) `` - Executes a single Rizin command in a given address and returns the output. This helps avoiding weird strings concatenation like `` cmd("ph " + hash + " @ " + QString::num(address)) `` .
2020-03-21 13:30:23 +00:00
- `` CutterCore::cmd() `` - *(Discouraged)* Only use it when `` cmdj `` or `` cmdRaw `` cannot be used. This is used for complex commands using concatenation of several commands (`` px 5; pd 7; afl; `` ), for grepping (`` pd 5~call `` ). for commands inside commands (`` ?e ` afn. ` `` ) and so on.
2020-07-26 04:56:46 +00:00
This is also used when the output is complex and is not parsed correctly in `` cmdRaw `` .
2020-03-21 13:30:23 +00:00
Make sure to carefully sanitize user-controlled variables that are passed to the command, to avoid unexpected command injections.
2019-12-10 07:32:52 +00:00
2020-12-15 08:49:50 +00:00
Generally, if one needs to retrieve information from a Rizin command, it
2020-07-26 04:56:46 +00:00
is preferred to use the JSON API.
2019-02-26 17:49:41 +00:00
Example:
.. code :: cpp
QJsonArray array = Core()->cmdj("pdj 1 @ main").array();
2020-07-26 04:56:46 +00:00
Seek the Current File
2019-02-26 17:49:41 +00:00
~~~~~~~~~~~~~~~~~~~~~
2020-12-15 08:49:50 +00:00
To modify Rizin seek use `` CutterCore::seek(const RVA offset) `` . This
2019-02-26 17:49:41 +00:00
is important because it will emit a
`` CutterCore::seekChanged(RVA offset) `` signal. Never ever call
`` cmd("s offset") `` ;
Example:
.. code :: cpp
Core()->seek(0x00C0FFEE);
2020-03-21 13:30:23 +00:00
.. note ::
Cutter also supports a silent seek which doesn't trigger the `` seekChanged `` event and doesn't add new entries to the seek history.
2020-07-26 04:56:46 +00:00
Creating a Widget
2019-02-26 17:49:41 +00:00
~~~~~~~~~~~~~~~~~
Make sure to connect the `` CutterCore::seekChanged(RVA offset) `` signal
2020-12-15 08:49:50 +00:00
so your widget refreshes its output when Rizin seek is modified
2019-02-26 17:49:41 +00:00
(switching to another function, etc.).
2020-07-26 04:56:46 +00:00
Coding Style
------------
2019-02-26 17:49:41 +00:00
2021-01-24 14:49:38 +00:00
In general, we follow a slightly customized version of `the official Qt guidelines <https://wiki.qt.io/Qt_Coding_Style> `__
to format the code. Before sending a pull request, you will need to use `clang-format` <https://clang.llvm.org/docs/ClangFormat.html> `__ (version 8 or newer)
2019-02-26 17:49:41 +00:00
to format the code. The command line for formatting the code according
to the style is:
.. code :: bash
2021-01-24 14:49:38 +00:00
clang-format -style=file -i src/filename.cpp
If your changes were done on many files across the codebase, you can use this oneliner to tun `` clang-format `` on the entire 'src' directory:
.. code :: bash
find ./src -regex '.*\.\(cpp\|h\)' -exec clang-format -style=file -i {} \;
2019-02-26 17:49:41 +00:00
2019-03-24 08:41:49 +00:00
In contrast to the official guidelines of Qt, in Cutter we always use curly braces in conditional statements, even if the body of a conditional statement contains only one line.
.. code :: cpp
// Wrong
if (address.isEmpty())
return false;
// Correct
if (address.isEmpty()) {
return false;
}
// Wrong
for (int i = 0; i < 10; ++i)
qDebug("%i", i);
// Correct
for (int i = 0; i < 10; ++i) {
qDebug("%i", i);
}
2019-03-08 07:20:13 +00:00
2019-03-16 22:54:44 +00:00
Includes
2020-03-01 19:47:34 +00:00
~~~~~~~~
2019-03-16 22:54:44 +00:00
2019-12-28 20:54:00 +00:00
Strive to include only **required** definitions inside header files.
This will avoid triggering additional unnecessary compilations.
2019-03-16 22:54:44 +00:00
If you only need to know that a class exists but don't need the prototype,
you can declare the class like this:
.. code :: cpp
class MyClassThatExists;
/** ... ** /
private:
MyClassThatExists *classInstance;
And then include the class header inside your .cpp so you can use that class.
If you need something in the source file (.cpp) that is not a class member,
then add the include in the source file.
2019-12-28 20:54:00 +00:00
The includes must be ordered from local to global. That is, first include
2020-07-26 04:56:46 +00:00
any local header file (with double quotes like `#include "common/Helpers.h"` .
2019-12-28 20:54:00 +00:00
Then, after an empty newline, include Qt definitions like
2019-03-16 22:54:44 +00:00
`#include <QShortcut>` .
2019-12-28 20:54:00 +00:00
Finally, include the standard C++ headers you need.
2019-03-16 22:54:44 +00:00
Includes must be sorted by alphabetical order.
2019-03-08 07:20:13 +00:00
Docstrings
2020-03-01 19:47:34 +00:00
~~~~~~~~~~
2019-03-08 07:20:13 +00:00
Our API reference is generated using Doxygen, so when it comes to
function documentation, please use the following format:
.. code :: cpp
/**
* @brief Add a new param to the accumulator
*/
virtual void accumulate(RefreshDeferrerParams params) =0;
2019-02-26 17:49:41 +00:00
Loops
2020-03-01 19:47:34 +00:00
~~~~~
2019-02-26 17:49:41 +00:00
2019-12-28 20:54:00 +00:00
We use the C++11 foreach loop style, which means any “foreach” loop should
2019-02-26 17:49:41 +00:00
look like:
.. code :: cpp
for (QJsonValue value : importsArray) {
doSomething(value);
}
2019-03-16 22:54:29 +00:00
nullptr
2020-03-01 19:47:34 +00:00
~~~~~~~
2019-02-26 17:49:41 +00:00
Please do not use `` 0 `` nor `` Q_NULLPTR `` , only use `` nullptr `` .
Example:
.. code :: cpp
QObject *object = nullptr;
2020-08-08 15:35:40 +00:00
Connecting Qt Signals
~~~~~~~~~~~~~~~~~~~~~
2019-02-26 17:49:41 +00:00
2020-08-08 15:35:40 +00:00
Use one of the following methods for connecting signals to slots:
2019-02-26 17:49:41 +00:00
.. code :: cpp
2020-08-08 15:35:40 +00:00
// typically you will make connection in the constructor to a member of current class
connect(this->ui->button1, &QPushButton::clicked,
this, &MyObject::buttonClicked); // Good
// you can also connect directly other object slots
connect(checkbox, &QCheckBox::toggled, widget, &QWidget::setEnabled); // Good
// use lambda for passing extra arguments
connect(button1, &QPushButton::clicked, this, [this](){ foo(getBar()); }); // Good
2019-02-26 17:49:41 +00:00
2020-03-01 19:47:34 +00:00
This syntax performs compile-time type checks and allows the use of lambda
2020-08-08 15:35:40 +00:00
functions. Other approaches for connecting signals can silently break at runtime.
Don't use the older macro based syntax or automatic name based connections.
.. code :: cpp
// SIGNAL and SLOT macros
connect(sender, SIGNAL(clicked), this, SLOT(buttonClicked)); // BAD
// automatic name based connection
slot:
void on_actionNew_triggered(); // BAD
// 3 argument connect without receiver object
connect(sender, &SomeObject::signal, [this](){ this->foo(getBar()); }); // BAD
2020-03-01 19:47:34 +00:00
2020-07-26 04:56:46 +00:00
General Coding Advices
2020-03-01 19:47:34 +00:00
----------------------
2019-02-26 17:49:41 +00:00
2020-07-26 04:56:46 +00:00
Functions Documentation
2019-02-26 17:49:41 +00:00
~~~~~~~~~~~~~~~~~~~~~~~
2020-07-26 04:56:46 +00:00
You can find the class documentation in the API Reference menu item.
2020-02-28 08:39:29 +00:00
2020-07-26 04:56:46 +00:00
Updating the Git Submodules
~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-02-28 08:39:29 +00:00
Git submodules play a major part in Cutter. This, because Cutter is powered
2020-12-15 08:49:50 +00:00
by Rizin, its parent project, and it tries to stay up-to-date with its
2020-02-28 08:39:29 +00:00
recent version, which allows us to implement new features, and enjoy bug
2020-12-15 08:49:50 +00:00
fixes and performance improvements on Rizin. Often, we need to update
the Rizin submodule or the others, to push their most recent
2020-07-26 04:56:46 +00:00
version to Cutter.
2020-02-28 08:39:29 +00:00
You can view the list of all the submodules from the cutter root folder with:
.. code :: sh
git config --file .gitmodules --get-regexp path | awk '{ print $2 }'
To update all the submodules at once, run these commands from the
cutter root folder:
.. code :: sh
git submodule foreach git pull origin master
git add submodule_name_1 submodule_name_2
git commit -m "Update submodules"
2020-12-15 08:49:50 +00:00
More likely, you'll only need to update the *rizin* submodule.
2020-02-28 08:39:29 +00:00
In order to update one submodule individually, use the following code:
.. code :: sh
2020-12-15 08:49:50 +00:00
cd rizin
2021-12-21 12:39:25 +00:00
git checkout dev && git pull
2020-02-28 08:39:29 +00:00
cd ..
2020-12-15 08:49:50 +00:00
git add rizin
git commit -m "Update rizin submodule"
2020-03-01 19:47:34 +00:00
2020-07-26 04:56:46 +00:00
Useful Resources (Qt Development)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-03-01 19:47:34 +00:00
* `Signals & Slots <https://doc.qt.io/qt-5/signalsandslots.html> `__
2020-07-26 04:56:46 +00:00
* `Model/View Programming <https://doc.qt.io/qt-5/model-view-programming.html> `__ - read this if you are going to work with a list or table-like widgets
2020-03-01 19:47:34 +00:00
* `QAction <https://doc.qt.io/qt-5/qaction.html#details> `__