diff options
| author | Glenn Smith <glenn@vector35.com> | 2022-06-07 21:51:27 -0400 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2022-06-14 21:05:38 -0400 |
| commit | b15607dc351bd7787b85751bce9bbddc0a705461 (patch) | |
| tree | 47558d7c26d1b8acb2fe4788e252634b1c139fd1 | |
| parent | 55cb3e76f536bc8d4a6533bd7ea5202d464c5f81 (diff) | |
Add Dump() to *LILInstruction
| -rw-r--r-- | highlevelilinstruction.cpp | 42 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 7 | ||||
| -rw-r--r-- | lowlevelilinstruction.cpp | 33 | ||||
| -rw-r--r-- | lowlevelilinstruction.h | 3 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 38 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 3 |
6 files changed, 124 insertions, 2 deletions
diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 5f8777e1..ecec3869 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include <string.h> #ifdef BINARYNINJACORE_LIBRARY #include "highlevelilfunction.h" #include "highlevelilssafunction.h" @@ -883,6 +884,47 @@ MediumLevelILInstruction HighLevelILInstructionBase::GetMediumLevelILSSAForm() c } +char* HighLevelILInstructionBase::Dump() const +{ + if (!function) + return strdup("<uninit>"); + + vector<InstructionTextToken> tokens; + vector<DisassemblyTextLine> lines = function->GetExprText(*this, new DisassemblySettings()); + if (!lines.empty()) + { + string text; + if (exprIndex != BN_INVALID_EXPR && (exprIndex & 0xffff000000000000) == 0) + { + text += "[expr " + to_string(exprIndex) + "] "; + } + if (instructionIndex != BN_INVALID_EXPR && (instructionIndex & 0xffff000000000000) == 0) + { + text += "[instr " + to_string(instructionIndex) + "] "; + } + Ref<Type> type = GetType(); + if (type) + { + text += "[type: " + type->GetString() + "] "; + } + + for (auto& line: lines) + { + for (auto& token: line.tokens) + { + text += token.text; + } + text += " ; "; + } + return strdup(text.c_str()); + } + else + { + return strdup("???"); + } +} + + void HighLevelILInstructionBase::Replace(ExprId expr) { function->ReplaceExpr(exprIndex, expr); diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index 6947479c..9cdb9b1a 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -293,9 +293,9 @@ namespace BinaryNinja struct HighLevelILInstructionBase : public BNHighLevelILInstruction { #ifdef BINARYNINJACORE_LIBRARY - HighLevelILFunction* function; + HighLevelILFunction* function = nullptr; #else - Ref<HighLevelILFunction> function; + Ref<HighLevelILFunction> function = nullptr; #endif size_t exprIndex, instructionIndex; bool ast; @@ -338,6 +338,9 @@ namespace BinaryNinja MediumLevelILInstruction GetMediumLevelIL() const; MediumLevelILInstruction GetMediumLevelILSSAForm() const; + // Return (and leak) a string describing the instruction for debugger use + char* Dump() const; + void Replace(ExprId expr); size_t GetInstructionIndex() const; diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index fe386e8d..b7277831 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include <string.h> #ifdef BINARYNINJACORE_LIBRARY #include "lowlevelilfunction.h" #include "lowlevelilssafunction.h" @@ -1744,6 +1745,38 @@ MediumLevelILInstruction LowLevelILInstructionBase::GetMappedMediumLevelIL() con } +char* LowLevelILInstructionBase::Dump() const +{ + vector<InstructionTextToken> tokens; +#ifdef BINARYNINJACORE_LIBRARY + bool success = function->GetExprText(function->GetFunction(), function->GetArchitecture(), *this, tokens); +#else + bool success = function->GetExprText(function->GetArchitecture(), exprIndex, tokens); +#endif + if (success) + { + string text; + if (exprIndex != BN_INVALID_EXPR && (exprIndex & 0xffff000000000000) == 0) + { + text += "[expr " + to_string(exprIndex) + "] "; + } + if (instructionIndex != BN_INVALID_EXPR && (instructionIndex & 0xffff000000000000) == 0) + { + text += "[instr " + to_string(instructionIndex) + "] "; + } + for (auto& token: tokens) + { + text += token.text; + } + return strdup(text.c_str()); + } + else + { + return strdup("???"); + } +} + + void LowLevelILInstructionBase::Replace(ExprId expr) { function->ReplaceExpr(exprIndex, expr); diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index 033b98b7..e9274761 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -705,6 +705,9 @@ namespace BinaryNinja MediumLevelILInstruction GetMediumLevelIL() const; MediumLevelILInstruction GetMappedMediumLevelIL() const; + // Return (and leak) a string describing the instruction for debugger use + char* Dump() const; + void Replace(ExprId expr); template <BNLowLevelILOperation N> diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index 29a58de7..49a5eed9 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include <string.h> #ifdef BINARYNINJACORE_LIBRARY #include "mediumlevelilfunction.h" #include "mediumlevelilssafunction.h" @@ -1059,6 +1060,43 @@ Confidence<Ref<Type>> MediumLevelILInstructionBase::GetType() const } +char* MediumLevelILInstructionBase::Dump() const +{ + vector<InstructionTextToken> tokens; +#ifdef BINARYNINJACORE_LIBRARY + bool success = function->GetExprText(function->GetFunction(), function->GetArchitecture(), *this, tokens, new DisassemblySettings()); +#else + bool success = function->GetExprText(function->GetArchitecture(), exprIndex, tokens); +#endif + if (success) + { + string text; + if (exprIndex != BN_INVALID_EXPR && (exprIndex & 0xffff000000000000) == 0) + { + text += "[expr " + to_string(exprIndex) + "] "; + } + if (instructionIndex != BN_INVALID_EXPR && (instructionIndex & 0xffff000000000000) == 0) + { + text += "[instr " + to_string(instructionIndex) + "] "; + } + Ref<Type> type = GetType(); + if (type) + { + text += "[type: " + type->GetString() + "] "; + } + for (auto& token: tokens) + { + text += token.text; + } + return strdup(text.c_str()); + } + else + { + return strdup("???"); + } +} + + size_t MediumLevelILInstructionBase::GetSSAVarVersion(const Variable& var) { return function->GetSSAVarVersionAtInstruction(var, instructionIndex); diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h index 7e6194a7..482cf2f9 100644 --- a/mediumlevelilinstruction.h +++ b/mediumlevelilinstruction.h @@ -431,6 +431,9 @@ namespace BinaryNinja const _STD_SET<BNDataFlowQueryOption>& options = _STD_SET<BNDataFlowQueryOption>()) const; Confidence<Ref<Type>> GetType() const; + // Return (and leak) a string describing the instruction for debugger use + char* Dump() const; + size_t GetSSAVarVersion(const Variable& var); size_t GetSSAMemoryVersion(); Variable GetVariableForRegister(uint32_t reg); |
