1 #ifndef CUTTER_H 2 #define CUTTER_H 3 4 #include "core/CutterCommon.h" 5 #include "core/CutterDescriptions.h" 6 #include "common/BasicInstructionHighlighter.h" 7 8 #include <QMap> 9 #include <QMenu> 10 #include <QDebug> 11 #include <QObject> 12 #include <QStringList> 13 #include <QMessageBox> 14 #include <QJsonDocument> 15 #include <QErrorMessage> 16 #include <QMutex> 17 #include <QDir> 18 19 class AsyncTaskManager; 20 class BasicInstructionHighlighter; 21 class CutterCore; 22 class Decompiler; 23 class R2Task; 24 class R2TaskDialog; 25 26 #include "common/BasicBlockHighlighter.h" 27 #include "common/R2Task.h" 28 #include "common/Helpers.h" 29 #include "dialogs/R2TaskDialog.h" 30 31 #define Core() (CutterCore::instance()) 32 33 class RCoreLocked; 34 35 class CUTTER_EXPORT CutterCore: public QObject 36 { 37 Q_OBJECT 38 39 friend class RCoreLocked; 40 friend class R2Task; 41 42 public: 43 explicit CutterCore(QObject *parent = nullptr); 44 ~CutterCore(); 45 static CutterCore *instance(); 46 47 void initialize(bool loadPlugins = true); 48 void loadCutterRC(); 49 void loadDefaultCutterRC(); 50 QDir getCutterRCDefaultDirectory() const; 51 getAsyncTaskManager()52 AsyncTaskManager *getAsyncTaskManager() { return asyncTaskManager; } 53 getOffset()54 RVA getOffset() const { return core_->offset; } 55 56 /* Core functions (commands) */ 57 static QString sanitizeStringForCommand(QString s); 58 /** 59 * @brief send a command to radare2 60 * @param str the command you want to execute 61 * @return command output 62 * @note if you want to seek to an address, you should use CutterCore::seek. 63 */ 64 QString cmd(const char *str); cmd(const QString & str)65 QString cmd(const QString &str) { return cmd(str.toUtf8().constData()); } 66 /** 67 * @brief send a command to radare2 asynchronously 68 * @param str the command you want to execute 69 * @param task a shared pointer that will be returned with the R2 command task 70 * @note connect to the &R2Task::finished signal to add your own logic once 71 * the command is finished. Use task->getResult()/getResultJson() for the 72 * return value. 73 * Once you have setup connections you can start the task with task->startTask() 74 * If you want to seek to an address, you should use CutterCore::seek. 75 */ 76 bool asyncCmd(const char *str, QSharedPointer<R2Task> &task); asyncCmd(const QString & str,QSharedPointer<R2Task> & task)77 bool asyncCmd(const QString &str, QSharedPointer<R2Task> &task) { return asyncCmd(str.toUtf8().constData(), task); } 78 79 /** 80 * @brief Execute a radare2 command \a cmd. By nature, the API 81 * is executing raw commands, and thus ignores multiple commands and overcome command injections. 82 * @param cmd - a raw command to execute. Passing multiple commands (e.g "px 5; pd 7 && pdf") will result in them treated as arguments to first command. 83 * @return the output of the command 84 */ 85 QString cmdRaw(const char *cmd); 86 87 /** 88 * @brief a wrapper around cmdRaw(const char *cmd,). 89 */ cmdRaw(const QString & cmd)90 QString cmdRaw(const QString &cmd) { return cmdRaw(cmd.toUtf8().constData()); }; 91 92 /** 93 * @brief Execute a radare2 command \a cmd at \a address. The function will preform a silent seek to the address 94 * without triggering the seekChanged event nor adding new entries to the seek history. By nature, the 95 * API is executing a single command without going through radare2 shell, and thus ignores multiple commands 96 * and tries to overcome command injections. 97 * @param cmd - a raw command to execute. If multiple commands will be passed (e.g "px 5; pd 7 && pdf") then 98 * only the first command will be executed. 99 * @param address - an address to which Cutter will temporarily seek. 100 * @return the output of the command 101 */ 102 QString cmdRawAt(const char *cmd, RVA address); 103 104 /** 105 * @brief a wrapper around cmdRawAt(const char *cmd, RVA address). 106 */ cmdRawAt(const QString & str,RVA address)107 QString cmdRawAt(const QString &str, RVA address) { return cmdRawAt(str.toUtf8().constData(), address); } 108 109 QJsonDocument cmdj(const char *str); cmdj(const QString & str)110 QJsonDocument cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); } 111 QJsonDocument cmdjAt(const char *str, RVA address); cmdList(const char * str)112 QStringList cmdList(const char *str) { return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS); } cmdList(const QString & str)113 QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); } 114 QString cmdTask(const QString &str); 115 QJsonDocument cmdjTask(const QString &str); 116 /** 117 * @brief send a command to radare2 and check for ESIL errors 118 * @param command the command you want to execute 119 * @note If you want to seek to an address, you should use CutterCore::seek. 120 */ 121 void cmdEsil(const char *command); cmdEsil(const QString & command)122 void cmdEsil(const QString &command) { cmdEsil(command.toUtf8().constData()); } 123 /** 124 * @brief send a command to radare2 and check for ESIL errors 125 * @param command the command you want to execute 126 * @param task a shared pointer that will be returned with the R2 command task 127 * @note connect to the &R2Task::finished signal to add your own logic once 128 * the command is finished. Use task->getResult()/getResultJson() for the 129 * return value. 130 * Once you have setup connections you can start the task with task->startTask() 131 * If you want to seek to an address, you should use CutterCore::seek. 132 */ 133 bool asyncCmdEsil(const char *command, QSharedPointer<R2Task> &task); asyncCmdEsil(const QString & command,QSharedPointer<R2Task> & task)134 bool asyncCmdEsil(const QString &command, QSharedPointer<R2Task> &task) { return asyncCmdEsil(command.toUtf8().constData(), task); } 135 QString getVersionInformation(); 136 137 QJsonDocument parseJson(const char *res, const char *cmd = nullptr); 138 QJsonDocument parseJson(const char *res, const QString &cmd = QString()) 139 { 140 return parseJson(res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData()); 141 } 142 143 QStringList autocomplete(const QString &cmd, RLinePromptType promptType, size_t limit = 4096); 144 145 /* Functions methods */ 146 void renameFunction(const RVA offset, const QString &newName); 147 void delFunction(RVA addr); 148 void renameFlag(QString old_name, QString new_name); 149 /** 150 * @brief Renames the specified local variable in the function specified by the 151 * address given. 152 * @param newName Specifies the name to which the current name of the variable 153 * should be renamed. 154 * @param oldName Specifies the current name of the function variable. 155 * @param functionAddress Specifies the exact address of the function. 156 */ 157 void renameFunctionVariable(QString newName, QString oldName, RVA functionAddress); 158 159 /** 160 * @param addr 161 * @return a function that contains addr or nullptr 162 */ 163 RAnalFunction *functionIn(ut64 addr); 164 165 /** 166 * @param addr 167 * @return the function that has its entrypoint at addr or nullptr 168 */ 169 RAnalFunction *functionAt(ut64 addr); 170 171 RVA getFunctionStart(RVA addr); 172 RVA getFunctionEnd(RVA addr); 173 RVA getLastFunctionInstruction(RVA addr); 174 QString cmdFunctionAt(QString addr); 175 QString cmdFunctionAt(RVA addr); 176 QString createFunctionAt(RVA addr); 177 QString createFunctionAt(RVA addr, QString name); 178 QStringList getDisassemblyPreview(RVA address, int num_of_lines); 179 180 /* Flags */ 181 void delFlag(RVA addr); 182 void delFlag(const QString &name); 183 void addFlag(RVA offset, QString name, RVA size); 184 QString listFlagsAsStringAt(RVA addr); 185 /** 186 * @brief Get nearest flag at or before offset. 187 * @param offset search position 188 * @param flagOffsetOut address of returned flag 189 * @return flag name 190 */ 191 QString nearestFlag(RVA offset, RVA *flagOffsetOut); 192 void triggerFlagsChanged(); 193 194 /* Edition functions */ 195 QString getInstructionBytes(RVA addr); 196 QString getInstructionOpcode(RVA addr); 197 void editInstruction(RVA addr, const QString &inst); 198 void nopInstruction(RVA addr); 199 void jmpReverse(RVA addr); 200 void editBytes(RVA addr, const QString &inst); 201 void editBytesEndian(RVA addr, const QString &bytes); 202 203 /* Code/Data */ 204 void setToCode(RVA addr); 205 enum class StringTypeFormats { None, ASCII_LATIN1, UTF8 }; 206 /** 207 * @brief Adds string at address 208 * That function calls the 'Cs' command 209 * \param addr The address of the array where the string will be applied 210 * \param size The size of string 211 * \param type The type of string 212 */ 213 void setAsString(RVA addr, int size = 0, StringTypeFormats type = StringTypeFormats::None); 214 /** 215 * @brief Removes string at address 216 * That function calls the 'Cs-' command 217 * \param addr The address of the array where the string will be applied 218 */ 219 void removeString(RVA addr); 220 /** 221 * @brief Gets string at address 222 * That function calls the 'ps' command 223 * \param addr The address of the first byte of the array 224 * @return string at requested address 225 */ 226 QString getString(RVA addr); 227 void setToData(RVA addr, int size, int repeat = 1); 228 int sizeofDataMeta(RVA addr); 229 230 /* Comments */ 231 void setComment(RVA addr, const QString &cmt); 232 void delComment(RVA addr); 233 QString getCommentAt(RVA addr); 234 void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID); 235 void setCurrentBits(int bits, RVA offset = RVA_INVALID); 236 237 /** 238 * @brief Changes immediate displacement to structure offset 239 * This function makes use of the "aht" command of r2 to apply structure 240 * offset to the immediate displacement used in the given instruction 241 * \param structureOffset The name of struct which will be applied 242 * \param offset The address of the instruction where the struct will be applied 243 */ 244 void applyStructureOffset(const QString &structureOffset, RVA offset = RVA_INVALID); 245 246 /* Classes */ 247 QList<QString> getAllAnalClasses(bool sorted); 248 QList<AnalMethodDescription> getAnalClassMethods(const QString &cls); 249 QList<AnalBaseClassDescription> getAnalClassBaseClasses(const QString &cls); 250 QList<AnalVTableDescription> getAnalClassVTables(const QString &cls); 251 void createNewClass(const QString &cls); 252 void renameClass(const QString &oldName, const QString &newName); 253 void deleteClass(const QString &cls); 254 bool getAnalMethod(const QString &cls, const QString &meth, AnalMethodDescription *desc); 255 void renameAnalMethod(const QString &className, const QString &oldMethodName, const QString &newMethodName); 256 void setAnalMethod(const QString &cls, const AnalMethodDescription &meth); 257 258 /* File related methods */ 259 bool loadFile(QString path, ut64 baddr = 0LL, ut64 mapaddr = 0LL, int perms = R_PERM_R, 260 int va = 0, bool loadbin = false, const QString &forceBinPlugin = QString()); 261 bool tryFile(QString path, bool rw); 262 bool mapFile(QString path, RVA mapaddr); 263 void loadScript(const QString &scriptname); 264 QJsonArray getOpenedFiles(); 265 266 /* Seek functions */ 267 void seek(QString thing); 268 void seek(ut64 offset); 269 void seekSilent(ut64 offset); seekSilent(QString thing)270 void seekSilent(QString thing) { seekSilent(math(thing)); } 271 void seekPrev(); 272 void seekNext(); 273 void updateSeek(); 274 /** 275 * @brief Raise a memory widget showing current offset, prefer last active 276 * memory widget. 277 */ 278 void showMemoryWidget(); 279 /** 280 * @brief Seek to \p offset and raise a memory widget showing it. 281 * @param offset 282 */ 283 void seekAndShow(ut64 offset); 284 /** 285 * @brief \see CutterCore::show(ut64) 286 * @param thing - addressable expression 287 */ 288 void seekAndShow(QString thing); 289 RVA getOffset(); 290 RVA prevOpAddr(RVA startAddr, int count); 291 RVA nextOpAddr(RVA startAddr, int count); 292 293 /* Math functions */ 294 ut64 math(const QString &expr); 295 ut64 num(const QString &expr); 296 QString itoa(ut64 num, int rdx = 16); 297 298 /* Config functions */ 299 void setConfig(const char *k, const char *v); 300 void setConfig(const QString &k, const char *v); 301 void setConfig(const char *k, const QString &v); setConfig(const QString & k,const QString & v)302 void setConfig(const QString &k, const QString &v) { setConfig(k.toUtf8().constData(), v); } 303 void setConfig(const char *k, int v); setConfig(const QString & k,int v)304 void setConfig(const QString &k, int v) { setConfig(k.toUtf8().constData(), v); } 305 void setConfig(const char *k, bool v); setConfig(const QString & k,bool v)306 void setConfig(const QString &k, bool v) { setConfig(k.toUtf8().constData(), v); } 307 void setConfig(const char *k, const QVariant &v); setConfig(const QString & k,const QVariant & v)308 void setConfig(const QString &k, const QVariant &v) { setConfig(k.toUtf8().constData(), v); } 309 int getConfigi(const char *k); getConfigi(const QString & k)310 int getConfigi(const QString &k) { return getConfigi(k.toUtf8().constData()); } 311 ut64 getConfigut64(const char *k); getConfigut64(const QString & k)312 ut64 getConfigut64(const QString &k) { return getConfigut64(k.toUtf8().constData()); } 313 bool getConfigb(const char *k); getConfigb(const QString & k)314 bool getConfigb(const QString &k) { return getConfigb(k.toUtf8().constData()); } 315 QString getConfig(const char *k); getConfig(const QString & k)316 QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); } 317 QString getConfigDescription(const char *k); 318 QList<QString> getColorThemes(); 319 320 /* Assembly\Hexdump related methods */ 321 QByteArray assemble(const QString &code); 322 QString disassemble(const QByteArray &data); 323 QString disassembleSingleInstruction(RVA addr); 324 QList<DisassemblyLine> disassembleLines(RVA offset, int lines); 325 326 static QByteArray hexStringToBytes(const QString &hex); 327 static QString bytesToHexString(const QByteArray &bytes); 328 enum class HexdumpFormats { Normal, Half, Word, Quad, Signed, Octal }; 329 QString hexdump(RVA offset, int size, HexdumpFormats format); 330 QString getHexdumpPreview(RVA offset, int size); 331 332 void setCPU(QString arch, QString cpu, int bits); 333 void setEndianness(bool big); 334 335 /* SDB */ 336 QList<QString> sdbList(QString path); 337 QList<QString> sdbListKeys(QString path); 338 QString sdbGet(QString path, QString key); 339 bool sdbSet(QString path, QString key, QString val); 340 341 /* Debug */ 342 QJsonDocument getRegistersInfo(); 343 QJsonDocument getRegisterValues(); 344 QString getRegisterName(QString registerRole); 345 RVA getProgramCounterValue(); 346 void setRegister(QString regName, QString regValue); 347 void setCurrentDebugThread(int tid); 348 /** 349 * @brief Attach to a given pid from a debug session 350 */ 351 void setCurrentDebugProcess(int pid); 352 /** 353 * @brief Returns a list of stack address and their telescoped references 354 * @param size number of bytes to scan 355 * @param depth telescoping depth 356 */ 357 QList<QJsonObject> getStack(int size = 0x100, int depth = 6); 358 /** 359 * @brief Recursively dereferences pointers starting at the specified address 360 * up to a given depth 361 * @param addr telescoping addr 362 * @param depth telescoping depth 363 */ 364 QJsonObject getAddrRefs(RVA addr, int depth); 365 /** 366 * @brief return a RefDescription with a formatted ref string and configured colors 367 * @param ref the "ref" JSON node from getAddrRefs 368 */ 369 RefDescription formatRefDesc(QJsonObject ref); 370 /** 371 * @brief Get a list of a given process's threads 372 * @param pid The pid of the process, -1 for the currently debugged process 373 * @return JSON object result of dptj 374 */ 375 QJsonDocument getProcessThreads(int pid); 376 /** 377 * @brief Get a list of a given process's child processes 378 * @param pid The pid of the process, -1 for the currently debugged process 379 * @return JSON object result of dptj 380 */ 381 QJsonDocument getChildProcesses(int pid); 382 QJsonDocument getBacktrace(); 383 void startDebug(); 384 void startEmulation(); 385 /** 386 * @brief attach to a remote debugger 387 * @param uri remote debugger uri 388 * @note attachedRemote(bool) signals the result 389 */ 390 void attachRemote(const QString &uri); 391 void attachDebug(int pid); 392 void stopDebug(); 393 void suspendDebug(); 394 void syncAndSeekProgramCounter(); 395 void continueDebug(); 396 void continueUntilCall(); 397 void continueUntilSyscall(); 398 void continueUntilDebug(QString offset); 399 void stepDebug(); 400 void stepOverDebug(); 401 void stepOutDebug(); 402 403 void addBreakpoint(const BreakpointDescription &config); 404 void updateBreakpoint(int index, const BreakpointDescription &config); 405 void toggleBreakpoint(RVA addr); 406 void delBreakpoint(RVA addr); 407 void delAllBreakpoints(); 408 void enableBreakpoint(RVA addr); 409 void disableBreakpoint(RVA addr); 410 /** 411 * @brief Enable or disable breakpoint tracing. 412 * @param index - breakpoint index to modify 413 * @param enabled - true if tracing should be enabled 414 */ 415 void setBreakpointTrace(int index, bool enabled); 416 int breakpointIndexAt(RVA addr); 417 BreakpointDescription getBreakpointAt(RVA addr); 418 419 bool isBreakpoint(const QList<RVA> &breakpoints, RVA addr); 420 QList<RVA> getBreakpointsAddresses(); 421 422 /** 423 * @brief Get all breakpoinst that are belong to a functions at this address 424 */ 425 QList<RVA> getBreakpointsInFunction(RVA funcAddr); 426 QString getActiveDebugPlugin(); 427 QStringList getDebugPlugins(); 428 void setDebugPlugin(QString plugin); 429 bool isDebugTaskInProgress(); 430 /** 431 * @brief Check if we can use output/input redirection with the currently debugged process 432 */ 433 bool isRedirectableDebugee(); 434 bool currentlyDebugging = false; 435 bool currentlyEmulating = false; 436 int currentlyAttachedToPID = -1; 437 QString currentlyOpenFile; 438 439 /* Decompilers */ 440 QList<Decompiler *> getDecompilers(); 441 Decompiler *getDecompilerById(const QString &id); 442 443 /** 444 * Register a new decompiler 445 * 446 * The decompiler must have a unique id, otherwise this method will fail. 447 * The decompiler's parent will be set to this CutterCore instance, so it will automatically be freed later. 448 * 449 * @return whether the decompiler was registered successfully 450 */ 451 bool registerDecompiler(Decompiler *decompiler); 452 453 RVA getOffsetJump(RVA addr); 454 QJsonDocument getFileInfo(); 455 QJsonDocument getSignatureInfo(); 456 QJsonDocument getFileVersionInfo(); 457 QStringList getStats(); 458 void setGraphEmpty(bool empty); 459 bool isGraphEmpty(); 460 461 void getOpcodes(); 462 QList<QString> opcodes; 463 QList<QString> regs; 464 void setSettings(); 465 466 void loadPDB(const QString &file); 467 468 QByteArray ioRead(RVA addr, int len); 469 470 QList<RVA> getSeekHistory(); 471 472 /* Plugins */ 473 QStringList getAsmPluginNames(); 474 QStringList getAnalPluginNames(); 475 476 /* Projects */ 477 QStringList getProjectNames(); 478 void openProject(const QString &name); 479 void saveProject(const QString &name); 480 void deleteProject(const QString &name); 481 static bool isProjectNameValid(const QString &name); 482 483 /* Widgets */ 484 QList<RBinPluginDescription> getRBinPluginDescriptions(const QString &type = QString()); 485 QList<RIOPluginDescription> getRIOPluginDescriptions(); 486 QList<RCorePluginDescription> getRCorePluginDescriptions(); 487 QList<RAsmPluginDescription> getRAsmPluginDescriptions(); 488 QList<FunctionDescription> getAllFunctions(); 489 QList<ImportDescription> getAllImports(); 490 QList<ExportDescription> getAllExports(); 491 QList<SymbolDescription> getAllSymbols(); 492 QList<HeaderDescription> getAllHeaders(); 493 QList<ZignatureDescription> getAllZignatures(); 494 QList<CommentDescription> getAllComments(const QString &filterType); 495 QList<RelocDescription> getAllRelocs(); 496 QList<StringDescription> getAllStrings(); 497 QList<FlagspaceDescription> getAllFlagspaces(); 498 QList<FlagDescription> getAllFlags(QString flagspace = QString()); 499 QList<SectionDescription> getAllSections(); 500 QList<SegmentDescription> getAllSegments(); 501 QList<EntrypointDescription> getAllEntrypoint(); 502 QList<BinClassDescription> getAllClassesFromBin(); 503 QList<BinClassDescription> getAllClassesFromFlags(); 504 QList<ResourcesDescription> getAllResources(); 505 QList<VTableDescription> getAllVTables(); 506 507 /** 508 * @return all loaded types 509 */ 510 QList<TypeDescription> getAllTypes(); 511 512 /** 513 * @return all loaded primitive types 514 */ 515 QList<TypeDescription> getAllPrimitiveTypes(); 516 517 /** 518 * @return all loaded unions 519 */ 520 QList<TypeDescription> getAllUnions(); 521 522 /** 523 * @return all loaded structs 524 */ 525 QList<TypeDescription> getAllStructs(); 526 527 /** 528 * @return all loaded enums 529 */ 530 QList<TypeDescription> getAllEnums(); 531 532 /** 533 * @return all loaded typedefs 534 */ 535 QList<TypeDescription> getAllTypedefs(); 536 537 /** 538 * @brief Fetching the C representation of a given Type 539 * @param name - the name or the type of the given Type / Struct 540 * @param category - the category of the given Type (Struct, Union, Enum, ...) 541 * @return The type decleration as C output 542 */ 543 QString getTypeAsC(QString name, QString category); 544 545 546 /** 547 * @brief Adds new types 548 * It first uses the r_parse_c_string() function from radare2 API to parse the 549 * supplied C file (in the form of a string). If there were errors, they are displayed. 550 * If there were no errors, it uses sdb_query_lines() function from radare2 API 551 * to save the parsed types returned by r_parse_c_string() 552 * \param str Contains the definition of the data types 553 * \return returns an empty QString if there was no error, else returns the error 554 */ 555 QString addTypes(const char *str); addTypes(const QString & str)556 QString addTypes(const QString &str) { return addTypes(str.toUtf8().constData()); } 557 558 /** 559 * @brief Checks if the given address is mapped to a region 560 * @param addr The address to be checked 561 * @return true if addr is mapped, false otherwise 562 */ 563 bool isAddressMapped(RVA addr); 564 565 QList<MemoryMapDescription> getMemoryMap(); 566 QList<SearchDescription> getAllSearch(QString search_for, QString space); 567 BlockStatistics getBlockStatistics(unsigned int blocksCount); 568 QList<BreakpointDescription> getBreakpoints(); 569 QList<ProcessDescription> getAllProcesses(); 570 /** 571 * @brief returns a list of reg values and their telescoped references 572 * @param depth telescoping depth 573 */ 574 QList<QJsonObject> getRegisterRefs(int depth = 6); 575 QVector<RegisterRefValueDescription> getRegisterRefValues(); 576 QList<VariableDescription> getVariables(RVA at); 577 /** 578 * @brief Fetches all the writes or reads to the specified local variable 'variableName' 579 * in the function in which the specified offset is a part of. 580 * @param variableName Name of the local variable. 581 * @param findWrites If this is true, then locations at which modification happen to the specified 582 * local variable is fetched. Else, the locations at which the local is variable is read is fetched. 583 * @param offset An offset in the function in which the specified local variable exist. 584 * @return A list of XrefDescriptions that contains details of all the writes or reads that happen to the 585 * variable 'variableName'. 586 */ 587 QList<XrefDescription> getXRefsForVariable(QString variableName, bool findWrites, RVA offset); 588 QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, 589 const QString &filterType = QString()); 590 591 QList<StringDescription> parseStringsJson(const QJsonDocument &doc); 592 593 void handleREvent(int type, void *data); 594 595 /* Signals related */ 596 void triggerVarsChanged(); 597 void triggerFunctionRenamed(const RVA offset, const QString &newName); 598 void triggerRefreshAll(); 599 void triggerAsmOptionsChanged(); 600 void triggerGraphOptionsChanged(); 601 602 void message(const QString &msg, bool debug = false); 603 604 QStringList getSectionList(); 605 606 RCoreLocked core(); 607 608 static QString ansiEscapeToHtml(const QString &text); 609 BasicBlockHighlighter *getBBHighlighter(); 610 BasicInstructionHighlighter *getBIHighlighter(); 611 612 /** 613 * @brief Enable or dsiable Cache mode. Cache mode is used to imagine writing to the opened file 614 * without committing the changes to the disk. 615 * @param enabled 616 */ 617 void setIOCache(bool enabled); 618 619 /** 620 * @brief Check if Cache mode is enabled. 621 * @return true if Cache is enabled, otherwise return false. 622 */ 623 bool isIOCacheEnabled() const; 624 625 /** 626 * @brief Commit write cache to the file on disk. 627 */ 628 void commitWriteCache(); 629 630 /** 631 * @brief Enable or disable Write mode. When the file is opened in write mode, any changes to it will be immediately 632 * committed to the file on disk, thus modify the file. This function wrap radare2 function which re-open the file with 633 * the desired permissions. 634 * @param enabled 635 */ 636 void setWriteMode(bool enabled); 637 /** 638 * @brief Check if the file is opened in write mode. 639 * @return true if write mode is enabled, otherwise return false. 640 */ 641 bool isWriteModeEnabled(); 642 643 signals: 644 void refreshAll(); 645 646 void functionRenamed(const RVA offset, const QString &new_name); 647 void varsChanged(); 648 void functionsChanged(); 649 void flagsChanged(); 650 void commentsChanged(RVA addr); 651 void registersChanged(); 652 void instructionChanged(RVA offset); 653 void breakpointsChanged(RVA offset); 654 void refreshCodeViews(); 655 void stackChanged(); 656 /** 657 * @brief update all the widgets that are affected by rebasing in debug mode 658 */ 659 void codeRebased(); 660 661 void switchedThread(); 662 void switchedProcess(); 663 664 void classNew(const QString &cls); 665 void classDeleted(const QString &cls); 666 void classRenamed(const QString &oldName, const QString &newName); 667 void classAttrsChanged(const QString &cls); 668 669 /** 670 * @brief end of current debug event received 671 */ 672 void debugProcessFinished(int pid); 673 674 void attachedRemote(bool successfully); 675 676 void projectSaved(bool successfully, const QString &name); 677 678 void ioCacheChanged(bool newval); 679 void writeModeChanged(bool newval); 680 void ioModeChanged(); 681 682 /** 683 * emitted when debugTask started or finished running 684 */ 685 void debugTaskStateChanged(); 686 687 /** 688 * emitted when config regarding disassembly display changes 689 */ 690 void asmOptionsChanged(); 691 692 /** 693 * emitted when config regarding graph display changes 694 */ 695 void graphOptionsChanged(); 696 697 /** 698 * @brief seekChanged is emitted each time radare2 seek value is modified 699 * @param offset 700 */ 701 void seekChanged(RVA offset); 702 703 void toggleDebugView(); 704 705 void newMessage(const QString &msg); 706 void newDebugMessage(const QString &msg); 707 708 void showMemoryWidgetRequested(); 709 710 private: 711 QString notes; 712 713 /** 714 * Internal reference to the RCore. 715 * NEVER use this directly! Always use the CORE_LOCK(); macro and access it like core->... 716 */ 717 RCore *core_ = nullptr; 718 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 719 QMutex coreMutex; 720 #else 721 QRecursiveMutex coreMutex; 722 #endif 723 int coreLockDepth = 0; 724 void *coreBed = nullptr; 725 726 AsyncTaskManager *asyncTaskManager; 727 RVA offsetPriorDebugging = RVA_INVALID; 728 QErrorMessage msgBox; 729 730 QList<Decompiler *> decompilers; 731 732 bool emptyGraph = false; 733 BasicBlockHighlighter *bbHighlighter; 734 bool iocache = false; 735 BasicInstructionHighlighter biHighlighter; 736 737 QSharedPointer<R2Task> debugTask; 738 R2TaskDialog *debugTaskDialog; 739 740 QVector<QString> getCutterRCFilePaths() const; 741 }; 742 743 class CUTTER_EXPORT RCoreLocked 744 { 745 CutterCore * const core; 746 747 public: 748 explicit RCoreLocked(CutterCore *core); 749 RCoreLocked(const RCoreLocked &) = delete; 750 RCoreLocked &operator=(const RCoreLocked &) = delete; 751 RCoreLocked(RCoreLocked &&); 752 ~RCoreLocked(); 753 operator RCore *() const; 754 RCore *operator->() const; 755 }; 756 757 #endif // CUTTER_H 758