From 6338b9a8754d1d04189861790a6ad7f71b09b617 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Wed, 22 Jun 2022 07:42:36 +0800 Subject: [PATCH 01/18] Use RZ_STRING_ENC_* enums instead of RZ_BIN_STRING_ENC_* Change in Rizin 4dfad73567e069e8c2804ed87935197d60aad1b4 Fixes #290 --- src/RizinScope.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index 043cd4ea..5f7bc0fc 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -462,12 +463,12 @@ Symbol *RizinScope::registerFlag(RzFlagItem *flag) const { switch(str->type) { - case RZ_BIN_STRING_ENC_WIDE_LE: - case RZ_BIN_STRING_ENC_WIDE_BE: + case RZ_STRING_ENC_UTF16LE: + case RZ_STRING_ENC_UTF16BE: tn = "char16_t"; break; - case RZ_BIN_STRING_ENC_WIDE32_LE: - case RZ_BIN_STRING_ENC_WIDE32_BE: + case RZ_STRING_ENC_UTF32LE: + case RZ_STRING_ENC_UTF32BE: tn = "char32_t"; break; } From 6d70dfb4aef10365e2e7f214427bcbda9c0cc89d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 22 Jun 2022 12:00:02 +0200 Subject: [PATCH 02/18] Fix expected test results --- test/db/extras/asm_ghidra | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/db/extras/asm_ghidra b/test/db/extras/asm_ghidra index 92d1ecd5..63a0b7dd 100644 --- a/test/db/extras/asm_ghidra +++ b/test/db/extras/asm_ghidra @@ -188,7 +188,8 @@ EXPECT=< Date: Fri, 1 Jul 2022 13:49:37 +0200 Subject: [PATCH 03/18] Update for RzBinStrDb changes in rizin (Fix #292) (#293) Broken in rizin 6567e6ba4eb1b83ca8e8cf41c10a825ca51085f5 Fixed with this in rizin f355dcf557fa1e019cc63e69560708f35a69fd76 --- src/RizinScope.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index 5f7bc0fc..68cc42a9 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -450,12 +450,7 @@ Symbol *RizinScope::registerFlag(RzFlagItem *flag) const auto bf = reinterpret_cast(pos); if(!bf->o) continue; - void *s = ht_up_find(bf->o->strings_db, flag->offset, nullptr); - if(s) - { - str = reinterpret_cast(s); - break; - } + str = rz_bin_object_get_string_at(bf->o, flag->offset, true); } Datatype *ptype; const char *tn = "char"; From 979ab29ecdcb08d83b05eefbe4409669946133cb Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Fri, 12 Aug 2022 21:37:26 +0800 Subject: [PATCH 04/18] Update rizin version header (#294) --- src/RizinScope.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index 68cc42a9..b88a0ec4 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include #include From 60bced6080dcb1ad1d678a6709d5b5a356ce96d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Mon, 15 Aug 2022 10:03:53 +0200 Subject: [PATCH 05/18] Update for latest rizin (Fix #296) Changes in rizin a73e8ecd4dbccb26cdd322500b3f47b9a14d39fa (and 40ca22202b6ed6ea3ee58f049aa6e67b0f07c4dc for tests) --- src/analysis_ghidra.cpp | 4 +-- test/db/extras/analysis_ghidra | 50 +++++++++++++++++----------------- test/db/extras/asm_ghidra | 28 +++++++++---------- test/db/extras/ghidra | 8 +++--- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/analysis_ghidra.cpp b/src/analysis_ghidra.cpp index cb898f84..7066de90 100644 --- a/src/analysis_ghidra.cpp +++ b/src/analysis_ghidra.cpp @@ -15,7 +15,7 @@ static SleighAsm sanalysis; -static int archinfo(RzAnalysis *analysis, int query) +static int archinfo(RzAnalysis *analysis, RzAnalysisInfoType query) { // This is to check if RzCore plugin set cpu properly. if(!analysis->cpu) @@ -36,7 +36,7 @@ static int archinfo(RzAnalysis *analysis, int query) return -1; } - if(query == RZ_ANALYSIS_ARCHINFO_ALIGN) + if(query == RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN) return sanalysis.alignment; else return -1; diff --git a/test/db/extras/analysis_ghidra b/test/db/extras/analysis_ghidra index 7124ac2e..b092ac80 100644 --- a/test/db/extras/analysis_ghidra +++ b/test/db/extras/analysis_ghidra @@ -81,95 +81,95 @@ e asm.arch e asm.cpu e asm.bits wx 89e1 -pdi 1 +pdq 1 ao | grep type ?e ---- wx a168a00408 -pdi 1 +pdq 1 ao | grep type ?e ---- wx a368a00408 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 8945f0 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 8b4510 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 0f4c0d03000000 -pdi 1 +pdq 1 ao | grep type ?e ---- wx cd80 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 55 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 6a00 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 5d -pdi 1 +pdq 1 ao | grep type ?e ---- wx 83f853 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 85c0 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 83c410 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 81ec88100000 -pdi 1 +pdq 1 ao | grep type ?e ---- wx f7ea -pdi 1 +pdq 1 ao | grep type ?e ---- wx f7f2 -pdi 1 +pdq 1 ao | grep type ?e ---- wx d1e8 -pdi 1 +pdq 1 ao | grep type ?e ---- wx d1e0 -pdi 1 +pdq 1 ao | grep type ?e ---- wx d1f8 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 0b25f0ff0000 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 2325f0ff0000 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 3325f0ff0000 -pdi 1 +pdq 1 ao | grep type ?e ---- wx 8703 -pdi 1 +pdq 1 ao | grep type EOF RUN @@ -187,11 +187,11 @@ CMDS=<ambassador = AMBASSADOR_PURE; } else { (bright->window).sunlight = bright->morning->saved_argv[1]; - iVar2 = sym.imp.strcmp((bright->window).sunlight, 0x804a05c); + iVar2 = sym.imp.strcmp((bright->window).sunlight, data.0804a05c); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_REASON; } else { @@ -1935,7 +1935,7 @@ void sym.Aeropause(BrightPtr bright, Bright *argc, char **argv) bright->ambassador = AMBASSADOR_PURE; } else { (bright->window).sunlight = bright->morning->saved_argv[1]; - iVar2 = sym.imp.strcmp((bright->window).sunlight, 0x804a05c); + iVar2 = sym.imp.strcmp((bright->window).sunlight, data.0804a05c); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_REASON; } else { @@ -1995,7 +1995,7 @@ void sym.Aeropause(BrightTypedefd *bright, int32_t argc, char **argv) bright->ambassador = AMBASSADOR_PURE; } else { (bright->window).sunlight = bright->morning->saved_argv[1]; - iVar2 = sym.imp.strcmp((bright->window).sunlight, 0x804a05c); + iVar2 = sym.imp.strcmp((bright->window).sunlight, data.0804a05c); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_REASON; } else { @@ -2055,7 +2055,7 @@ void sym.Aeropause(BrightTypedefdPtr bright, int32_t argc, char **argv) bright->ambassador = AMBASSADOR_PURE; } else { (bright->window).sunlight = bright->morning->saved_argv[1]; - iVar2 = sym.imp.strcmp((bright->window).sunlight, 0x804a05c); + iVar2 = sym.imp.strcmp((bright->window).sunlight, data.0804a05c); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_REASON; } else { From 7a2a6bcdbc99742f217231016e96f239f08d17f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 31 Aug 2022 10:41:14 +0200 Subject: [PATCH 06/18] Remove some unnecessary includes (#300) --- src/RizinScope.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index b88a0ec4..df27404d 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -7,9 +7,6 @@ #include -#include -#include -#include #include #include "RizinUtils.h" From 2dd3d2bf7b9eab7018991e7b62ab3376c6faa9ff Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Fri, 23 Sep 2022 09:17:03 +0200 Subject: [PATCH 07/18] Fixe build due removed callbacks in rizin (#302) --- src/analysis_ghidra.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/analysis_ghidra.cpp b/src/analysis_ghidra.cpp index 7066de90..cf1d7a1d 100644 --- a/src/analysis_ghidra.cpp +++ b/src/analysis_ghidra.cpp @@ -3293,8 +3293,6 @@ RzAnalysisPlugin rz_analysis_plugin_ghidra = { /* .address_bits = */ nullptr, /* .op = */ &sleigh_op, /* .get_reg_profile = */ &get_reg_profile, - /* .fingerprint_bb = */ nullptr, - /* .fingerprint_fcn = */ nullptr, /* .diff_bb = */ nullptr, /* .diff_fcn = */ nullptr, /* .diff_eval = */ nullptr, From ea4573c8823b8cd0de69cfcbfd47189d15cd0e4a Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Wed, 5 Oct 2022 05:55:43 +0200 Subject: [PATCH 08/18] Fix build due removed diff callbacks in rizin (#303) --- src/analysis_ghidra.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/analysis_ghidra.cpp b/src/analysis_ghidra.cpp index cf1d7a1d..a838202d 100644 --- a/src/analysis_ghidra.cpp +++ b/src/analysis_ghidra.cpp @@ -3293,9 +3293,6 @@ RzAnalysisPlugin rz_analysis_plugin_ghidra = { /* .address_bits = */ nullptr, /* .op = */ &sleigh_op, /* .get_reg_profile = */ &get_reg_profile, - /* .diff_bb = */ nullptr, - /* .diff_fcn = */ nullptr, - /* .diff_eval = */ nullptr, /* .esil_init = */ esil_sleigh_init, /* .esil_post_loop = */ nullptr, /* .esil_trap = */ nullptr, From 1d32e58984dcc771646c8f6e061ecaaf47fbe442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Fri, 4 Nov 2022 18:17:42 +0100 Subject: [PATCH 09/18] Update for removed rz_analysis_var_all_list() in rizin (#305) This was removed in rizin 3f077bce4a0a7c6323b31d06c6a3a631a988fa5f. --- src/RizinScope.cpp | 267 ++++++++++++++++++++++----------------------- 1 file changed, 130 insertions(+), 137 deletions(-) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index df27404d..c23c2824 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -169,7 +169,6 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const extraPop = arch->translate->getDefaultSize(); RangeList varRanges; // to check for overlaps - RzList *vars = rz_analysis_var_all_list(core->analysis, fcn); auto stackSpace = arch->getStackSpace(); auto addrForVar = [&](RzAnalysisVar *var, bool warn_on_fail) { @@ -216,37 +215,35 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const ParamActive params(false); - if(vars) - { - rz_list_foreach_cpp(vars, [&](RzAnalysisVar *var) { - std::string typeError; - Datatype *type = var->type ? arch->getTypeFactory()->fromRzType(var->type, &typeError) : nullptr; + rz_pvector_foreach_cpp(&fcn->vars, [&](RzAnalysisVar *var) { + std::string typeError; + Datatype *type = var->type ? arch->getTypeFactory()->fromRzType(var->type, &typeError) : nullptr; + if(!type) + { + char *tstr = rz_type_as_string(core->analysis->typedb, var->type); + arch->addWarning("Failed to match type " + to_string(tstr ? tstr : "?") + " for variable " + to_string(var->name) + " to Decompiler type: " + typeError); + rz_mem_free(tstr); + type = arch->types->getBase(core->analysis->bits / 8, TYPE_UNKNOWN); if(!type) - { - char *tstr = rz_type_as_string(core->analysis->typedb, var->type); - arch->addWarning("Failed to match type " + to_string(tstr ? tstr : "?") + " for variable " + to_string(var->name) + " to Decompiler type: " + typeError); - rz_mem_free(tstr); - type = arch->types->getBase(core->analysis->bits / 8, TYPE_UNKNOWN); - if(!type) - return; - } - if(type->getSize() < 1) - { - arch->addWarning("Type " + type->getName() + " of variable " + to_string(var->name) + " has size 0"); - return; - } - var_types[var] = type; - - if(!var->isarg) - return; - auto addr = addrForVar(var, true); - if(addr.isInvalid()) - return; - params.registerTrial(addr, type->getSize()); - int4 i = params.whichTrial(addr, type->getSize()); - params.getTrial(i).markActive(); - }); - } + return true; + } + if(type->getSize() < 1) + { + arch->addWarning("Type " + type->getName() + " of variable " + to_string(var->name) + " has size 0"); + return true; + } + var_types[var] = type; + + if(!var->isarg) + return true; + auto addr = addrForVar(var, true); + if(addr.isInvalid()) + return true; + params.registerTrial(addr, type->getSize()); + int4 i = params.whichTrial(addr, type->getSize()); + params.getTrial(i).markActive(); + return true; + }); if(proto) proto->deriveInputMap(¶ms); @@ -264,131 +261,127 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const }); }; - if(vars) - { - std::vector argsByIndex; - - rz_list_foreach_cpp(vars, [&](RzAnalysisVar *var) { - auto type_it = var_types.find(var); - if(type_it == var_types.end()) - return; - Datatype *type = type_it->second; - bool typelock = true; - - auto addr = addrForVar(var, var->isarg /* Already emitted this warning before */); - if(addr.isInvalid()) - return; - - uintb last = addr.getOffset(); - if(type->getSize() > 0) - last += type->getSize() - 1; - if(last < addr.getOffset()) - { - arch->addWarning("Variable " + to_string(var->name) + " extends beyond the stackframe. Try changing its type to something smaller."); - return; - } - bool overlap = false; - for(const auto &range : varRanges) - { - if(range.getSpace() != addr.getSpace()) - continue; - if(range.getFirst() > last) - continue; - if(range.getLast() < addr.getOffset()) - continue; - overlap = true; - break; - } - - if(overlap) - { - arch->addWarning("Detected overlap for variable " + to_string(var->name)); + std::vector argsByIndex; - if(var->isarg) // Can't have args with typelock=false, otherwise we get segfaults in the Decompiler - return; + rz_pvector_foreach_cpp(&fcn->vars, [&](RzAnalysisVar *var) { + auto type_it = var_types.find(var); + if(type_it == var_types.end()) + return true; + Datatype *type = type_it->second; + bool typelock = true; - typelock = false; - } + auto addr = addrForVar(var, var->isarg /* Already emitted this warning before */); + if(addr.isInvalid()) + return true; - int4 paramIndex = -1; - if(var->isarg) - { - if(proto && !proto->possibleInputParam(addr, type->getSize())) - { - // Prevent segfaults in the Decompiler - arch->addWarning("Removing arg " + to_string(var->name) + " because it doesn't fit into ProtoModel"); - return; - } + uintb last = addr.getOffset(); + if(type->getSize() > 0) + last += type->getSize() - 1; + if(last < addr.getOffset()) + { + arch->addWarning("Variable " + to_string(var->name) + " extends beyond the stackframe. Try changing its type to something smaller."); + return true; + } + bool overlap = false; + for(const auto &range : varRanges) + { + if(range.getSpace() != addr.getSpace()) + continue; + if(range.getFirst() > last) + continue; + if(range.getLast() < addr.getOffset()) + continue; + overlap = true; + break; + } - paramIndex = params.whichTrial(addr, type->getSize()); - if(paramIndex < 0) - { - arch->addWarning("Failed to determine arg index of " + to_string(var->name)); - return; - } - } + if(overlap) + { + arch->addWarning("Detected overlap for variable " + to_string(var->name)); - varRanges.insertRange(addr.getSpace(), addr.getOffset(), last); + if(var->isarg) // Can't have args with typelock=false, otherwise we get segfaults in the Decompiler + return true; - auto mapsymElement = child(symbollistElement, "mapsym"); - auto symbolElement = child(mapsymElement, "symbol", { - { "name", var->name }, - { "typelock", typelock ? "true" : "false" }, - { "namelock", "true" }, - { "readonly", "false" }, - { "cat", var->isarg ? "0" : "-1" } - }); + typelock = false; + } - if(var->isarg) + int4 paramIndex = -1; + if(var->isarg) + { + if(proto && !proto->possibleInputParam(addr, type->getSize())) { - if(argsByIndex.size() < paramIndex + 1) - argsByIndex.resize(paramIndex + 1, nullptr); - - argsByIndex[paramIndex] = symbolElement; + // Prevent segfaults in the Decompiler + arch->addWarning("Removing arg " + to_string(var->name) + " because it doesn't fit into ProtoModel"); + return true; + } - symbolElement->addAttribute("index", to_string(paramIndex < 0 ? 0 : paramIndex)); + paramIndex = params.whichTrial(addr, type->getSize()); + if(paramIndex < 0) + { + arch->addWarning("Failed to determine arg index of " + to_string(var->name)); + return true; } + } - childType(symbolElement, type); - childAddr(mapsymElement, "addr", addr); + varRanges.insertRange(addr.getSpace(), addr.getOffset(), last); - auto rangelist = child(mapsymElement, "rangelist"); - if(var->isarg && var->kind == RZ_ANALYSIS_VAR_KIND_REG) - childRegRange(rangelist); + auto mapsymElement = child(symbollistElement, "mapsym"); + auto symbolElement = child(mapsymElement, "symbol", { + { "name", var->name }, + { "typelock", typelock ? "true" : "false" }, + { "namelock", "true" }, + { "readonly", "false" }, + { "cat", var->isarg ? "0" : "-1" } }); - // Add placeholder args in gaps - for(size_t i=0; iisarg) { - if(argsByIndex[i]) - continue; + if(argsByIndex.size() < paramIndex + 1) + argsByIndex.resize(paramIndex + 1, nullptr); - auto trial = params.getTrial(i); + argsByIndex[paramIndex] = symbolElement; - Datatype *type = arch->types->getBase(trial.getSize(), TYPE_UNKNOWN); - if(!type) - continue; - - auto mapsymElement = child(symbollistElement, "mapsym"); - auto symbolElement = child(mapsymElement, "symbol", { - { "name", "placeholder_" + to_string(i) }, - { "typelock", "true" }, - { "namelock", "true" }, - { "readonly", "false" }, - { "cat", "0" }, - { "index", to_string(i) } - }); - - childAddr(mapsymElement, "addr", trial.getAddress()); - childType(symbolElement, type); - - auto rangelist = child(mapsymElement, "rangelist"); - if(trial.getAddress().getSpace() != arch->translate->getStackSpace()) - childRegRange(rangelist); + symbolElement->addAttribute("index", to_string(paramIndex < 0 ? 0 : paramIndex)); } - } - rz_list_free(vars); + childType(symbolElement, type); + childAddr(mapsymElement, "addr", addr); + + auto rangelist = child(mapsymElement, "rangelist"); + if(var->isarg && var->kind == RZ_ANALYSIS_VAR_KIND_REG) + childRegRange(rangelist); + return true; + }); + + // Add placeholder args in gaps + for(size_t i=0; itypes->getBase(trial.getSize(), TYPE_UNKNOWN); + if(!type) + continue; + + auto mapsymElement = child(symbollistElement, "mapsym"); + auto symbolElement = child(mapsymElement, "symbol", { + { "name", "placeholder_" + to_string(i) }, + { "typelock", "true" }, + { "namelock", "true" }, + { "readonly", "false" }, + { "cat", "0" }, + { "index", to_string(i) } + }); + + childAddr(mapsymElement, "addr", trial.getAddress()); + childType(symbolElement, type); + + auto rangelist = child(mapsymElement, "rangelist"); + if(trial.getAddress().getSpace() != arch->translate->getStackSpace()) + childRegRange(rangelist); + } auto prototypeElement = child(functionElement, "prototype", { { "extrapop", to_string(extraPop) }, From 955bf7f302afc85167eddd76dd7b2dc2a8473f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Mon, 2 Jan 2023 13:29:29 +0100 Subject: [PATCH 10/18] Update for new variable storage in Rizin (#307) Change in Rizin d9950f74792c1dfb565ac491cc7ef706b80e6044 --- src/RizinScope.cpp | 44 +-- test/bins/Makefile | 6 + test/bins/dectest32-sp | Bin 0 -> 14796 bytes test/bins/dectest64-sp | Bin 0 -> 15736 bytes test/db/extras/ghidra | 736 ++++++++++++++++++++++++++--------------- 5 files changed, 496 insertions(+), 290 deletions(-) create mode 100755 test/bins/dectest32-sp create mode 100755 test/bins/dectest64-sp diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index c23c2824..83c83218 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -164,46 +164,29 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const arch->addWarning("Function " + to_string(fcn_name) + " has no calling convention set, args may be inaccurate."); } - int4 extraPop = proto ? proto->getExtraPop() : arch->translate->getDefaultSize(); - if(extraPop == ProtoModel::extrapop_unknown) - extraPop = arch->translate->getDefaultSize(); - RangeList varRanges; // to check for overlaps auto stackSpace = arch->getStackSpace(); auto addrForVar = [&](RzAnalysisVar *var, bool warn_on_fail) { - switch(var->kind) + switch(var->storage.type) { - case RZ_ANALYSIS_VAR_KIND_BPV: + case RZ_ANALYSIS_VAR_STORAGE_STACK: { uintb off; - int delta = var->delta + fcn->bp_off - extraPop; // not 100% sure if extraPop is correct here + st64 delta = var->storage.stack_off; if(delta >= 0) off = delta; else off = stackSpace->getHighest() + delta + 1; return Address(stackSpace, off); } - case RZ_ANALYSIS_VAR_KIND_REG: + case RZ_ANALYSIS_VAR_STORAGE_REG: { - RzRegItem *reg = rz_reg_index_get(core->analysis->reg, var->delta); - if(!reg) - { - if(warn_on_fail) - arch->addWarning("Register for arg " + to_string(var->name) + " not found"); - return Address(); - } - - auto ret = arch->registerAddressFromRizinReg(reg->name); + auto ret = arch->registerAddressFromRizinReg(var->storage.reg); if(ret.isInvalid() && warn_on_fail) arch->addWarning("Failed to match register " + to_string(var->name) + " for arg " + to_string(var->name)); - return ret; } - case RZ_ANALYSIS_VAR_KIND_SPV: - if(warn_on_fail) - arch->addWarning("Var " + to_string(var->name) + " is stack pointer based, which is not supported for decompilation."); - return Address(); default: if(warn_on_fail) arch->addWarning("Failed to get address for var " + to_string(var->name)); @@ -234,7 +217,7 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const } var_types[var] = type; - if(!var->isarg) + if(!rz_analysis_var_is_arg(var)) return true; auto addr = addrForVar(var, true); if(addr.isInvalid()) @@ -270,7 +253,7 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const Datatype *type = type_it->second; bool typelock = true; - auto addr = addrForVar(var, var->isarg /* Already emitted this warning before */); + auto addr = addrForVar(var, rz_analysis_var_is_arg(var) /* Already emitted this warning before */); if(addr.isInvalid()) return true; @@ -299,14 +282,14 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const { arch->addWarning("Detected overlap for variable " + to_string(var->name)); - if(var->isarg) // Can't have args with typelock=false, otherwise we get segfaults in the Decompiler + if(rz_analysis_var_is_arg(var)) // Can't have args with typelock=false, otherwise we get segfaults in the Decompiler return true; typelock = false; } int4 paramIndex = -1; - if(var->isarg) + if(rz_analysis_var_is_arg(var)) { if(proto && !proto->possibleInputParam(addr, type->getSize())) { @@ -331,10 +314,10 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const { "typelock", typelock ? "true" : "false" }, { "namelock", "true" }, { "readonly", "false" }, - { "cat", var->isarg ? "0" : "-1" } + { "cat", rz_analysis_var_is_arg(var) ? "0" : "-1" } }); - if(var->isarg) + if(rz_analysis_var_is_arg(var)) { if(argsByIndex.size() < paramIndex + 1) argsByIndex.resize(paramIndex + 1, nullptr); @@ -348,7 +331,7 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const childAddr(mapsymElement, "addr", addr); auto rangelist = child(mapsymElement, "rangelist"); - if(var->isarg && var->kind == RZ_ANALYSIS_VAR_KIND_REG) + if(rz_analysis_var_is_arg(var) && var->storage.type == RZ_ANALYSIS_VAR_STORAGE_REG) childRegRange(rangelist); return true; }); @@ -383,6 +366,9 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const childRegRange(rangelist); } + int4 extraPop = proto ? proto->getExtraPop() : arch->translate->getDefaultSize(); + if(extraPop == ProtoModel::extrapop_unknown) + extraPop = arch->translate->getDefaultSize(); auto prototypeElement = child(functionElement, "prototype", { { "extrapop", to_string(extraPop) }, { "model", proto ? proto->getName() : "unknown" } diff --git a/test/bins/Makefile b/test/bins/Makefile index 6f90f56f..50eef138 100644 --- a/test/bins/Makefile +++ b/test/bins/Makefile @@ -8,9 +8,15 @@ clean: dectest32: dectest.c types.h gcc -m32 -fno-pic -no-pie -fno-omit-frame-pointer -o dectest32 -O0 dectest.c +dectest32-sp: dectest.c types.h + gcc -m32 -fno-pic -no-pie -fomit-frame-pointer -o dectest32-sp -O0 dectest.c + dectest64: dectest.c types.h gcc -m64 -fno-pic -no-pie -fno-omit-frame-pointer -o dectest64 -O0 dectest.c +dectest64-sp: dectest.c types.h + gcc -m64 -fno-pic -no-pie -fomit-frame-pointer -o dectest64-sp -O0 dectest.c + rec: rec.c types_rec.h gcc -m64 -fno-pic -no-pie -fno-omit-frame-pointer -o rec -O0 rec.c diff --git a/test/bins/dectest32-sp b/test/bins/dectest32-sp new file mode 100755 index 0000000000000000000000000000000000000000..1a648e427816e248563dacbef5c12fe3fe952c3a GIT binary patch literal 14796 zcmeHOZEO_B8J;_@;Tp{OAWm?>QCHNY4he@%93Tmy{>E->FrRG$&2qk5a|h?U<8BQ& zK}pC#gX_>YRmsFYMybHt>O{&Hy4{)tqgfO^QJB`LJ1rP)5u?vA~D zN##$~A3N~g`}NE_GwtL*9QyG+N`Q1XbP|0qTLgwmN`UkMDv;#vq*r{xted>V!^` zzP0C#nA=|mA4&Rq;oqwYu@`+Kb;C!J{?+h9y{WK$4tov!?*3nfjl}xQ-@;^~Z(%aF zAel%F?h5D9;YGHu8b0P|#me=-`HB+ncVxJ%7;J-ah-2Y=F()kK0TBIGzEz<@v}|uY z`Eil5yUcYdGa)m!EYusM0#1GD4SLrN`jAUkAwS^KS)ctsqDdj94P2 z4d(Qi&@?0`3QHtwXakW%O5}`ebRZ)#gGMwS$%;%ikuv&$10=dli^jKU{gFgc3`CO2 zbX2f5Q@U8J=r~S7umLmeJvBc@W`B0B@)v) z15Y`&#v%Yc^wF9Ti%ybO35@G{_Kz{|jm8CaXY7$}{BbD;Bnxi!7; z3rpv2C9YCGV(Hwq#OtURpf`N-^zcXdbC-J8ttovG#yz8((XFlcw|c{=;%l!cf!@-7 z;4Y8U)QP;q&>6RdHH5%+PzI2aexQXMaIT zj-g=HUqIyWJ10tCI`L1xZ|wc6hWaZj))`}#6)V(h2Rma2Gwv5M&I?xCV$j9~N=fwn zx8;oIL#sO`aI(Ge@4o&JoTINd^7BA31jmEra0^pSh2(1YRi zmmALHFDmBXIkWyid#Shd5v=HhHPn&ym-PoNoKarNeQuf~J=fkl5V z`*;#|RLJkH4JkY4Sgi7;{fIKsRvS8T)?eNU)QB+8?g65yrBWE1#*?f)hqb5MwZ}Ko zqSErOe_Qd!yJ-0eEf*Zi5?U6~@<+!qkCsPidDpSrP0MmxjyV=z0j8~Ym40vQh5X41 zr~g|6rJviz;dj{C;SfJZ#K^kZDwkY6+^aYak-zHOX`xOv@f#~H{LmRFYBecHtrf?? zH!1jS#5bWcy`^%yp?$@{>4cyGdV>bbL z8)kf(6P}s2>jd&wm7PI;JU623%b>D(_KBM&Vy_*}H4$0IGC2{O9n0iItaL1s6S2&( zOisjn$Kor<{#>l+ExqNM4(l4i3&)<(V-ND{hwBE$;uS9gUIx4jcp30A;AOzefR_O; z16~IH&oaPG2cK6q5A;QHxkxOXRd+;^gZg7Co|tBJk<}x)bP8-oIyq=0AnMV0TF;4{ zcwQ<763HZOLM%Rr=j5QLKuOSZAS14;s)$9h+k_EMWcip=y#0M8@IL5c&=t_sA7Cdu zr|j`g__!rI{8!UF3SM!^G+AL8cmX{4scD`DuLA!Nd^Y$c@a^C=*o!rMW}3UfxhrPz zJ+nsmb|Z9!qU`rg4e*9U4d@8sFCYNr)>!*lEU`y{#v%Yc^wF9Ti%ybO35 z_}^xrfTzowLEHxQf-2ZN-ap4nyP^&IR6dX9`{Z-Lxo4RT3PI;yk@}U-&2;ERCBXNl zi{RV?)`Q;#z8^FV#QoqsAQtYuMNtXx31K~m`_UPoS)ikNB|!NwINy5?fcOqQIi9(u zH^Gia$!Yc#Teoy4bclCc`2M@Bv>0RU0Br#EgLZ(v4U+!(5FW+go&{gg+WMGUw?a=D z>9pF=5PmpZuVxw_aKu}?mrS^2#7WL^$fAf(P3Gzf=AsDh7o35~LOCyqa8lzXZ#t!e;}RU^q&XG_89LomtTd< zBO7&2do%pAL=d|Bz4-f}%ffgIp)Z^0U$tn2Uc~qaGt3|f1q*0H9!r(Nr8TO+g;-K$!fyR}sv9c$ay zY3rI>y4yA92tbp3qn|JD-*8G`!iRVKoAqou6TxW$z;-QN9NwZES|+L)@xj!#aNjQH z1i?fNMAKstBOmHz%@EY3?>Zh1}oZU2%ubdpa8yHT8l?gu_QWj{UHbE zEQ33ep2FFOSW?UCIK>b#bOtpNQ7w}|?f#4w--!nLayh3l>tqB6wk4VFizKy3HX9kz z@N3Qv372^X4oqm;x}H|8ePx@b2@NAOgu9Lq;oQ)G5$OXrvNn%P3G=3BGa{Ty8+v$4 zYA~EZX7#KwO=J9K=~?kl?6;EDNt0EQ>)BcM0c| zE&->~;S`B$gZ_7{5sb(6DFi`<%yo)|IMPZGue-!?-KvLBfXv@CLR%QFUmHMNyNKgD zSA?)1vMj{1@EXfCia4%Mov6fXk!+WC(l!v+G|F7pHUZZJ+1)Nw@eJq-AmX?#9tMur z3mK1Npq>X2*8<`?dK5UWuf*L8lDL;4v#)H&x)xz@DrKh-$MOm@mIF8pk>!xCjqwExk`!RHh;~KbE zwa=T~h&%4WjR7|X+^<>DDKg$~pa((hx^;#QZ{SHEp_EC#166{E|o9%b*J!d^0 z90~DIsnT3&=DX*+=ezgLxihnOcJ6$$x4$nQiz!KQwMCINmasKt_DXeb(k64AYKgMd z7u2olb6{$**}8<#pQ91cjqL9n*6E7Q;ecH4Vj!g?V)A%mL zuf7Ik*Wh#DEo|XL$FNYlYS_!=3WLgZ5!gYu z#u4jU>@g}F@fescl*oC~oXswwE9lG2{ro%M!|7I|Xr#zzbXoQ~s%HRsN>{ep8tI&r zF(hI(zz5IQ7Tcy`wHO=4NRk!c`4ZGcZ2?}c0V-$@@O-P&{+$7y+K5sVfhYn|1fmE; z5r`rXMIeem6oG{z;Eeyh&Y4*B-dd%cr>6aQ<-9Zgo4T`A*UH9sP*hoU5&MP}HgaTV zsQl7}3eu{#$)+jorSsbUBiV7Xr?ve%vT162X;RxSlTB0FOQ&J4dv8bijYpjFJI?sU zD|`0!uA5%>nse^lNF$oMX*XQ|Ih1Tz@g&?$`)7k@k5bPMVB+g+roDgT^W;T`aorRV zl?y{B&kh9zwt7+fAAes%`HJ(>`&*rtW^0_-tIiu&{l;nyi@Aoder)qpE#=(RtOfp}nenTY3WlnaYHXnzr|K-* z_|6xj60>Ygew`yUWZQ(LOUUx|pFoccU^G4le9ljwO1^}NkN*IUYd zYqL|{*IGA4k6JTt!ow-Q?4ZLfPB~$4LLmapbCv_M&MEJ~*-LIHR^zj=BaPZTXY1#> zOFu?+QtnLH@D=|#p_MAEM5A1N00L!2vo( zL~wvIL<9%uAtHhU)JH_@r1S=%c#cP@4YvY)kC=B?z;Q$=ia->BC<0Lgq6kD0h$0Y0 zAc{Z~f&aS*$osIa;R9Z&#&y_P2X$bja)IUifOM@$O8@+a-)70+4NwhkS?hs zc%P?+v$-5`cn{iS>tnx}@eamL#vP1)CT&?Nd%zl}hCl?4JS81Ah&?2%HAa0-HXpR1$cmdmY$D&vr=7 z22||Py()Gz5nF!4;<}Tu#fb!XT6-{nx^H8jg?-KYLGn$(m#bB+u-maszh9{g09AdW zufFB}hU<^ijj656?z?kCtFD&Xc^KQ<(8_x|;^_VA?*kmQJ%()>++LvSskh@h>+6XB zKDLj+zhHPP{)_s$7UUq#lK@VaJt zZlWaRA6=~!$UaeH6PPvIz)Y=8rd}IOc!taAl_I6b45;fF>G_A!O$MradIhJGZEJ`d zOC4pDXFPcpTgrT9k*#yWcd{-0re{4$SR|^Gw2ybA`gmr!|9D}nZHX%$&$NA!%US+E z16fxdZg3NiZy)1+#v#VTjA7lKOx%OTsWc|rw{5%EYTKU9`-OtFZe4OivfUc#Sk2jm zi|?)$hijj+DSox;!^#|Eay0&Ne4X$zpTGKgVEQ(U zrg*)Q>rcwQOS~8Xr2hmK;=h4_HlqGLTz@TV@cLJ`8}85fYt-{+@D{dk`Ui-{_)_JB z`cDJcs2U)$wM5#jM}HRT=SuJi)uJ+?dcH{h@g-_9Vd{aY(`(o_;d~fl{x;^fa6RF8 z-cR+wpBA7{+N<|U?Pfm9yxa$dm_HEWN5RwahU-60{&Ae8+#jx9Jx%_I|HFJ-a$ixY z^q`+E`N=`GhZe%m{ZFUdp0Doe+PPyJ*1O}20=L(3`}TJ2>~)=}^>=Zx+jk7UWk;v8ui+T`Y`vqouTR(<#sQlslBoXFstjk0Q8FnGm^s)rHdmfnJ@V15+hQBRO9sbqAAv`Y7^xc#_3}9;{?K z;|>+Q;k27cK`WL~nBzAJ$)jR#I6H_|3#bdbq;9}ehDfU9U}1O|A(ONAv!l81&V4)4 zQe*4Nxl{aoGqx&aQpHdlqEt&xi1Ob zgUrA1+b!+OeB}gBFr@$TjYhcrUC^7~DpRA(XU?#G+R%EwL&q+9nOE!wN3PPo%#ZZS zI`A?dLRP16{2l>Ia}m+Y{No}YXo7XpfAJGMgmRkOh%NJ*S=QUEr*B|_{byP|iVV4m zUglGs+@Oq~v>!hHCt2Uk70Uc9!vdMlk%?dHPsHz8aMUmApH6Z=<^z{`pA_?9iK)uS z1@#u|E!GcIJxxa9DR?TRm*1x`cK9iu2U3mb#Qs4@FTek-Jb{&YsQ8Ebf133YfBF4Y zmQhR^sO}~HLYzT{j$iaLPnxuh2fd>Srf~beL}5^`R@%mWrGZ%k)qS}AX_VAslQ7Bi zhJ5E2_7_|5b!ai`sOsf;q$LRwN&Jj8XAA!(3h3OC_GSJk-)+kGnR0%KPR8+1(9-dX zUcM*0vKAzg_!;Yy?f(S@LA|nV`!e4)5kD~WA|#2=(kiElM#Io<=hLpo|X!^WAr;i_j&1$+&}61kiO5;Z!p#= XX^0C$Cgy4j>pM0YK}|>yGSz> 0x10); + } while (*(char *)((int16_t)in_stack_00000008 + var_6h + -1) != '\n'); + *(undefined *)((int16_t)in_stack_00000008 + var_6h + -1) = 0; + return in_stack_00000008; } EOF CMDS=<morning = pMVar1; + bright->morning->saved_argc = argc; + bright->morning->saved_argv = argv; + if (bright->morning->saved_argc < 2) { + bright->ambassador = AMBASSADOR_PURE; + } else { + (bright->window).sunlight = bright->morning->saved_argv[1]; + in_stack_ffffffe8 = "the "; + iVar2 = sym.imp.strcmp((bright->window).sunlight, "the "); + if (iVar2 == 0) { + bright->ambassador = AMBASSADOR_REASON; + } else { + in_stack_ffffffe8 = "dark"; + iVar2 = sym.imp.strcmp((bright->window).sunlight, "dark"); + if (iVar2 == 0) { + bright->ambassador = AMBASSADOR_REVOLUTION; + } else { + in_stack_ffffffe8 = "third"; + iVar2 = sym.imp.strcmp((bright->window).sunlight, "third"); + if (iVar2 == 0) { + bright->ambassador = AMBASSADOR_ECHOES; + } else { + bright->ambassador = AMBASSADOR_MILLION; + } + } + } + } + // switch table (5 cases) at 0x804a070 + switch(bright->ambassador) { + case AMBASSADOR_PURE: + sym.imp.printf("pure"); + break; + case AMBASSADOR_REASON: + sym.imp.printf("reason"); + break; + case AMBASSADOR_REVOLUTION: + sym.imp.printf("revolution"); + break; + case AMBASSADOR_ECHOES: + sym.imp.printf("echoes"); + break; + case AMBASSADOR_WALL: + sym.imp.printf("wall"); + break; + default: + if (bright->ambassador == AMBASSADOR_MILLION) { + sym.imp.printf("million"); + } + break; + case 0xbad1abe1: + break; + } + sym.PrintAmbassador(bright->ambassador, in_stack_ffffffe8, in_stack_ffffffec, in_stack_fffffff0, in_stack_fffffff4); + return; +} +EOF +CMDS=<morning = pMVar2; @@ -1902,7 +1987,7 @@ EOF CMDS=<morning = pMVar2; + bright->morning->saved_argc = argc; + *(char ***)((int64_t)&bright->morning->saved_argv + 4) = argv; + if (bright->morning->saved_argc < 2) { + *(undefined4 *)&bright->ambassador = 0; + } else { + (bright->window).sunlight = *(char **)(*(int64_t *)((int64_t)&bright->morning->saved_argv + 4) + 8); + iVar1 = sym.imp.strcmp((bright->window).sunlight, "the "); + if (iVar1 == 0) { + *(undefined4 *)&bright->ambassador = 1; + } else { + iVar1 = sym.imp.strcmp((bright->window).sunlight, "dark"); + if (iVar1 == 0) { + *(undefined4 *)&bright->ambassador = 2; + } else { + iVar1 = sym.imp.strcmp((bright->window).sunlight, "third"); + if (iVar1 == 0) { + *(undefined4 *)&bright->ambassador = 3; + } else { + *(undefined4 *)&bright->ambassador = 1000000; + } + } + } + } + // switch table (5 cases) at 0x402088 + switch(*(int32_t *)&bright->ambassador) { + case 0: + sym.imp.printf("pure"); + break; + case 1: + sym.imp.printf("reason"); + break; + case 2: + sym.imp.printf("revolution"); + break; + case 3: + sym.imp.printf("echoes"); + break; + case 4: + sym.imp.printf("wall"); + break; + default: + if (*(int32_t *)&bright->ambassador == 1000000) { + sym.imp.printf("million"); + } + break; + case -0x452e541f: + break; + } + sym.PrintAmbassador((uint64_t)*(uint32_t *)&bright->ambassador); + return; +} +EOF +CMDS=< + + + @@ -2305,6 +2488,10 @@ CCu base64:Jg== @ 0x804858a + + + + @@ -2336,11 +2523,11 @@ CCu base64:Jg== @ 0x804858a - + - + @@ -2464,24 +2651,26 @@ CCu base64:Jg== @ 0x804858a undefined4 main(void) { - int32_t var_78h; + int32_t var_88h; + int32_t var_7ch; sym.imp.printf("IOLI Crackme Level 0x05\n"); sym.imp.printf("Password: "); - sym.imp.scanf(0x80486b2, &var_78h); - sym.check((int32_t)&var_78h); + sym.imp.scanf(0x80486b2, &var_7ch); + sym.check((int32_t)&var_7ch); return 0; } -- |  0x08048540 |undefined4 main(void) |{ - | int32_t var_78h; + | int32_t var_88h; + | int32_t var_7ch; | 0x08048566 | sym.imp.printf("IOLI Crackme Level 0x05\n"); 0x08048572 | sym.imp.printf("Password: "); - 0x08048585 | sym.imp.scanf(0x80486b2, &var_78h); - 0x0804858a | sym.check((int32_t)&var_78h); + 0x08048585 | sym.imp.scanf(0x80486b2, &var_7ch); + 0x0804858a | sym.check((int32_t)&var_7ch); 0x0804859b | return 0; |} EOF @@ -2511,17 +2700,17 @@ FILE=rizin-testbins/elf/hello_world ARGS=-B 0x1000000000000000 EXPECT=< Date: Fri, 6 Jan 2023 09:22:59 +0800 Subject: [PATCH 11/18] Make Travis CI System Z job mandatory (#308) --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 260e0425..36449b21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,11 +23,6 @@ jobs: name: ARM64 arch: arm64 dist: focal - allow_failures: - - os: linux - name: S390X - arch: s390x - dist: focal addons: apt: From 39f56408f8e93fd13db20fa42643ba913ce57e32 Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Fri, 6 Jan 2023 17:13:48 +0800 Subject: [PATCH 12/18] Set pdg as child of pd instead of the root dir (#309) --- src/core_ghidra.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_ghidra.cpp b/src/core_ghidra.cpp index 6939b997..b8a90c4d 100644 --- a/src/core_ghidra.cpp +++ b/src/core_ghidra.cpp @@ -671,7 +671,7 @@ static bool rz_ghidra_init(RzCore *core) rz_config_lock (cfg, true); auto rzcmd = core->rcmd; - RzCmdDesc *root_cd = rz_cmd_desc_group_new(rzcmd, rz_cmd_get_root(rzcmd), "pdg", pdg_handler, &pdg_help, &root_help); + RzCmdDesc *root_cd = rz_cmd_desc_group_new(rzcmd, rz_cmd_get_desc(rzcmd, "pd"), "pdg", pdg_handler, &pdg_help, &root_help); rz_cmd_desc_argv_new(rzcmd, root_cd, "pdgd", pdgd_handler, &pdgd_help); rz_cmd_desc_argv_new(rzcmd, root_cd, "pdgx", pdgx_handler, &pdgx_help); rz_cmd_desc_argv_new(rzcmd, root_cd, "pdgj", pdgj_handler, &pdgj_help); From 6862d337d8709f775d57f72482eedad7f616ef68 Mon Sep 17 00:00:00 2001 From: Riccardo Schirone Date: Wed, 11 Jan 2023 18:36:28 +0100 Subject: [PATCH 13/18] Deregister the 'pdg' command when unloading the rizin plugin --- src/core_ghidra.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core_ghidra.cpp b/src/core_ghidra.cpp index b8a90c4d..baf5d847 100644 --- a/src/core_ghidra.cpp +++ b/src/core_ghidra.cpp @@ -689,6 +689,10 @@ static bool rz_ghidra_fini(RzCore *core) { std::lock_guard lock(decompiler_mutex); shutdownDecompilerLibrary(); + + auto rzcmd = core->rcmd; + RzCmdDesc *pdg_cd = rz_cmd_get_desc(rzcmd, "pdg"); + rz_cmd_desc_remove(rzcmd, pdg_cd); return true; } From 9f8dd1128b77ea1d4b4bb18eb84db3b04cf36e81 Mon Sep 17 00:00:00 2001 From: Riccardo Schirone <562321+ret2libc@users.noreply.github.com> Date: Mon, 16 Jan 2023 15:19:31 +0100 Subject: [PATCH 14/18] Remove plugin.pkgname because not used anymore (#311) --- src/analysis_ghidra.cpp | 1 - src/asm_ghidra.cpp | 1 - src/core_ghidra.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/src/analysis_ghidra.cpp b/src/analysis_ghidra.cpp index a838202d..000e91fd 100644 --- a/src/analysis_ghidra.cpp +++ b/src/analysis_ghidra.cpp @@ -3306,7 +3306,6 @@ RZ_API RzLibStruct rizin_plugin = { /* .data = */ &rz_analysis_plugin_ghidra, /* .version = */ RZ_VERSION, /* .free = */ nullptr, - /* .pkgname = */ "rz-ghidra" }; } #endif diff --git a/src/asm_ghidra.cpp b/src/asm_ghidra.cpp index 5f146ceb..a1aad321 100644 --- a/src/asm_ghidra.cpp +++ b/src/asm_ghidra.cpp @@ -70,7 +70,6 @@ RZ_API RzLibStruct rizin_plugin = { /* .data = */ &rz_asm_plugin_ghidra, /* .version = */ RZ_VERSION, /* .free = */ nullptr, - /* .pkgname = */ "rz-ghidra" }; } #endif diff --git a/src/core_ghidra.cpp b/src/core_ghidra.cpp index baf5d847..cc653578 100644 --- a/src/core_ghidra.cpp +++ b/src/core_ghidra.cpp @@ -713,7 +713,6 @@ RZ_API RzLibStruct rizin_plugin = { /* .data = */ &rz_core_plugin_ghidra, /* .version = */ RZ_VERSION, /* .free = */ nullptr, - /* .pkgname = */ "rz-ghidra" }; } #endif From d371317f27aa9b603213bf49ba4310292337066c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Fri, 20 Jan 2023 11:48:19 +0100 Subject: [PATCH 15/18] Register functions from reloc targets Rizin shows calls to reloc targets as their function names in disassembly. We do the same in the decompiler. Addresses #312 --- src/RizinScope.cpp | 16 ++++++++++++++++ src/RizinScope.h | 2 ++ test/db/extras/ghidra | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index 83c83218..4be88f2f 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -410,6 +410,14 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const return dynamic_cast(sym); } +FunctionSymbol *RizinScope::registerRelocTarget(RzBinReloc *reloc) const +{ + RzCoreLock core(arch->getCore()); + if(!reloc->import || !reloc->import->name) + return nullptr; + return cache->addFunction(Address(arch->getDefaultCodeSpace(), reloc->target_vaddr), reloc->import->name); +} + Symbol *RizinScope::registerFlag(RzFlagItem *flag) const { RzCoreLock core(arch->getCore()); @@ -516,6 +524,14 @@ Symbol *RizinScope::queryRizinAbsolute(ut64 addr, bool contain) const if(glob) return registerGlobalVar(glob); + RzBinReloc *reloc = rz_core_get_reloc_to(core, addr); + if(reloc && reloc->import) + { + auto rsym = registerRelocTarget(reloc); + if(rsym) + return rsym; + } + // TODO: register more things // TODO: correctly handle contain for flags diff --git a/src/RizinScope.h b/src/RizinScope.h index 9417cf2c..c3ef33b7 100644 --- a/src/RizinScope.h +++ b/src/RizinScope.h @@ -19,6 +19,7 @@ class RizinArchitecture; typedef struct rz_analysis_function_t RzAnalysisFunction; typedef struct rz_flag_item_t RzFlagItem; typedef struct rz_analysis_var_global_t RzAnalysisVarGlobal; +typedef struct rz_bin_reloc_t RzBinReloc; class RizinScope : public Scope { @@ -30,6 +31,7 @@ class RizinScope : public Scope uint8 makeId() const { return (*next_id)++; } FunctionSymbol *registerFunction(RzAnalysisFunction *fcn) const; + FunctionSymbol *registerRelocTarget(RzBinReloc *reloc) const; Symbol *registerFlag(RzFlagItem *flag) const; Symbol *registerGlobalVar(RzAnalysisVarGlobal *glob) const; Symbol *queryRizinAbsolute(ut64 addr, bool contain) const; diff --git a/test/db/extras/ghidra b/test/db/extras/ghidra index d530ab4a..f2e04cae 100644 --- a/test/db/extras/ghidra +++ b/test/db/extras/ghidra @@ -3262,3 +3262,22 @@ undefined8 entry0(int64_t arg1, int64_t arg2) } EOF RUN + +NAME=reloc target functions +FILE=rizin-testbins/elf/linux-example-x86-32.ko +CMDS=< Date: Fri, 20 Jan 2023 12:30:28 +0100 Subject: [PATCH 16/18] Fallback to RzBinString length if flag size is invalid --- src/RizinScope.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index 4be88f2f..d12062f3 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -450,10 +450,16 @@ Symbol *RizinScope::registerFlag(RzFlagItem *flag) const case RZ_STRING_ENC_UTF32BE: tn = "char32_t"; break; + default: + break; } } ptype = arch->types->findByName(tn); int4 sz = static_cast(flag->size) / ptype->getSize(); + if(!sz && str) // Zero string length is an error + sz = str->length; + if(!sz) + sz = 1; // The decompiler will figure out the length to display type = arch->types->getTypeArray(sz, ptype); attr |= Varnode::readonly; } From 4bb1894b8881c1646deb5c630f692748198f84a8 Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 7 Feb 2023 04:00:44 +0800 Subject: [PATCH 17/18] Various upgrades in GHA and builds.sr.ht (#315) --- .builds/freebsd.yml | 1 + .builds/openbsd.yml | 1 + .github/workflows/ci.yml | 10 +++++----- .github/workflows/codeql-analysis.yml | 14 +++++++------- .github/workflows/coverity-scan.yml | 10 +++++----- .github/workflows/dist.yml | 8 ++++---- .github/workflows/linter.yml | 6 +++--- .travis.yml | 8 ++++---- 8 files changed, 30 insertions(+), 28 deletions(-) diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml index 67989f50..1da1008e 100644 --- a/.builds/freebsd.yml +++ b/.builds/freebsd.yml @@ -16,6 +16,7 @@ sources: - https://github.com/rizinorg/rizin - https://github.com/rizinorg/rz-ghidra - https://github.com/rizinorg/rizin-testbins +hottub_trigger: '.*' tasks: - rizinbuild: | cd rizin diff --git a/.builds/openbsd.yml b/.builds/openbsd.yml index 6f3142e1..2665ed2f 100644 --- a/.builds/openbsd.yml +++ b/.builds/openbsd.yml @@ -14,6 +14,7 @@ sources: - https://github.com/rizinorg/rizin - https://github.com/rizinorg/rz-ghidra - https://github.com/rizinorg/rizin-testbins +hottub_trigger: '.*' tasks: - rizinbuild: | cd rizin diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc12d6fe..57a3c9ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: name: ${{ matrix.name }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Checkout submodules run: | git submodule init @@ -40,10 +40,10 @@ jobs: windows: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v4 - name: Preparing msvc toolchain uses: ilammy/msvc-dev-cmd@v1 with: @@ -52,13 +52,13 @@ jobs: run: | python -m pip install --upgrade pip pip install meson ninja PyYAML - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: repository: rizinorg/rizin path: rizin - name: Extract rizin version shell: pwsh - run: echo "##[set-output name=branch;]$( python sys\\version.py )" + run: echo "branch=$(python sys/version.py)" >> $Env:GITHUB_OUTPUT id: extract_version working-directory: rizin - name: Build with meson + ninja diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f6951851..08bb1c43 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -11,7 +11,7 @@ on: jobs: analyze: name: Analyze - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. @@ -30,14 +30,14 @@ jobs: git submodule init git submodule update - - uses: actions/setup-python@v1 + - uses: actions/setup-python@v4 with: - python-version: 3.8.x + python-version: 3.10.x - name: apt dependencies run: | sudo apt-get --assume-yes update - sudo apt-get --assume-yes install ninja-build libgraphviz-dev bison flex qt5-default + sudo apt-get --assume-yes install ninja-build libgraphviz-dev bison flex qtbase5-dev cmake - name: py dependencies run: | @@ -53,7 +53,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} @@ -64,4 +64,4 @@ jobs: make - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index abe1eeb3..baae3c4c 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -5,14 +5,14 @@ on: jobs: latest: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 with: submodules: true - - uses: actions/setup-python@v1 + - uses: actions/setup-python@v4 with: - python-version: 3.7.x + python-version: 3.10.x - name: Download Coverity Build Tool run: | @@ -28,7 +28,7 @@ jobs: sudo chmod -R go-w /usr/share - name: apt dependencies - run: sudo apt-get install ninja-build libgraphviz-dev bison flex qt5-default + run: sudo apt-get install ninja-build libgraphviz-dev bison flex qtbase5-dev qt5-qmake cmake - name: py dependencies run: | diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index a4c934cf..8be00b39 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -9,7 +9,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/deploy-test-') || startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Checkout submodules run: | git submodule init @@ -35,10 +35,10 @@ jobs: tarball ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Extract version id: extract_version - run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//} + run: echo "version=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT - name: Create Release id: create_release uses: actions/create-release@v1 @@ -49,7 +49,7 @@ jobs: release_name: Release ${{ steps.extract_version.outputs.version }} draft: true prerelease: false - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 - name: Display structure of downloaded files run: ls -R - name: Upload rz-ghidra src tarball diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index da2702a4..72766e20 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -6,9 +6,9 @@ on: jobs: licenses: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: REUSE Compliance Check - uses: fsfe/reuse-action@v1.1 + uses: fsfe/reuse-action@v1 diff --git a/.travis.yml b/.travis.yml index 36449b21..a49c9d81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,19 +10,19 @@ jobs: include: - os: linux name: X86_64 - dist: focal + dist: jammy - os: linux name: S390X arch: s390x - dist: focal + dist: jammy - os: linux name: PPC64 arch: ppc64le - dist: focal + dist: jammy - os: linux name: ARM64 arch: arm64 - dist: focal + dist: jammy addons: apt: From 30cd6b0c45b3c325e8b9700c9f888c6468131f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 12 Feb 2023 12:56:33 +0100 Subject: [PATCH 18/18] Update Ghidra --- CMakeLists.txt | 5 +- ghidra/CMakeLists.txt | 2 + ghidra/ghidra | 2 +- src/CodeXMLParse.cpp | 57 ++- src/PrettyXmlEncode.cpp | 37 ++ src/PrettyXmlEncode.h | 21 + src/RizinArchitecture.cpp | 2 +- src/RizinCommentDatabase.h | 4 +- src/RizinScope.cpp | 16 +- src/RizinScope.h | 4 +- src/RizinTypeFactory.cpp | 8 +- src/SleighAsm.cpp | 88 ++-- src/SleighInstruction.cpp | 9 +- src/SleighInstruction.h | 2 +- src/analysis_ghidra.cpp | 10 +- src/asm_ghidra.cpp | 10 +- src/core_ghidra.cpp | 35 +- src/rz_ghidra_internal.h | 11 + test/db/extras/analysis_ghidra | 6 +- test/db/extras/asm_ghidra | 32 +- test/db/extras/ghidra | 715 ++++++++++++++++++--------------- 21 files changed, 649 insertions(+), 427 deletions(-) create mode 100644 src/PrettyXmlEncode.cpp create mode 100644 src/PrettyXmlEncode.h create mode 100644 src/rz_ghidra_internal.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b9d154a..fa6558fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,10 @@ set(CORE_SOURCE src/RizinPrintC.cpp src/RzCoreMutex.h src/RzCoreMutex.cpp - src/rz_ghidra.h) + src/PrettyXmlEncode.h + src/PrettyXmlEncode.cpp + src/rz_ghidra.h + src/rz_ghidra_internal.h) if(BUILD_SLEIGH_PLUGIN) set(ASM_SOURCE diff --git a/ghidra/CMakeLists.txt b/ghidra/CMakeLists.txt index a24cd57f..eef7a2a1 100644 --- a/ghidra/CMakeLists.txt +++ b/ghidra/CMakeLists.txt @@ -5,6 +5,7 @@ # Base of everything set(SOURCE_BASE_CXX # xml.cc // generated by yacc task + marshal.cc space.cc float.cc address.cc @@ -46,6 +47,7 @@ set(SOURCE_DECOMPILER_CXX funcdata.cc funcdata_block.cc funcdata_varnode.cc + unionresolve.cc funcdata_op.cc pcodeinject.cc heritage.cc diff --git a/ghidra/ghidra b/ghidra/ghidra index d8790574..d89dd09b 160000 --- a/ghidra/ghidra +++ b/ghidra/ghidra @@ -1 +1 @@ -Subproject commit d87905747fe38d2dcd7492ed2e83bbf438b156d3 +Subproject commit d89dd09b18645ba62fc202f962fdb73fb60145a7 diff --git a/src/CodeXMLParse.cpp b/src/CodeXMLParse.cpp index fa9a8539..3623c84f 100644 --- a/src/CodeXMLParse.cpp +++ b/src/CodeXMLParse.cpp @@ -139,32 +139,47 @@ void AnnotateCommentOffset(ANNOTATOR_PARAMS) void AnnotateColor(ANNOTATOR_PARAMS) { pugi::xml_attribute attr = node.attribute("color"); - if (attr.empty()) + if(attr.empty()) return; - std::string color = attr.as_string(); - if (color == "") + int color = attr.as_int(-1); + if(color < 0) return; RSyntaxHighlightType type; - if (color == "keyword") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD; - else if (color == "comment") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT; - else if (color == "type") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE; - else if (color == "funcname") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME; - else if (color == "param") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER; - else if (color == "var") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE; - else if (color == "const") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE; - else if (color == "global") - type = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE; - else - return; + switch(color) + { + case Emit::syntax_highlight::keyword_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD; + break; + case Emit::syntax_highlight::comment_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT; + break; + case Emit::syntax_highlight::type_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE; + break; + case Emit::syntax_highlight::funcname_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME; + break; + case Emit::syntax_highlight::var_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE; + break; + case Emit::syntax_highlight::const_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE; + break; + case Emit::syntax_highlight::param_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER; + break; + case Emit::syntax_highlight::global_color: + type = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE; + break; + case Emit::syntax_highlight::no_color: + case Emit::syntax_highlight::error_color: + case Emit::syntax_highlight::special_color: + default: + return; + } + RzCodeAnnotation annotation = {}; annotation.type = RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT; annotation.syntax_highlight.type = type; diff --git a/src/PrettyXmlEncode.cpp b/src/PrettyXmlEncode.cpp new file mode 100644 index 00000000..a1fdb777 --- /dev/null +++ b/src/PrettyXmlEncode.cpp @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2023 Florian Märkl +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "PrettyXmlEncode.h" + +void PrettyXmlEncode::indent() +{ + for(int i = 0; i < depth; i++) + outStream << " "; +} + +void PrettyXmlEncode::openElement(const ElementId &elemId) +{ + if(elementTagIsOpen) + outStream << ">\n"; + else + elementTagIsOpen = true; + indent(); + depth++; + outStream << '<' << elemId.getName(); +} + +void PrettyXmlEncode::closeElement(const ElementId &elemId) +{ + depth--; + if(elementTagIsOpen) + { + outStream << "/>\n"; + elementTagIsOpen = false; + } + else + { + indent(); + outStream << "\n"; + } +} + diff --git a/src/PrettyXmlEncode.h b/src/PrettyXmlEncode.h new file mode 100644 index 00000000..a0d90535 --- /dev/null +++ b/src/PrettyXmlEncode.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2023 Florian Märkl +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef PRETTY_XML_ENCODE_H +#define PRETTY_XML_ENCODE_H + +#include + +class PrettyXmlEncode: public XmlEncode +{ + private: + int depth = 0; + void indent(); + + public: + PrettyXmlEncode(std::ostream &s) : XmlEncode(s) {} + void openElement(const ElementId &elemId) override; + void closeElement(const ElementId &elemId) override; +}; + +#endif diff --git a/src/RizinArchitecture.cpp b/src/RizinArchitecture.cpp index c4f96b0e..883604f1 100644 --- a/src/RizinArchitecture.cpp +++ b/src/RizinArchitecture.cpp @@ -37,7 +37,7 @@ std::string FilenameFromCore(RzCore *core) } RizinArchitecture::RizinArchitecture(RzCore *core, const std::string &sleigh_id) - : SleighArchitecture(FilenameFromCore(core), sleigh_id.empty() ? SleighIdFromCore(core) : sleigh_id, &cout), + : SleighArchitecture(FilenameFromCore(core), sleigh_id.empty() ? SleighIdFromCore(core) : sleigh_id, &std::cout), coreMutex(core) { } diff --git a/src/RizinCommentDatabase.h b/src/RizinCommentDatabase.h index 7d00ea95..e2bd6254 100644 --- a/src/RizinCommentDatabase.h +++ b/src/RizinCommentDatabase.h @@ -29,8 +29,8 @@ class RizinCommentDatabase : public CommentDatabase CommentSet::const_iterator beginComment(const Address &fad) const override; CommentSet::const_iterator endComment(const Address &fad) const override; - void saveXml(ostream &s) const override { cache.saveXml(s); } - void restoreXml(const Element *el, const AddrSpaceManager *trans) override { throw LowlevelError("commentdb::restoreXml unimplemented"); } + void encode(Encoder &encoder) const override { cache.encode(encoder); } + void decode(Decoder &decoder) override { throw LowlevelError("CommentDatabaseGhidra::decode unimplemented"); } }; #endif //RZ_GHIDRA_RizinCOMMENTDATABASE_H diff --git a/src/RizinScope.cpp b/src/RizinScope.cpp index d12062f3..695e1dda 100644 --- a/src/RizinScope.cpp +++ b/src/RizinScope.cpp @@ -225,6 +225,7 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const params.registerTrial(addr, type->getSize()); int4 i = params.whichTrial(addr, type->getSize()); params.getTrial(i).markActive(); + params.getTrial(i).markUsed(); return true; }); @@ -298,12 +299,20 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const return true; } - paramIndex = params.whichTrial(addr, type->getSize()); - if(paramIndex < 0) + int4 paramTrialIndex = params.whichTrial(addr, type->getSize()); + if(paramTrialIndex < 0) { arch->addWarning("Failed to determine arg index of " + to_string(var->name)); return true; } + + paramIndex = 0; + for(int4 i = 0; i < paramTrialIndex; i++) + { + if(!params.getTrial(i).isUsed()) + continue; + paramIndex++; + } } varRanges.insertRange(addr.getSpace(), addr.getOffset(), last); @@ -406,7 +415,8 @@ FunctionSymbol *RizinScope::registerFunction(RzAnalysisFunction *fcn) const child(&doc, "rangelist"); - auto sym = cache->addMapSym(&doc); + XmlDecode dec(arch, &doc); + auto sym = cache->addMapSym(dec); return dynamic_cast(sym); } diff --git a/src/RizinScope.h b/src/RizinScope.h index c3ef33b7..b9173a8e 100644 --- a/src/RizinScope.h +++ b/src/RizinScope.h @@ -87,8 +87,8 @@ class RizinScope : public Scope void renameSymbol(Symbol *sym,const string &newname) override { throw LowlevelError("renameSymbol unimplemented"); } void retypeSymbol(Symbol *sym,Datatype *ct) override { throw LowlevelError("retypeSymbol unimplemented"); } string makeNameUnique(const string &nm) const override { throw LowlevelError("makeNameUnique unimplemented"); } - void saveXml(ostream &s) const override { cache->saveXml(s); } - void restoreXml(const Element *el) override { throw LowlevelError("restoreXml unimplemented"); } + void encode(Encoder &encoder) const override { cache->encode(encoder); } + void decode(Decoder &decoder) override { throw LowlevelError("decode unimplemented"); } void printEntries(ostream &s) const override { throw LowlevelError("printEntries unimplemented"); } int4 getCategorySize(int4 cat) const override { throw LowlevelError("getCategorySize unimplemented"); } Symbol *getCategorySymbol(int4 cat,int4 ind) const override { throw LowlevelError("getCategorySymbol unimplemented"); } diff --git a/src/RizinTypeFactory.cpp b/src/RizinTypeFactory.cpp index a7efde6b..cf07587e 100644 --- a/src/RizinTypeFactory.cpp +++ b/src/RizinTypeFactory.cpp @@ -53,11 +53,13 @@ Datatype *RizinTypeFactory::addRizinStruct(RzBaseType *type, StackTypes &stack_t // if(elements > 0) // memberType = getTypeArray(elements, memberType); - fields.push_back({ + TypeField tf = { + (int4)offset, // id = offset by default (int4)offset, // Currently, this is 0 most of the time: member->offset, std::string(member->name), member_type - }); + }; + fields.push_back(tf); // TODO: right now, we track member offset ourselves // which means all structs are assumed to be packed. @@ -110,7 +112,7 @@ Datatype *RizinTypeFactory::addRizinTypedef(RzBaseType *type, StackTypes &stack_ Datatype *resolved = fromRzTypeInternal(type->type, nullptr, &stack_types, true, false); // use prototype=true to avoid recursion if(!resolved) return nullptr; - Datatype *typedefd = getTypedef(resolved, type->name, 0); + Datatype *typedefd = getTypedef(resolved, type->name, 0, 0); fromRzTypeInternal(type->type, nullptr, &stack_types, false, false); // fully create the type after querying with prototype=true before return typedefd; } diff --git a/src/SleighAsm.cpp b/src/SleighAsm.cpp index 88017a53..74176d23 100644 --- a/src/SleighAsm.cpp +++ b/src/SleighAsm.cpp @@ -57,7 +57,7 @@ void SleighAsm::initInner(std::string sleigh_id) } static void parseProto(const Element *el, std::vector &arg_names, - std::vector &ret_names) + std::vector &ret_names) { if(el->getName() != "prototype") throw LowlevelError("Expecting tag"); @@ -103,7 +103,7 @@ static void parseProto(const Element *el, std::vector &arg_names, } static void parseDefaultProto(const Element *el, std::vector &arg_names, - std::vector &ret_names) + std::vector &ret_names) { const List &list(el->getChildren()); List::const_iterator iter; @@ -157,7 +157,7 @@ static std::unordered_map parseRegisterData(const Elem unused = (*iter)->getAttributeValue("unused"); rename = (*iter)->getAttributeValue("rename"); } - catch(const XmlError &e) + catch(const DecoderError &e) { std::string err_prefix("Unknown attribute: "); if(e.explain == err_prefix + "group") { /* nothing */ } @@ -181,26 +181,39 @@ static std::unordered_map parseRegisterData(const Elem * Context data is used to fill contextreg. */ void SleighAsm::parseProcConfig(DocumentStorage &store) + { const Element *el = store.getTag("processor_spec"); if(!el) throw LowlevelError("No processor configuration tag found"); - - const List &list(el->getChildren()); - List::const_iterator iter; - - for(iter = list.begin(); iter != list.end(); iter++) + XmlDecode decoder(&trans, el); + uint4 elemId = decoder.openElement(ELEM_PROCESSOR_SPEC); + for(;;) { - const string &elname((*iter)->getName()); - if(elname == "context_data") - context.restoreFromSpec(*iter, &trans); - - if(elname == "programcounter") - pc_name = (*iter)->getAttributeValue("register"); - - if(elname == "register_data") - reg_group = parseRegisterData(*iter); + uint4 subId = decoder.peekElement(); + if(subId == 0) + break; + if (subId == ELEM_PROGRAMCOUNTER) + { + decoder.openElement(); + pc_name = decoder.readString(ATTRIB_REGISTER); + decoder.closeElement(subId); + } + else if (subId == ELEM_CONTEXT_DATA) + context.decodeFromSpec(decoder); + else if (subId == ELEM_REGISTER_DATA) + { + decoder.openElement(); + parseRegisterData(decoder.getCurrentXmlElement()); + decoder.closeElement(subId); + } + else + { + decoder.openElement(); + decoder.closeElementSkipping(subId); + } } + decoder.closeElement(elemId); } /* @@ -226,7 +239,7 @@ void SleighAsm::buildSpecfile(DocumentStorage &store) Document *doc = store.openDocument(processorfile); store.registerTag(doc->getRoot()); } - catch(XmlError &err) + catch(DecoderError &err) { ostringstream serr; serr << "XML error parsing processor specification: " << processorfile; @@ -246,7 +259,7 @@ void SleighAsm::buildSpecfile(DocumentStorage &store) Document *doc = store.openDocument(compilerfile); store.registerTag(doc->getRoot()); } - catch(XmlError &err) + catch(DecoderError &err) { ostringstream serr; serr << "XML error parsing compiler specification: " << compilerfile; @@ -266,7 +279,7 @@ void SleighAsm::buildSpecfile(DocumentStorage &store) Document *doc = store.openDocument(slafile); store.registerTag(doc->getRoot()); } - catch(XmlError &err) + catch(DecoderError &err) { ostringstream serr; serr << "XML error parsing SLEIGH file: " << slafile; @@ -284,7 +297,7 @@ void SleighAsm::buildSpecfile(DocumentStorage &store) /* * From sleigh_arch.cc's resolveArchitecture() - * This function is used to reolve the index of asm.cpu in description. + * This function is used to resolve the index of asm.cpu in description. * It is stripped because asm.cpu is the result of normalizeArchitecture(). */ void SleighAsm::resolveArch(const string &archid) @@ -366,28 +379,33 @@ void SleighAsm::loadLanguageDescription(const string &specfile) if(!s) throw LowlevelError("Unable to open: " + specfile); - Document *doc; - Element *el; + XmlDecode decoder((const AddrSpaceManager *)0); try { - doc = xml_tree(s); + decoder.ingestStream(s); } - catch(XmlError &err) + catch(DecoderError &err) { throw LowlevelError("Unable to parse sleigh specfile: " + specfile); } - el = doc->getRoot(); - const List &list(el->getChildren()); - List::const_iterator iter; - for(iter = list.begin(); iter != list.end(); ++iter) - { - if((*iter)->getName() != "language") - continue; - description.push_back(LanguageDescription()); - description.back().restoreXml(*iter); + uint4 elemId = decoder.openElement(ELEM_LANGUAGE_DEFINITIONS); + for(;;) { + uint4 subId = decoder.peekElement(); + if(subId == 0) + break; + if(subId == ELEM_LANGUAGE) + { + description.emplace_back(); + description.back().decode(decoder); + } + else + { + decoder.openElement(); + decoder.closeElementSkipping(subId); + } } - delete doc; + decoder.closeElement(elemId); } /* diff --git a/src/SleighInstruction.cpp b/src/SleighInstruction.cpp index c92a163c..f5146f40 100644 --- a/src/SleighInstruction.cpp +++ b/src/SleighInstruction.cpp @@ -93,7 +93,7 @@ SleighParserContext *RizinSleigh::getParserContext(Address &addr, SleighInstruct SleighParserContext *RizinSleigh::newSleighParserContext(Address &addr, SleighInstructionPrototype *proto) { - SleighParserContext *pos = new SleighParserContext(getContextCache()); + SleighParserContext *pos = new SleighParserContext(getContextCache(), this); pos->initialize(1, 0, getConstantSpace()); pos->setAddr(addr); pos->setPrototype(proto); @@ -235,9 +235,9 @@ FlowType SleighInstructionPrototype::convertFlowFlags(FlowFlags flags) { if((flags & FLOW_LABEL) != 0) flags = FlowFlags(flags | FLOW_BRANCH_TO_END); - flags = FlowFlags(flags & (~(FLOW_CROSSBUILD | FLOW_LABEL))); + int mask = FlowFlags(flags & (~(FLOW_CROSSBUILD | FLOW_LABEL))); // NOTE: If prototype has cross-build, flow must be determined dynamically - switch(flags) + switch(mask) { // Convert flags to a standard flowtype case 0: case FLOW_BRANCH_TO_END: return FlowType::FALL_THROUGH; @@ -546,9 +546,6 @@ Address SleighInstructionPrototype::getHandleAddr(FixedHandle &hand, AddrSpace * return Address(); Address newaddr(hand.space, hand.space->wrapOffset(hand.offset_offset)); - - newaddr.toPhysical(); - // if we are in an address space, translate it // if (curSpace.isOverlaySpace()) { // newaddr = curSpace.getOverlayAddress(newaddr); diff --git a/src/SleighInstruction.h b/src/SleighInstruction.h index 011d9f66..bd047f55 100644 --- a/src/SleighInstruction.h +++ b/src/SleighInstruction.h @@ -274,7 +274,7 @@ class SleighParserContext : public ParserContext SleighInstructionPrototype *prototype = nullptr; public: - SleighParserContext(ContextCache *ccache): ParserContext(ccache) {} + SleighParserContext(ContextCache *ccache, Translate *trans): ParserContext(ccache, trans) {} SleighInstructionPrototype *getPrototype() { return prototype; } void setPrototype(SleighInstructionPrototype *p); }; diff --git a/src/analysis_ghidra.cpp b/src/analysis_ghidra.cpp index 000e91fd..6adeec69 100644 --- a/src/analysis_ghidra.cpp +++ b/src/analysis_ghidra.cpp @@ -809,7 +809,7 @@ static void sleigh_esil(RzAnalysis *a, RzAnalysisOp *analysis_op, ut64 addr, con const std::vector &Pcodes) { std::vector esil_stack; - stringstream ss; + std::stringstream ss; auto print_if_unique = [&esil_stack, &ss](const PcodeOperand *arg, int offset = 0) -> bool { if(arg->is_unique()) @@ -1095,6 +1095,7 @@ static void sleigh_esil(RzAnalysis *a, RzAnalysisOp *analysis_op, ut64 addr, con case CPUI_INT_LESSEQUAL: ss << "<="; break; case CPUI_INT_NOTEQUAL: ss << "==,!"; break; case CPUI_INT_EQUAL: ss << "=="; break; + default: break; } if(iter->output->is_unique()) @@ -1154,6 +1155,7 @@ static void sleigh_esil(RzAnalysis *a, RzAnalysisOp *analysis_op, ut64 addr, con case CPUI_INT_SRIGHT: ss << iter->input0->size * 8 << ",SWAP,SIGN,>>"; break; + default: break; } ss << "," << iter->output->size * 8 << ",1,<<,1,SWAP,-,&"; @@ -1327,6 +1329,7 @@ static void sleigh_esil(RzAnalysis *a, RzAnalysisOp *analysis_op, ut64 addr, con case CPUI_FLOAT_ABS: ss << ",0,I2F,F<=,!,?{,-F,}"; break; case CPUI_FLOAT_NEG: ss << ",-F"; break; case CPUI_FLOAT_FLOAT2FLOAT: /* same as below */ break; + default: break; } switch(iter->type) { @@ -1340,6 +1343,7 @@ static void sleigh_esil(RzAnalysis *a, RzAnalysisOp *analysis_op, ut64 addr, con case CPUI_FLOAT_FLOAT2FLOAT: ss << "," << iter->output->size * 8 << ",SWAP,F2F"; break; + default: break; } if(iter->output->is_unique()) @@ -1352,6 +1356,8 @@ static void sleigh_esil(RzAnalysis *a, RzAnalysisOp *analysis_op, ut64 addr, con throw LowlevelError("sleigh_esil: arguments of Pcodes are not well inited."); break; } + default: + break; } } @@ -3048,7 +3054,7 @@ static bool sleigh_esil_eq(RzAnalysisEsil *esil) return ret; } -static unordered_set float_mem; +static std::unordered_set float_mem; static bool sleigh_esil_peek4(RzAnalysisEsil *esil) // Read out { diff --git a/src/asm_ghidra.cpp b/src/asm_ghidra.cpp index a1aad321..86a5472c 100644 --- a/src/asm_ghidra.cpp +++ b/src/asm_ghidra.cpp @@ -4,6 +4,7 @@ #include #include #include "SleighAsm.h" +#include "rz_ghidra_internal.h" static SleighAsm sasm; static RzIO *rio = nullptr; @@ -36,8 +37,15 @@ static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) return r; } +static bool init(void **user) +{ + rz_ghidra_lib_init(); + return true; +} + static bool fini(void *p) { + rz_ghidra_lib_fini(); if(rio) rz_io_free(rio); rio = nullptr; @@ -54,7 +62,7 @@ RzAsmPlugin rz_asm_plugin_ghidra = { /* .license = */ "LGPL3", /* .bits = */ 8 | 16 | 32 | 64, /* .endian = */ 0, - /* .init = */ nullptr, + /* .init = */ &init, /* .fini = */ &fini, /* .disassemble = */ &disassemble, /* .assemble = */ nullptr, diff --git a/src/core_ghidra.cpp b/src/core_ghidra.cpp index cc653578..a426a06e 100644 --- a/src/core_ghidra.cpp +++ b/src/core_ghidra.cpp @@ -7,7 +7,9 @@ #include "RizinArchitecture.h" #include "CodeXMLParse.h" #include "ArchMap.h" +#include "PrettyXmlEncode.h" #include "rz_ghidra.h" +#include "rz_ghidra_internal.h" // Windows clash #ifdef restrict @@ -74,6 +76,7 @@ static const ConfigVar cfg_var_verbose ("verbose", "true", "Show ve static std::recursive_mutex decompiler_mutex; +static int lib_init_refcount = 0; // protected by decompiler_mutex, refcounts rz_ghidra_lib_init initialization class DecompilerLock { @@ -173,7 +176,7 @@ static void Decompile(RzCore *core, ut64 addr, DecompileMode mode, std::stringst case DecompileMode::JSON: case DecompileMode::OFFSET: case DecompileMode::STATEMENTS: - arch.print->setXML(true); + arch.print->setMarkup(true); break; default: break; @@ -181,7 +184,8 @@ static void Decompile(RzCore *core, ut64 addr, DecompileMode mode, std::stringst if(mode == DecompileMode::XML) { out_stream << ""; - func->saveXml(out_stream, 0, true); + PrettyXmlEncode enc(out_stream); + func->encode(enc, 0, true); out_stream << ""; } switch(mode) @@ -199,9 +203,11 @@ static void Decompile(RzCore *core, ut64 addr, DecompileMode mode, std::stringst throw LowlevelError("Failed to parse XML code from Decompiler"); } break; - case DecompileMode::DEBUG_XML: - arch.saveXml(out_stream); + case DecompileMode::DEBUG_XML: { + PrettyXmlEncode enc(out_stream); + arch.encode(enc); break; + } default: break; } @@ -652,10 +658,27 @@ static RzCmdStatus pdgstar_handler(RzCore *core, int argc, const char **argv) { return RZ_CMD_STATUS_OK; } -static bool rz_ghidra_init(RzCore *core) +void rz_ghidra_lib_init(void) { std::lock_guard lock(decompiler_mutex); + lib_init_refcount++; startDecompilerLibrary(nullptr); +} + +void rz_ghidra_lib_fini(void) +{ + std::lock_guard lock(decompiler_mutex); + lib_init_refcount--; + if(lib_init_refcount < 0) + return; + if(lib_init_refcount == 0) + shutdownDecompilerLibrary(); +} + +static bool rz_ghidra_init(RzCore *core) +{ + std::lock_guard lock(decompiler_mutex); + rz_ghidra_lib_init(); RzConfig *cfg = core->config; rz_config_lock (cfg, false); @@ -688,7 +711,7 @@ static bool rz_ghidra_init(RzCore *core) static bool rz_ghidra_fini(RzCore *core) { std::lock_guard lock(decompiler_mutex); - shutdownDecompilerLibrary(); + rz_ghidra_lib_fini(); auto rzcmd = core->rcmd; RzCmdDesc *pdg_cd = rz_cmd_get_desc(rzcmd, "pdg"); diff --git a/src/rz_ghidra_internal.h b/src/rz_ghidra_internal.h new file mode 100644 index 00000000..de0f4a54 --- /dev/null +++ b/src/rz_ghidra_internal.h @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: 2023 Florian Märkl +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef RZ_GHIDRA_H +#define RZ_GHIDRA_H + +void rz_ghidra_lib_init(void); +void rz_ghidra_lib_fini(void); + +#endif + diff --git a/test/db/extras/analysis_ghidra b/test/db/extras/analysis_ghidra index b092ac80..a5011e6b 100644 --- a/test/db/extras/analysis_ghidra +++ b/test/db/extras/analysis_ghidra @@ -52,13 +52,13 @@ type: mul 0x00000000 DIV edx type: mod ---- -0x00000000 SHR eax,1 +0x00000000 SHR eax,0x1 type: shr ---- -0x00000000 SHL eax,1 +0x00000000 SHL eax,0x1 type: shl ---- -0x00000000 SAR eax,1 +0x00000000 SAR eax,0x1 type: sar ---- 0x00000000 OR esp,dword ptr [0xfff0] diff --git a/test/db/extras/asm_ghidra b/test/db/extras/asm_ghidra index 20661859..fc45bf7f 100644 --- a/test/db/extras/asm_ghidra +++ b/test/db/extras/asm_ghidra @@ -124,7 +124,7 @@ FILE=rizin-testbins/elf/analysis/dwarf_load EXPECT=<ambassador = AMBASSADOR_PURE; } else { (bright->window).sunlight = bright->morning->saved_argv[1]; - in_stack_ffffffe8 = "the "; iVar2 = sym.imp.strcmp((bright->window).sunlight, "the "); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_REASON; } else { - in_stack_ffffffe8 = "dark"; iVar2 = sym.imp.strcmp((bright->window).sunlight, "dark"); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_REVOLUTION; } else { - in_stack_ffffffe8 = "third"; iVar2 = sym.imp.strcmp((bright->window).sunlight, "third"); if (iVar2 == 0) { bright->ambassador = AMBASSADOR_ECHOES; @@ -1898,7 +1892,7 @@ void sym.Aeropause(Bright *bright, int32_t argc, char **argv) case 0xbad1abe1: break; } - sym.PrintAmbassador(bright->ambassador, in_stack_ffffffe8, in_stack_ffffffec, in_stack_fffffff0, in_stack_fffffff4); + sym.PrintAmbassador(bright->ambassador, in_stack_fffffff4); return; } EOF @@ -2380,273 +2374,340 @@ CCu base64:c3ltLmltcC5wcmludGYoIlBhc3N3b3JkOiAiKQ== @ 0x8048572 CCu base64:Jg== @ 0x804858a -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 494f4c4920437261636b6d65204c6576656c2030 7830350a0050617373776f72 - - - + + + + 50617373776f72643a2000257300000000000000 00ffffffffffffffffffffff - - - + + + -- undefined4 main(void) @@ -2748,7 +2809,9 @@ EXPECT=<