summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/CMakeLists.txt1
-rw-r--r--examples/bid64_constant/CMakeLists.txt30
-rwxr-xr-xexamples/bid64_constant/sample_binarybin0 -> 374912 bytes
-rw-r--r--examples/bid64_constant/src/bid64_constant.cpp144
4 files changed, 175 insertions, 0 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 3e1bedce..1e8d5373 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,5 +1,6 @@
# Personal+ edition (free edition doesn't get plugins due to no API access)
add_subdirectory(background_task)
+add_subdirectory(bid64_constant)
add_subdirectory(breakpoint)
add_subdirectory(encoded_strings)
add_subdirectory(x86_extension)
diff --git a/examples/bid64_constant/CMakeLists.txt b/examples/bid64_constant/CMakeLists.txt
new file mode 100644
index 00000000..4dc29cb0
--- /dev/null
+++ b/examples/bid64_constant/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
+
+project(bid64_constant CXX C)
+
+add_library(${PROJECT_NAME} SHARED
+ src/bid64_constant.cpp)
+
+if(NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD)
+ # Out-of-tree build
+ find_path(
+ BN_API_PATH
+ NAMES binaryninjaapi.h
+ HINTS ../.. binaryninjaapi $ENV{BN_API_PATH}
+ REQUIRED
+ )
+ add_subdirectory(${BN_API_PATH} api)
+endif()
+
+target_link_libraries(${PROJECT_NAME}
+ binaryninjaapi)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
+ CXX_STANDARD 20
+ CXX_VISIBILITY_PRESET hidden
+ CXX_STANDARD_REQUIRED ON
+ VISIBILITY_INLINES_HIDDEN ON
+ POSITION_INDEPENDENT_CODE ON
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out/bin)
+
+bn_install_plugin(${PROJECT_NAME})
diff --git a/examples/bid64_constant/sample_binary b/examples/bid64_constant/sample_binary
new file mode 100755
index 00000000..53aef608
--- /dev/null
+++ b/examples/bid64_constant/sample_binary
Binary files differ
diff --git a/examples/bid64_constant/src/bid64_constant.cpp b/examples/bid64_constant/src/bid64_constant.cpp
new file mode 100644
index 00000000..f2c91ea4
--- /dev/null
+++ b/examples/bid64_constant/src/bid64_constant.cpp
@@ -0,0 +1,144 @@
+// This plugin renders 64-bit binary integer decimal floating point constants directly in the
+// decompilation. See the sample binary at `examples/bid64_constant/sample_binary` for an
+// example of a binary that uses this unusual format.
+
+#define _CRT_SECURE_NO_WARNINGS
+#include <cinttypes>
+#include <cstdio>
+#include <cstring>
+#include <map>
+#include <functional>
+#include <vector>
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+using namespace std;
+
+
+static string Bid64ToString(bool sign, uint64_t magnitude, int exponent)
+{
+ if (magnitude == 0)
+ exponent = 0;
+
+ string digits = to_string(magnitude);
+ int intPartDigits = digits.length() + exponent;
+
+ int displayedExponent = 0;
+ if (intPartDigits > 10 || intPartDigits < -4)
+ {
+ int newExponent = 1 - (int)digits.length();
+ displayedExponent = exponent - newExponent;
+ intPartDigits = digits.length() + newExponent;
+ }
+
+ string fracDigits;
+ if (intPartDigits < 0)
+ fracDigits = digits;
+ else if (intPartDigits <= (int)digits.length())
+ fracDigits = digits.substr(intPartDigits);
+
+ int trailingZeros = 0;
+ for (size_t i = 0; i < fracDigits.length(); i++)
+ {
+ if (fracDigits[(fracDigits.length() - 1) - i] != '0')
+ break;
+ trailingZeros++;
+ }
+
+ int nonzeroFracDigits = (int)fracDigits.length() - trailingZeros;
+ fracDigits = fracDigits.substr(0, nonzeroFracDigits);
+
+ string result;
+ if (sign)
+ result = "-";
+ if (intPartDigits > 0)
+ {
+ for (size_t i = 0; i < intPartDigits; i++)
+ {
+ if (i >= digits.length())
+ result += "0";
+ else
+ result += string(1, digits[i]);
+ }
+ }
+ else
+ {
+ result += "0";
+ }
+
+ if (intPartDigits < 0 && fracDigits.length() > 0)
+ {
+ result += ".";
+ for (size_t i = 0; i < -intPartDigits; i++)
+ result += "0";
+ result += fracDigits;
+ }
+ else if (fracDigits.length() > 0)
+ {
+ result += ".";
+ result += fracDigits;
+ }
+
+ if (displayedExponent > 0)
+ result += "E+" + to_string(displayedExponent);
+ else if (displayedExponent < 0)
+ result += "E" + to_string(displayedExponent);
+
+ return result;
+}
+
+
+class Bid64ConstantRenderer : public ConstantRenderer
+{
+public:
+ Bid64ConstantRenderer() : ConstantRenderer("bid64_constant")
+ {
+ }
+
+ bool RenderConstant(const HighLevelILInstruction&, Type* type, int64_t val, HighLevelILTokenEmitter& tokens,
+ DisassemblySettings* settings, BNOperatorPrecedence) override
+ {
+ // Typedefs have the final type, so make sure it is a 64 bit integer. The registered name
+ // should be the typedef "BID_UINT64".
+ if (!type || type->GetClass() != IntegerTypeClass)
+ return false;
+ if (type->GetWidth() != 8)
+ return false;
+ auto name = type->GetRegisteredName();
+ if (!name || name->GetName().GetString() != "BID_UINT64")
+ return false;
+
+ // Get sign bit and raw exponent
+ bool sign = (val & (1LL << 63)) != 0;
+ int rawExponent = (int)((val >> 53) & 0x3ff);
+ if (rawExponent >= 0x300)
+ {
+ // Don't try and render NaN or infinity
+ return false;
+ }
+
+ // Get magnitude and actual exponent
+ constexpr uint64_t BIAS = 398;
+ int exponent = rawExponent - BIAS;
+ uint64_t magnitude = val & ((1LL << 53) - 1);
+
+ tokens.Append(FloatingPointToken, Bid64ToString(sign, magnitude, exponent) + "_bid");
+ return true;
+ }
+};
+
+
+extern "C"
+{
+ BN_DECLARE_CORE_ABI_VERSION
+
+ BINARYNINJAPLUGIN void CorePluginDependencies()
+ {
+ }
+
+ BINARYNINJAPLUGIN bool CorePluginInit()
+ {
+ ConstantRenderer::Register(new Bid64ConstantRenderer());
+ return true;
+ }
+}