summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2022-06-07 21:51:27 -0400
committerGlenn Smith <glenn@vector35.com>2022-06-14 21:05:38 -0400
commitb15607dc351bd7787b85751bce9bbddc0a705461 (patch)
tree47558d7c26d1b8acb2fe4788e252634b1c139fd1
parent55cb3e76f536bc8d4a6533bd7ea5202d464c5f81 (diff)
Add Dump() to *LILInstruction
-rw-r--r--highlevelilinstruction.cpp42
-rw-r--r--highlevelilinstruction.h7
-rw-r--r--lowlevelilinstruction.cpp33
-rw-r--r--lowlevelilinstruction.h3
-rw-r--r--mediumlevelilinstruction.cpp38
-rw-r--r--mediumlevelilinstruction.h3
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);