2017-09-27 20:23:18 +00:00
|
|
|
#ifndef CUTTER_H
|
2017-09-25 12:55:41 +00:00
|
|
|
#define CUTTER_H
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-10-03 12:42:31 +00:00
|
|
|
// Workaround for compile errors on Windows
|
2017-03-30 03:07:34 +00:00
|
|
|
#ifdef _WIN32
|
2017-10-15 19:19:48 +00:00
|
|
|
#include <r_addr_interval_msvc.h>
|
|
|
|
#endif //_WIN32
|
2017-03-30 03:07:34 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
#include "r_core.h"
|
|
|
|
|
2017-10-03 12:42:31 +00:00
|
|
|
// Workaround for compile errors on Windows
|
2017-03-30 03:07:34 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#undef min
|
2017-10-03 12:42:31 +00:00
|
|
|
#undef max
|
2017-03-30 03:07:34 +00:00
|
|
|
#endif //_WIN32
|
|
|
|
|
2017-10-15 19:19:48 +00:00
|
|
|
#include <QMap>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QObject>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QJsonDocument>
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
#define HAVE_LATEST_LIBR2 false
|
|
|
|
|
2017-09-25 17:51:49 +00:00
|
|
|
#define CutterRListForeach(list, it, type, x) \
|
2017-03-29 10:18:37 +00:00
|
|
|
if (list) for (it = list->head; it && ((x=(type*)it->data)); it = it->n)
|
|
|
|
|
|
|
|
#define __alert(x) QMessageBox::question (this, "Alert", QString(x), QMessageBox::Ok)
|
|
|
|
#define __question(x) (QMessageBox::Yes==QMessageBox::question (this, "Alert", QString(x), QMessageBox::Yes| QMessageBox::No))
|
|
|
|
|
2017-09-25 12:55:41 +00:00
|
|
|
#define APPNAME "Cutter"
|
2017-11-27 16:24:31 +00:00
|
|
|
#define CUTTER_VERSION "1.0"
|
2017-09-25 12:55:41 +00:00
|
|
|
|
2017-10-14 09:35:49 +00:00
|
|
|
#define Core() (CutterCore::getInstance())
|
|
|
|
|
2017-10-03 18:38:34 +00:00
|
|
|
typedef ut64 RVA;
|
|
|
|
#define RVA_INVALID UT64_MAX
|
|
|
|
|
2017-04-09 18:42:45 +00:00
|
|
|
class RCoreLocked
|
2017-04-09 17:12:36 +00:00
|
|
|
{
|
2017-04-09 19:55:06 +00:00
|
|
|
RCore *core;
|
2017-04-09 18:42:45 +00:00
|
|
|
|
|
|
|
public:
|
2017-04-09 19:55:06 +00:00
|
|
|
explicit RCoreLocked(RCore *core);
|
|
|
|
RCoreLocked(const RCoreLocked &) = delete;
|
|
|
|
RCoreLocked &operator=(const RCoreLocked &) = delete;
|
|
|
|
RCoreLocked(RCoreLocked &&);
|
2017-04-09 17:12:36 +00:00
|
|
|
~RCoreLocked();
|
2017-04-09 19:55:06 +00:00
|
|
|
operator RCore *() const;
|
|
|
|
RCore *operator->() const;
|
2017-10-03 18:38:34 +00:00
|
|
|
RVA seek(RVA offset);
|
|
|
|
RVA getSeek();
|
2017-04-09 17:12:36 +00:00
|
|
|
};
|
|
|
|
|
2017-04-28 13:09:40 +00:00
|
|
|
inline QString RAddressString(RVA addr)
|
|
|
|
{
|
|
|
|
return QString::asprintf("%#010llx", addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline QString RSizeString(RVA size)
|
|
|
|
{
|
|
|
|
return QString::asprintf("%lld", size);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct FunctionDescription
|
|
|
|
{
|
|
|
|
RVA offset;
|
|
|
|
RVA size;
|
|
|
|
QString name;
|
|
|
|
|
|
|
|
bool contains(RVA addr) const { return addr >= offset && addr < offset + size; }
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ImportDescription
|
|
|
|
{
|
|
|
|
RVA plt;
|
|
|
|
int ordinal;
|
|
|
|
QString bind;
|
|
|
|
QString type;
|
|
|
|
QString name;
|
|
|
|
};
|
|
|
|
|
2017-05-19 07:45:26 +00:00
|
|
|
struct ExportDescription
|
|
|
|
{
|
|
|
|
RVA vaddr;
|
|
|
|
RVA paddr;
|
|
|
|
RVA size;
|
|
|
|
QString type;
|
|
|
|
QString name;
|
|
|
|
QString flag_name;
|
|
|
|
};
|
|
|
|
|
2017-04-28 13:09:40 +00:00
|
|
|
struct SymbolDescription
|
|
|
|
{
|
|
|
|
RVA vaddr;
|
|
|
|
QString bind;
|
|
|
|
QString type;
|
|
|
|
QString name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CommentDescription
|
|
|
|
{
|
|
|
|
RVA offset;
|
|
|
|
QString name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct RelocDescription
|
|
|
|
{
|
|
|
|
RVA vaddr;
|
|
|
|
RVA paddr;
|
|
|
|
QString type;
|
|
|
|
QString name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct StringDescription
|
|
|
|
{
|
|
|
|
RVA vaddr;
|
|
|
|
QString string;
|
|
|
|
};
|
|
|
|
|
2017-05-03 09:09:57 +00:00
|
|
|
struct FlagspaceDescription
|
|
|
|
{
|
|
|
|
QString name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FlagDescription
|
|
|
|
{
|
|
|
|
RVA offset;
|
|
|
|
RVA size;
|
|
|
|
QString name;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SectionDescription
|
|
|
|
{
|
|
|
|
RVA vaddr;
|
|
|
|
RVA paddr;
|
|
|
|
RVA size;
|
|
|
|
RVA vsize;
|
|
|
|
QString name;
|
|
|
|
QString flags;
|
|
|
|
};
|
|
|
|
|
2017-07-13 18:49:12 +00:00
|
|
|
struct EntrypointDescription
|
|
|
|
{
|
|
|
|
RVA vaddr;
|
|
|
|
RVA paddr;
|
|
|
|
RVA baddr;
|
|
|
|
RVA laddr;
|
|
|
|
RVA haddr;
|
|
|
|
QString type;
|
|
|
|
};
|
|
|
|
|
2017-06-07 19:35:38 +00:00
|
|
|
struct XrefDescription
|
2017-06-07 10:56:55 +00:00
|
|
|
{
|
|
|
|
RVA from;
|
2017-11-27 16:05:10 +00:00
|
|
|
QString from_str;
|
2017-06-07 10:56:55 +00:00
|
|
|
RVA to;
|
2017-11-27 16:05:10 +00:00
|
|
|
QString to_str;
|
2017-06-07 10:56:55 +00:00
|
|
|
QString type;
|
|
|
|
};
|
|
|
|
|
2017-09-29 11:32:53 +00:00
|
|
|
struct RBinPluginDescription
|
|
|
|
{
|
|
|
|
QString name;
|
|
|
|
QString description;
|
|
|
|
QString license;
|
|
|
|
QString type;
|
|
|
|
};
|
|
|
|
|
2017-04-28 13:09:40 +00:00
|
|
|
Q_DECLARE_METATYPE(FunctionDescription)
|
|
|
|
Q_DECLARE_METATYPE(ImportDescription)
|
2017-05-19 07:45:26 +00:00
|
|
|
Q_DECLARE_METATYPE(ExportDescription)
|
2017-04-28 13:09:40 +00:00
|
|
|
Q_DECLARE_METATYPE(SymbolDescription)
|
|
|
|
Q_DECLARE_METATYPE(CommentDescription)
|
|
|
|
Q_DECLARE_METATYPE(RelocDescription)
|
|
|
|
Q_DECLARE_METATYPE(StringDescription)
|
2017-05-03 09:09:57 +00:00
|
|
|
Q_DECLARE_METATYPE(FlagspaceDescription)
|
|
|
|
Q_DECLARE_METATYPE(FlagDescription)
|
2017-06-07 19:35:38 +00:00
|
|
|
Q_DECLARE_METATYPE(XrefDescription)
|
2017-07-13 18:49:12 +00:00
|
|
|
Q_DECLARE_METATYPE(EntrypointDescription)
|
2017-09-29 11:32:53 +00:00
|
|
|
Q_DECLARE_METATYPE(RBinPluginDescription)
|
2017-04-28 13:09:40 +00:00
|
|
|
|
2017-09-25 12:55:41 +00:00
|
|
|
class CutterCore: public QObject
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
2017-10-09 18:08:35 +00:00
|
|
|
friend class ccClass;
|
2017-04-28 13:09:40 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
public:
|
2017-09-25 12:55:41 +00:00
|
|
|
explicit CutterCore(QObject *parent = 0);
|
|
|
|
~CutterCore();
|
2017-11-03 17:22:54 +00:00
|
|
|
static CutterCore *getInstance();
|
2017-04-28 13:09:40 +00:00
|
|
|
|
2017-10-09 18:08:35 +00:00
|
|
|
/* Getters */
|
2017-09-25 12:55:41 +00:00
|
|
|
RVA getOffset() const { return core_->offset; }
|
2017-03-29 10:18:37 +00:00
|
|
|
int getCycloComplex(ut64 addr);
|
|
|
|
int getFcnSize(ut64 addr);
|
|
|
|
int fcnCyclomaticComplexity(ut64 addr);
|
|
|
|
int fcnBasicBlockCount(ut64 addr);
|
2017-06-07 19:35:38 +00:00
|
|
|
int fcnEndBbs(RVA addr);
|
2017-10-09 18:08:35 +00:00
|
|
|
static QString sanitizeStringForCommand(QString s);
|
2017-03-29 10:18:37 +00:00
|
|
|
QString cmd(const QString &str);
|
2017-04-18 08:33:35 +00:00
|
|
|
QJsonDocument cmdj(const QString &str);
|
2017-09-27 20:23:18 +00:00
|
|
|
QStringList cmdList(const QString &str) { auto l = cmd(str).split("\n"); l.removeAll(""); return l; }
|
2017-03-29 10:18:37 +00:00
|
|
|
void renameFunction(QString prev_name, QString new_name);
|
2017-11-27 08:22:52 +00:00
|
|
|
void renameFlag(QString old_name, QString new_name);
|
2017-12-01 10:46:13 +00:00
|
|
|
|
|
|
|
void setComment(RVA addr, const QString &cmt);
|
2017-03-29 10:18:37 +00:00
|
|
|
void delComment(ut64 addr);
|
2017-12-01 10:46:13 +00:00
|
|
|
|
2017-11-28 13:13:22 +00:00
|
|
|
void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID);
|
2017-12-03 11:47:26 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
void setOptions(QString key);
|
2017-09-29 11:32:53 +00:00
|
|
|
bool loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, bool rw = false, int va = 0, int idx = 0, bool loadbin = false, const QString &forceBinPlugin = nullptr);
|
2017-03-29 10:18:37 +00:00
|
|
|
bool tryFile(QString path, bool rw);
|
2017-07-24 11:05:28 +00:00
|
|
|
void analyze(int level, QList<QString> advanced);
|
2017-10-16 19:00:47 +00:00
|
|
|
|
|
|
|
// Seek functions
|
2017-03-29 10:18:37 +00:00
|
|
|
void seek(QString addr);
|
2017-04-28 13:09:40 +00:00
|
|
|
void seek(ut64 offset);
|
2017-10-16 19:00:47 +00:00
|
|
|
void seekPrev();
|
|
|
|
void seekNext();
|
|
|
|
RVA getOffset();
|
2017-10-12 19:55:15 +00:00
|
|
|
|
2017-11-02 06:48:32 +00:00
|
|
|
RVA prevOpAddr(RVA startAddr, int count);
|
|
|
|
RVA nextOpAddr(RVA startAddr, int count);
|
|
|
|
|
2017-12-06 23:19:14 +00:00
|
|
|
// Disassembly/Graph/Hexdump/Pseudocode view priority
|
|
|
|
enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Pseudocode };
|
2017-11-04 11:46:29 +00:00
|
|
|
MemoryWidgetType getMemoryWidgetPriority() const { return memoryWidgetPriority; }
|
|
|
|
void setMemoryWidgetPriority(MemoryWidgetType type) { memoryWidgetPriority = type; }
|
|
|
|
void triggerRaisePrioritizedMemoryWidget() { emit raisePrioritizedMemoryWidget(memoryWidgetPriority); }
|
2017-10-22 10:21:44 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
ut64 math(const QString &expr);
|
2017-04-09 19:55:06 +00:00
|
|
|
QString itoa(ut64 num, int rdx = 16);
|
2017-10-01 14:36:40 +00:00
|
|
|
|
2017-10-09 18:08:35 +00:00
|
|
|
/* Config related */
|
2017-10-01 14:36:40 +00:00
|
|
|
void setConfig(const QString &k, const QString &v);
|
|
|
|
void setConfig(const QString &k, int v);
|
|
|
|
void setConfig(const QString &k, bool v);
|
|
|
|
void setConfig(const QString &k, const char *v) { setConfig(k, QString(v)); }
|
2017-09-02 08:17:48 +00:00
|
|
|
int getConfigi(const QString &k);
|
2017-10-01 14:36:40 +00:00
|
|
|
bool getConfigb(const QString &k);
|
2017-09-02 08:17:48 +00:00
|
|
|
QString getConfig(const QString &k);
|
2017-10-01 14:36:40 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
QString assemble(const QString &code);
|
2017-04-12 20:44:05 +00:00
|
|
|
QString disassemble(const QString &hex);
|
2017-06-07 15:48:36 +00:00
|
|
|
QString disassembleSingleInstruction(RVA addr);
|
2017-03-29 10:18:37 +00:00
|
|
|
void setDefaultCPU();
|
2017-04-13 14:24:23 +00:00
|
|
|
void setCPU(QString arch, QString cpu, int bits, bool temporary = false);
|
2017-04-09 19:55:06 +00:00
|
|
|
RAnalFunction *functionAt(ut64 addr);
|
2017-03-29 10:18:37 +00:00
|
|
|
QString cmdFunctionAt(QString addr);
|
2017-04-28 13:09:40 +00:00
|
|
|
QString cmdFunctionAt(RVA addr);
|
2017-10-09 18:08:35 +00:00
|
|
|
|
2017-12-10 20:40:15 +00:00
|
|
|
QString createFunctionAt(RVA addr, QString name);
|
|
|
|
void markString(RVA addr);
|
|
|
|
|
2017-10-09 18:08:35 +00:00
|
|
|
/* SDB */
|
2017-03-29 10:18:37 +00:00
|
|
|
QList<QString> sdbList(QString path);
|
|
|
|
QList<QString> sdbListKeys(QString path);
|
|
|
|
QString sdbGet(QString path, QString key);
|
|
|
|
bool sdbSet(QString path, QString key, QString val);
|
|
|
|
int get_size();
|
|
|
|
ulong get_baddr();
|
|
|
|
QList<QList<QString>> get_exec_sections();
|
|
|
|
QString getOffsetInfo(QString addr);
|
2017-11-28 11:56:38 +00:00
|
|
|
RVA getOffsetJump(RVA addr);
|
2017-12-06 23:19:14 +00:00
|
|
|
QString getDecompiledCode(RVA addr);
|
2017-03-29 10:18:37 +00:00
|
|
|
QString getDecompiledCode(QString addr);
|
|
|
|
QString getFileInfo();
|
|
|
|
QStringList getStats();
|
|
|
|
QString getSimpleGraph(QString function);
|
|
|
|
QString binStart;
|
|
|
|
QString binEnd;
|
|
|
|
void getOpcodes();
|
|
|
|
QList<QString> opcodes;
|
|
|
|
QList<QString> regs;
|
2017-03-30 16:47:50 +00:00
|
|
|
void setSettings();
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-09-27 20:23:18 +00:00
|
|
|
void loadPDB(const QString &file);
|
2017-04-28 13:09:40 +00:00
|
|
|
|
|
|
|
QList<RVA> getSeekHistory();
|
2017-05-03 09:09:57 +00:00
|
|
|
|
|
|
|
QStringList getAsmPluginNames();
|
|
|
|
QStringList getAnalPluginNames();
|
|
|
|
|
2017-05-13 18:09:36 +00:00
|
|
|
QStringList getProjectNames();
|
2017-10-21 19:20:10 +00:00
|
|
|
void openProject(const QString &name);
|
|
|
|
void saveProject(const QString &name);
|
|
|
|
|
|
|
|
static bool isProjectNameValid(const QString &name);
|
|
|
|
|
|
|
|
const QString &getNotes() const { return notes; }
|
|
|
|
void setNotes(const QString ¬es);
|
2017-05-13 18:09:36 +00:00
|
|
|
|
2017-09-29 11:32:53 +00:00
|
|
|
QList<RBinPluginDescription> getRBinPluginDescriptions(const QString &type = nullptr);
|
|
|
|
|
2017-04-28 13:09:40 +00:00
|
|
|
QList<FunctionDescription> getAllFunctions();
|
|
|
|
QList<ImportDescription> getAllImports();
|
2017-05-19 07:45:26 +00:00
|
|
|
QList<ExportDescription> getAllExports();
|
2017-04-28 13:09:40 +00:00
|
|
|
QList<SymbolDescription> getAllSymbols();
|
2017-04-28 13:38:01 +00:00
|
|
|
QList<CommentDescription> getAllComments(const QString &filterType);
|
2017-04-28 13:09:40 +00:00
|
|
|
QList<RelocDescription> getAllRelocs();
|
|
|
|
QList<StringDescription> getAllStrings();
|
2017-05-03 09:09:57 +00:00
|
|
|
QList<FlagspaceDescription> getAllFlagspaces();
|
|
|
|
QList<FlagDescription> getAllFlags(QString flagspace = NULL);
|
|
|
|
QList<SectionDescription> getAllSections();
|
2017-07-13 18:49:12 +00:00
|
|
|
QList<EntrypointDescription> getAllEntrypoint();
|
2017-04-28 13:09:40 +00:00
|
|
|
|
2017-06-08 22:40:43 +00:00
|
|
|
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString::null);
|
2017-06-07 10:56:55 +00:00
|
|
|
|
2017-07-11 11:05:42 +00:00
|
|
|
void addFlag(RVA offset, QString name, RVA size);
|
2017-11-30 21:30:51 +00:00
|
|
|
void triggerFlagsChanged();
|
|
|
|
|
|
|
|
void triggerVarsChanged();
|
|
|
|
void triggerFunctionRenamed(const QString &prevName, const QString &newName);
|
2017-07-11 11:05:42 +00:00
|
|
|
|
2017-11-19 12:56:10 +00:00
|
|
|
void triggerRefreshAll();
|
|
|
|
|
2017-10-01 14:36:40 +00:00
|
|
|
void triggerAsmOptionsChanged();
|
|
|
|
|
|
|
|
void resetDefaultAsmOptions();
|
|
|
|
void saveDefaultAsmOptions();
|
|
|
|
|
2017-04-09 17:12:36 +00:00
|
|
|
RCoreLocked core() const;
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
/* fields */
|
2017-04-09 17:12:36 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
Sdb *db;
|
2017-04-28 13:09:40 +00:00
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
signals:
|
2017-11-19 12:56:10 +00:00
|
|
|
void refreshAll();
|
|
|
|
|
2017-04-28 13:09:40 +00:00
|
|
|
void functionRenamed(QString prev_name, QString new_name);
|
2017-11-30 21:30:51 +00:00
|
|
|
void varsChanged();
|
2017-07-11 11:05:42 +00:00
|
|
|
void flagsChanged();
|
|
|
|
void commentsChanged();
|
2017-11-28 13:13:22 +00:00
|
|
|
void instructionChanged(RVA offset);
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-10-21 19:20:10 +00:00
|
|
|
void notesChanged(const QString ¬es);
|
|
|
|
void projectSaved(const QString &name);
|
|
|
|
|
2017-10-01 14:36:40 +00:00
|
|
|
/*!
|
|
|
|
* emitted when config regarding disassembly display changes
|
|
|
|
*/
|
|
|
|
void asmOptionsChanged();
|
|
|
|
|
2017-10-09 18:08:35 +00:00
|
|
|
/*!
|
|
|
|
* \brief seekChanged is emitted each time radare2 seek value is modified
|
|
|
|
* \param offset
|
|
|
|
*/
|
|
|
|
void seekChanged(RVA offset);
|
|
|
|
|
2017-11-04 11:46:29 +00:00
|
|
|
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
public slots:
|
|
|
|
|
|
|
|
private:
|
|
|
|
QString default_arch;
|
|
|
|
QString default_cpu;
|
|
|
|
int default_bits;
|
2017-04-09 17:12:36 +00:00
|
|
|
|
2017-11-04 11:46:29 +00:00
|
|
|
MemoryWidgetType memoryWidgetPriority;
|
|
|
|
|
2017-10-21 19:20:10 +00:00
|
|
|
QString notes;
|
|
|
|
|
2017-04-09 17:12:36 +00:00
|
|
|
RCore *core_;
|
2017-03-29 10:18:37 +00:00
|
|
|
};
|
|
|
|
|
2017-10-09 18:08:35 +00:00
|
|
|
class ccClass : public CutterCore
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
2017-09-25 12:55:41 +00:00
|
|
|
#endif // CUTTER_H
|