diff options
| author | Glenn Smith <glenn@vector35.com> | 2024-12-27 16:14:46 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2025-01-30 17:20:05 -0500 |
| commit | 8862696926173104957729683832591438161557 (patch) | |
| tree | 78ba6d7dc8144430136086c8dc84726171eec8ab /plugins/stack_render_layer | |
| parent | 5a5426d030b6be26d4564ba1eba2d8a275533256 (diff) | |
Render Layers
Diffstat (limited to 'plugins/stack_render_layer')
| -rw-r--r-- | plugins/stack_render_layer/CMakeLists.txt | 46 | ||||
| -rw-r--r-- | plugins/stack_render_layer/plugin.cpp | 124 |
2 files changed, 170 insertions, 0 deletions
diff --git a/plugins/stack_render_layer/CMakeLists.txt b/plugins/stack_render_layer/CMakeLists.txt new file mode 100644 index 00000000..3133e63d --- /dev/null +++ b/plugins/stack_render_layer/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +project(stack_render_layer) + +file(GLOB SOURCES + *.cpp + *.c + *.h) + +if(DEMO) + add_library(${PROJECT_NAME} STATIC ${SOURCES}) +else() + add_library(${PROJECT_NAME} SHARED ${SOURCES}) +endif() + +if(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 17 + CXX_VISIBILITY_PRESET hidden + CXX_STANDARD_REQUIRED ON + C_STANDARD 99 + C_STANDARD_REQUIRED ON + C_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + POSITION_INDEPENDENT_CODE ON) + +if(BN_INTERNAL_BUILD) + plugin_rpath(${PROJECT_NAME}) + set_target_properties(${PROJECT_NAME} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR} + RUNTIME_OUTPUT_DIRECTORY ${BN_CORE_PLUGIN_DIR}) +else() + bn_install_plugin(${PROJECT_NAME}) +endif() diff --git a/plugins/stack_render_layer/plugin.cpp b/plugins/stack_render_layer/plugin.cpp new file mode 100644 index 00000000..b32ee470 --- /dev/null +++ b/plugins/stack_render_layer/plugin.cpp @@ -0,0 +1,124 @@ + +#include <binaryninjaapi.h> +#include <thread> + +using namespace BinaryNinja; + + +class StackRenderLayer: public RenderLayer +{ +public: + StackRenderLayer(): RenderLayer("Annotate Stack Offset") {} + + void ApplyToLines( + Ref<BasicBlock> block, + std::vector<DisassemblyTextLine>& lines + ) + { + for (auto& line: lines) + { + // Skip blank lines (block separators) + if (line.tokens.empty()) + { + continue; + } + + // Insert tokens after the address separator + int64_t sep = -1; + for (int64_t i = 0; i < line.tokens.size(); i ++) + { + if (line.tokens[i].type == AddressSeparatorToken) + { + sep = i; + break; + } + } + // Don't annotate lines which don't have an address separator + // (these are usually annotations like { Does not return } + if (sep == -1) + { + continue; + } + + // Grab stack offset value from function + auto stackOffset = block->GetFunction()->GetRegisterValueAtInstruction( + block->GetArchitecture(), + line.addr, + block->GetArchitecture()->GetStackPointerRegister() + ); + auto stackOffsetAfter = block->GetFunction()->GetRegisterValueAfterInstruction( + block->GetArchitecture(), + line.addr, + block->GetArchitecture()->GetStackPointerRegister() + ); + if (stackOffset.state == StackFrameOffset) + { + // Stack pointer is resolved to an offset: show the offset + // (but negative because that is how other tools do it) + line.tokens.emplace( + line.tokens.begin() + sep + 1, + IntegerToken, + fmt::format("{:4x}", -stackOffset.value), + -stackOffset.value + ); + } + else + { + // Stack pointer is not resolved, show ?? + line.tokens.emplace( + line.tokens.begin() + sep + 1, + IntegerToken, + " ??", + 0 + ); + } + // And put a spacer after the offset token + if (stackOffset != stackOffsetAfter) + { + line.tokens.emplace( + line.tokens.begin() + sep + 2, + TextToken, + "* " + ); + } + else + { + line.tokens.emplace( + line.tokens.begin() + sep + 2, + TextToken, + " " + ); + } + } + } + + virtual void ApplyToDisassemblyBlock( + Ref<BasicBlock> block, + std::vector<DisassemblyTextLine>& lines + ) override + { + // Break this out into a helper so we don't have to write it twice + ApplyToLines(block, lines); + } + + virtual void ApplyToLowLevelILBlock( + Ref<BasicBlock> block, + std::vector<DisassemblyTextLine>& lines + ) override + { + // Break this out into a helper so we don't have to write it twice + ApplyToLines(block, lines); + } +}; + + +extern "C" { + BN_DECLARE_CORE_ABI_VERSION + + BINARYNINJAPLUGIN bool CorePluginInit() + { + static StackRenderLayer* layer = new StackRenderLayer(); + RenderLayer::Register(layer, DisabledByDefaultRenderLayerDefaultEnableState); + return true; + } +}
\ No newline at end of file |
