diff options
| -rw-r--r-- | highlevelilinstruction.cpp | 52 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 22 | ||||
| -rw-r--r-- | lowlevelilinstruction.cpp | 41 | ||||
| -rw-r--r-- | lowlevelilinstruction.h | 21 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 46 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 21 |
6 files changed, 203 insertions, 0 deletions
diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 3c838c1a..3626dd54 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -3262,3 +3262,55 @@ ExprId HighLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprId { return AddExprWithLocation(HLIL_FCMP_UO, loc, size, a, b); } + + +fmt::format_context::iterator fmt::formatter<HighLevelILInstruction>::format(const HighLevelILInstruction& obj, format_context& ctx) const +{ + if (!obj.function) + return fmt::format_to(ctx.out(), "<uninit>"); + + vector<InstructionTextToken> tokens; + Ref<DisassemblySettings> settings = new DisassemblySettings(); + vector<DisassemblyTextLine> lines = obj.function->GetExprText(obj, settings); + if (!lines.empty()) + { + if (presentation == '?') + { + fmt::format_to(ctx.out(), "{} ", obj.operation); + fmt::format_to(ctx.out(), "@ {:#x} ", obj.address); + if (obj.exprIndex != BN_INVALID_EXPR && (obj.exprIndex & 0xffff000000000000) == 0) + { + fmt::format_to(ctx.out(), "[expr {}] ", obj.exprIndex); + } + if (obj.instructionIndex != BN_INVALID_EXPR && (obj.instructionIndex & 0xffff000000000000) == 0) + { + fmt::format_to(ctx.out(), "[instr {}] ", obj.instructionIndex); + } + Ref<Type> type = obj.GetType(); + if (type) + { + fmt::format_to(ctx.out(), "[type: {}] ", type->GetString()); + } + } + + bool first = true; + for (auto& line: lines) + { + if (!first) + { + fmt::format_to(ctx.out(), " ; "); + } + first = false; + + for (auto& token: line.tokens) + { + fmt::format_to(ctx.out(), "{}", token.text); + } + } + } + else + { + fmt::format_to(ctx.out(), "???"); + } + return ctx.out(); +} diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index 0476a182..be6f8b43 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -29,6 +29,7 @@ #include "binaryninjaapi.h" #endif #include "mediumlevelilinstruction.h" +#include <fmt/core.h> #ifdef BINARYNINJACORE_LIBRARY namespace BinaryNinjaCore @@ -1419,3 +1420,24 @@ namespace BinaryNinja #undef _STD_SET #undef _STD_UNORDERED_MAP } // namespace BinaryNinjaCore + +#ifdef BINARYNINJACORE_LIBRARY +#define IL_INS_NS BinaryNinjaCore +#else +#define IL_INS_NS BinaryNinja +#endif +template<> struct fmt::formatter<IL_INS_NS::HighLevelILInstruction> +{ + // <empty> -> normal, ? -> debug + char presentation = ' '; + format_context::iterator format(const IL_INS_NS::HighLevelILInstruction& obj, format_context& ctx) const; + constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator + { + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == '?') + presentation = *it++; + if (it != end && *it != '}') detail::throw_format_error("invalid format"); + return it; + } +}; +#undef IL_INS_NS diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index e0d5922d..17368662 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -3690,3 +3690,44 @@ ExprId LowLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprId b { return AddExprWithLocation(LLIL_FCMP_UO, loc, size, 0, a, b); } + + +fmt::format_context::iterator fmt::formatter<LowLevelILInstruction>::format(const LowLevelILInstruction& obj, format_context& ctx) const +{ + if (!obj.function) + return fmt::format_to(ctx.out(), "<uninit>"); + + vector<InstructionTextToken> tokens; +#ifdef BINARYNINJACORE_LIBRARY + bool success = obj.function->GetExprText(obj.function->GetFunction(), obj.function->GetArchitecture(), obj, tokens); +#else + bool success = obj.function->GetExprText(obj.function->GetArchitecture(), obj.exprIndex, tokens); +#endif + if (success) + { + string text; + if (presentation == '?') + { + fmt::format_to(ctx.out(), "{} ", obj.operation); + fmt::format_to(ctx.out(), "@ {:#x} ", obj.address); + if (obj.exprIndex != BN_INVALID_EXPR && (obj.exprIndex & 0xffff000000000000) == 0) + { + fmt::format_to(ctx.out(), "[expr {}] ", obj.exprIndex); + } + if (obj.instructionIndex != BN_INVALID_EXPR && (obj.instructionIndex & 0xffff000000000000) == 0) + { + fmt::format_to(ctx.out(), "[instr {}] ", obj.instructionIndex); + } + } + + for (auto& token: tokens) + { + fmt::format_to(ctx.out(), token.text); + } + } + else + { + fmt::format_to(ctx.out(), "???"); + } + return ctx.out(); +} diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index 898e72b8..dd416e90 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -2010,3 +2010,24 @@ namespace BinaryNinja #undef _STD_UNORDERED_MAP #undef _STD_MAP } // namespace BinaryNinjaCore + +#ifdef BINARYNINJACORE_LIBRARY +#define IL_INS_NS BinaryNinjaCore +#else +#define IL_INS_NS BinaryNinja +#endif +template<> struct fmt::formatter<IL_INS_NS::LowLevelILInstruction> +{ + // <empty> -> normal, ? -> debug + char presentation = ' '; + format_context::iterator format(const IL_INS_NS::LowLevelILInstruction& obj, format_context& ctx) const; + constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator + { + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == '?') + presentation = *it++; + if (it != end && *it != '}') detail::throw_format_error("invalid format"); + return it; + } +}; +#undef IL_INS_NS diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index 0306a404..754729c0 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -3125,3 +3125,49 @@ ExprId MediumLevelILFunction::FloatCompareUnordered(size_t size, ExprId a, ExprI { return AddExprWithLocation(MLIL_FCMP_UO, loc, size, a, b); } + + +fmt::format_context::iterator fmt::formatter<MediumLevelILInstruction>::format(const MediumLevelILInstruction& obj, format_context& ctx) const +{ + if (!obj.function) + return fmt::format_to(ctx.out(), "<uninit>"); + + vector<InstructionTextToken> tokens; +#ifdef BINARYNINJACORE_LIBRARY + bool success = obj.function->GetExprText(obj.function->GetFunction(), obj.function->GetArchitecture(), obj, tokens, new DisassemblySettings()); +#else + bool success = obj.function->GetExprText(obj.function->GetArchitecture(), obj.exprIndex, tokens); +#endif + if (success) + { + string text; + if (presentation == '?') + { + fmt::format_to(ctx.out(), "{} ", obj.operation); + fmt::format_to(ctx.out(), "@ {:#x} ", obj.address); + if (obj.exprIndex != BN_INVALID_EXPR && (obj.exprIndex & 0xffff000000000000) == 0) + { + fmt::format_to(ctx.out(), "[expr {}] ", obj.exprIndex); + } + if (obj.instructionIndex != BN_INVALID_EXPR && (obj.instructionIndex & 0xffff000000000000) == 0) + { + fmt::format_to(ctx.out(), "[instr {}] ", obj.instructionIndex); + } + Ref<Type> type = obj.GetType(); + if (type) + { + fmt::format_to(ctx.out(), "[type: {}] ", type->GetString()); + } + } + + for (auto& token: tokens) + { + fmt::format_to(ctx.out(), token.text); + } + } + else + { + fmt::format_to(ctx.out(), "???"); + } + return ctx.out(); +} diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h index 861bf395..b9745177 100644 --- a/mediumlevelilinstruction.h +++ b/mediumlevelilinstruction.h @@ -1713,3 +1713,24 @@ namespace BinaryNinja #undef _STD_UNORDERED_MAP #undef _STD_MAP } // namespace BinaryNinjaCore + +#ifdef BINARYNINJACORE_LIBRARY +#define IL_INS_NS BinaryNinjaCore +#else +#define IL_INS_NS BinaryNinja +#endif +template<> struct fmt::formatter<IL_INS_NS::MediumLevelILInstruction> +{ + // <empty> -> normal, ? -> debug + char presentation = ' '; + format_context::iterator format(const IL_INS_NS::MediumLevelILInstruction& obj, format_context& ctx) const; + constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator + { + auto it = ctx.begin(), end = ctx.end(); + if (it != end && *it == '?') + presentation = *it++; + if (it != end && *it != '}') detail::throw_format_error("invalid format"); + return it; + } +}; +#undef IL_INS_NS |
