diff options
| author | Mason Reed <mason@vector35.com> | 2024-05-22 20:06:24 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2024-05-22 20:22:44 -0400 |
| commit | dff192e3bd6d5737633a740988c31e4ecba92998 (patch) | |
| tree | 39dfd844e8c35c0af37e917f97abeabf568c8d72 /examples/background_task | |
| parent | 331d226464fb043a12eada4f4c752d8ef20c5efb (diff) | |
Add background task example plugin
Clarify BackgroundTask functionality (skip-note, skip-ci)
Providing clear documentation so it is understood that background tasks do not manage the execution of said the task.
Add background_task plugin to examples section
Diffstat (limited to 'examples/background_task')
| -rw-r--r-- | examples/background_task/CMakeLists.txt | 36 | ||||
| -rw-r--r-- | examples/background_task/src/backgroundtask.cpp | 80 |
2 files changed, 116 insertions, 0 deletions
diff --git a/examples/background_task/CMakeLists.txt b/examples/background_task/CMakeLists.txt new file mode 100644 index 00000000..36e012b0 --- /dev/null +++ b/examples/background_task/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) + +project(background_task CXX C) + +file(GLOB SOURCES + src/*.cpp + src/*.h) + +add_library(background_task SHARED ${SOURCES}) + +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(background_task binaryninjaui) + +set_target_properties(background_task PROPERTIES + CXX_STANDARD 17 + CXX_VISIBILITY_PRESET hidden + CXX_STANDARD_REQUIRED ON + VISIBILITY_INLINES_HIDDEN ON + POSITION_INDEPENDENT_CODE ON + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/out/bin) + +if(BN_INTERNAL_BUILD) + ui_plugin_rpath(background_task) +endif() + +bn_install_plugin(${PROJECT_NAME}) diff --git a/examples/background_task/src/backgroundtask.cpp b/examples/background_task/src/backgroundtask.cpp new file mode 100644 index 00000000..8a307080 --- /dev/null +++ b/examples/background_task/src/backgroundtask.cpp @@ -0,0 +1,80 @@ +#include <thread> +#include <random> + +#include "binaryninjaapi.h" + +using namespace BinaryNinja; + +static Ref<BackgroundTask> inspireBackgroundTask = nullptr; + +uint64_t InspireWriteCallback(uint8_t *data, uint64_t len, void *ctxt) +{ + try + { + Json::Value json; + std::unique_ptr<Json::CharReader> reader(Json::CharReaderBuilder().newCharReader()); + std::string errors; + if (!reader->parse((char *) data, (char *) data + len, &json, &errors)) + { + LogError("Failed to parse! %s", errors.c_str()); + } + else + { + std::random_device rd; + std::map<int, int> hist; + std::uniform_int_distribution<Json::ArrayIndex> dist(0, json.size()); + auto randQuoteObj = json.get(dist(rd), 0); + if (randQuoteObj.isObject() && randQuoteObj.size() == 2) + { + std::string quote = randQuoteObj.get("text", Json::Value("INVALID")).asString(); + LogInfo("%s", quote.c_str()); + // Display quote in progress text for 3 seconds. + inspireBackgroundTask->SetProgressText(quote); + std::this_thread::sleep_for(std::chrono::seconds(3)); + } + } + } catch (Json::Exception e) + { + LogError("JSON exception! %s", e.m_message.c_str()); + inspireBackgroundTask->Cancel(); + } + return len; +} + +bool InspireProgressCallback(void *ctxt, uint64_t progress, uint64_t total) +{ + // Close connection on cancellation + return !inspireBackgroundTask->IsCancelled(); +} + +void Inspire(BinaryView *bv) +{ + inspireBackgroundTask = new BackgroundTask("Getting inspired!", true); + std::thread inspireThread([]() { + LogInfo("Getting inspired!"); + BNDownloadInstanceOutputCallbacks outputCallbacks; + memset(&outputCallbacks, 0, sizeof(outputCallbacks)); + outputCallbacks.writeCallback = InspireWriteCallback; + outputCallbacks.progressCallback = InspireProgressCallback; + + auto downloadProvider = DownloadProvider::GetByName("CoreDownloadProvider"); + auto downloadInstance = downloadProvider->CreateNewInstance(); + inspireBackgroundTask->SetProgressText("Waiting for inspiration..."); + if (downloadInstance->PerformRequest("https://type.fit/api/quotes", &outputCallbacks)) + LogError("Inspiration failed!"); + + inspireBackgroundTask->Finish(); + }); + inspireThread.detach(); +} + +extern "C" { + BN_DECLARE_CORE_ABI_VERSION + + BINARYNINJAPLUGIN bool CorePluginInit() + { + PluginCommand::Register("Inspire me!", "Print an inspirational quote to the log", Inspire); + + return true; + } +} |
