diff options
| -rw-r--r-- | binaryninjaapi.h | 16 | ||||
| -rw-r--r-- | binaryninjacore.h | 32 | ||||
| -rw-r--r-- | transformcontext.cpp | 71 | ||||
| -rw-r--r-- | transformsession.cpp | 6 | ||||
| -rw-r--r-- | ui/containerbrowser.h | 57 | ||||
| -rw-r--r-- | ui/passworddialog.h | 34 | ||||
| -rw-r--r-- | ui/passwordedit.h | 6 | ||||
| -rw-r--r-- | view/kernelcache/core/transformers/KernelCacheTransforms.cpp | 7 |
8 files changed, 178 insertions, 51 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index a71d8fc0..a1429ec1 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -9040,15 +9040,22 @@ namespace BinaryNinja { TransformContext(BNTransformContext* context); virtual ~TransformContext(); - std::string GetTransformName() const; - std::string GetFileName() const; Ref<BinaryView> GetInput() const; + std::string GetFileName() const; + std::string GetTransformName() const; + void SetTransformParameters(const std::map<std::string, DataBuffer>& params); + void SetTransformParameter(const std::string& name, const DataBuffer& data); + bool HasTransformParameter(const std::string& name) const; + void ClearTransformParameter(const std::string& name); + std::string GetExtractionMessage() const; + BNTransformResult GetExtractionResult() const; + BNTransformResult GetTransformResult() const; Ref<Metadata> GetMetadata() const; Ref<TransformContext> GetParent() const; size_t GetChildCount() const; std::vector<Ref<TransformContext>> GetChildren() const; - Ref<TransformContext> GetChild(const std::string& filename) const; - Ref<TransformContext> CreateChild(const DataBuffer& data, const std::string& filename); + Ref<TransformContext> GetChild(const std::string& filename = "") const; + Ref<TransformContext> SetChild(const DataBuffer& data, const std::string& filename = "", BNTransformResult result = TransformSuccess, const std::string& message = ""); bool IsLeaf() const; bool IsRoot() const; std::vector<std::string> GetAvailableFiles() const; @@ -9073,6 +9080,7 @@ namespace BinaryNinja { Ref<BinaryView> GetCurrentView() const; Ref<TransformContext> GetRootContext() const; Ref<TransformContext> GetCurrentContext() const; + bool ProcessFrom(Ref<TransformContext> context); bool Process(); bool HasAnyStages() const; bool HasSinglePath() const; diff --git a/binaryninjacore.h b/binaryninjacore.h index 3ea122bd..619b1c98 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,14 +37,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 135 +#define BN_CURRENT_CORE_ABI_VERSION 136 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 134 +#define BN_MINIMUM_CORE_ABI_VERSION 136 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -364,6 +364,14 @@ extern "C" TransformSessionModeOnDemand = 2, // Proceed step-by-step, requesting input at each stage } BNTransformSessionMode; + typedef enum BNTransformResult + { + TransformSuccess = 0, + TransformNotAttempted = 1, + TransformFailure = 2, + TransformRequiresPassword = 3 + } BNTransformResult; + typedef enum BNBranchType { UnconditionalBranch = 0, @@ -4650,26 +4658,31 @@ extern "C" BINARYNINJACOREAPI char* BNGetTransformGroup(BNTransform* xform); BINARYNINJACOREAPI BNTransformParameterInfo* BNGetTransformParameterList(BNTransform* xform, size_t* count); BINARYNINJACOREAPI void BNFreeTransformParameterList(BNTransformParameterInfo* params, size_t count); - BINARYNINJACOREAPI bool BNDecode( - BNTransform* xform, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount); - BINARYNINJACOREAPI bool BNEncode( - BNTransform* xform, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount); + BINARYNINJACOREAPI bool BNDecode(BNTransform* xform, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount); + BINARYNINJACOREAPI bool BNEncode(BNTransform* xform, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount); BINARYNINJACOREAPI bool BNDecodeWithContext(BNTransform* xform, BNTransformContext* context, BNTransformParameter* params, size_t paramCount); BINARYNINJACOREAPI bool BNCanDecode(BNTransform* xform, BNBinaryView* input); // Transform Context BINARYNINJACOREAPI BNTransformContext* BNNewTransformContextReference(BNTransformContext* context); BINARYNINJACOREAPI void BNFreeTransformContext(BNTransformContext* context); - BINARYNINJACOREAPI char* BNTransformContextGetTransformName(BNTransformContext* context); - BINARYNINJACOREAPI char* BNTransformContextGetFileName(BNTransformContext* context); BINARYNINJACOREAPI BNBinaryView* BNTransformContextGetInput(BNTransformContext* context); + BINARYNINJACOREAPI char* BNTransformContextGetFileName(BNTransformContext* context); + BINARYNINJACOREAPI char* BNTransformContextGetTransformName(BNTransformContext* context); + BINARYNINJACOREAPI void BNTransformContextSetTransformParameters(BNTransformContext* context, BNTransformParameter* params, size_t paramCount); + BINARYNINJACOREAPI void BNTransformContextSetTransformParameter(BNTransformContext* context, const char* name, BNDataBuffer* data); + BINARYNINJACOREAPI bool BNTransformContextHasTransformParameter(BNTransformContext* context, const char* name); + BINARYNINJACOREAPI void BNTransformContextClearTransformParameter(BNTransformContext* context, const char* name); + BINARYNINJACOREAPI char* BNTransformContextGetExtractionMessage(BNTransformContext* context); + BINARYNINJACOREAPI BNTransformResult BNTransformContextGetExtractionResult(BNTransformContext* context); + BINARYNINJACOREAPI BNTransformResult BNTransformContextGetTransformResult(BNTransformContext* context); BINARYNINJACOREAPI BNMetadata* BNTransformContextGetMetadata(BNTransformContext* context); BINARYNINJACOREAPI BNTransformContext* BNTransformContextGetParent(BNTransformContext* context); BINARYNINJACOREAPI size_t BNTransformContextGetChildCount(BNTransformContext* context); BINARYNINJACOREAPI BNTransformContext** BNTransformContextGetChildren(BNTransformContext* context, size_t* count); BINARYNINJACOREAPI void BNFreeTransformContextList(BNTransformContext** contexts, size_t count); BINARYNINJACOREAPI BNTransformContext* BNTransformContextGetChild(BNTransformContext* context, const char* filename); - BINARYNINJACOREAPI BNTransformContext* BNTransformContextCreateChild(BNTransformContext* context, BNDataBuffer* data, const char* filename); + BINARYNINJACOREAPI BNTransformContext* BNTransformContextSetChild(BNTransformContext* context, BNDataBuffer* data, const char* filename, BNTransformResult result, const char* message); BINARYNINJACOREAPI bool BNTransformContextIsLeaf(BNTransformContext* context); BINARYNINJACOREAPI bool BNTransformContextIsRoot(BNTransformContext* context); BINARYNINJACOREAPI char** BNTransformContextGetAvailableFiles(BNTransformContext* context, size_t* count); @@ -4690,6 +4703,7 @@ extern "C" BINARYNINJACOREAPI BNBinaryView* BNTransformSessionGetCurrentView(BNTransformSession* session); BINARYNINJACOREAPI BNTransformContext* BNTransformSessionGetRootContext(BNTransformSession* session); BINARYNINJACOREAPI BNTransformContext* BNTransformSessionGetCurrentContext(BNTransformSession* session); + BINARYNINJACOREAPI bool BNTransformSessionProcessFrom(BNTransformSession* session, BNTransformContext* context); BINARYNINJACOREAPI bool BNTransformSessionProcess(BNTransformSession* session); BINARYNINJACOREAPI bool BNTransformSessionHasAnyStages(BNTransformSession* session); BINARYNINJACOREAPI bool BNTransformSessionHasSinglePath(BNTransformSession* session); diff --git a/transformcontext.cpp b/transformcontext.cpp index 5bddda80..181d3c79 100644 --- a/transformcontext.cpp +++ b/transformcontext.cpp @@ -15,27 +15,82 @@ TransformContext::~TransformContext() } -string TransformContext::GetTransformName() const +Ref<BinaryView> TransformContext::GetInput() const { - char* name = BNTransformContextGetTransformName(m_object); + return new BinaryView(BNTransformContextGetInput(m_object)); +} + + +string TransformContext::GetFileName() const +{ + char* name = BNTransformContextGetFileName(m_object); string result = name; BNFreeString(name); return result; } -string TransformContext::GetFileName() const +string TransformContext::GetTransformName() const { - char* name = BNTransformContextGetFileName(m_object); + char* name = BNTransformContextGetTransformName(m_object); string result = name; BNFreeString(name); return result; } -Ref<BinaryView> TransformContext::GetInput() const +void TransformContext::SetTransformParameters(const map<string, DataBuffer>& params) { - return new BinaryView(BNTransformContextGetInput(m_object)); + BNTransformParameter* list = new BNTransformParameter[params.size()]; + size_t idx = 0; + for (const auto& param : params) + { + list[idx].name = param.first.c_str(); + list[idx].value = param.second.GetBufferObject(); + idx++; + } + + BNTransformContextSetTransformParameters(m_object, list, params.size()); + delete[] list; +} + + +void TransformContext::SetTransformParameter(const string& name, const DataBuffer& data) +{ + BNTransformContextSetTransformParameter(m_object, name.c_str(), data.GetBufferObject()); +} + + +bool TransformContext::HasTransformParameter(const string& name) const +{ + return BNTransformContextHasTransformParameter(m_object, name.c_str()); +} + + +void TransformContext::ClearTransformParameter(const string& name) +{ + BNTransformContextClearTransformParameter(m_object, name.c_str()); +} + + +string TransformContext::GetExtractionMessage() const +{ + char* message = BNTransformContextGetExtractionMessage(m_object); + string result = message; + BNFreeString(message); + return result; +} + + +BNTransformResult TransformContext::GetExtractionResult() const +{ + return BNTransformContextGetExtractionResult(m_object); +} + + +BNTransformResult TransformContext::GetTransformResult() const +{ + return BNTransformContextGetTransformResult(m_object); } @@ -85,9 +140,9 @@ Ref<TransformContext> TransformContext::GetChild(const string& filename) const } -Ref<TransformContext> TransformContext::CreateChild(const DataBuffer& data, const string& filename) +Ref<TransformContext> TransformContext::SetChild(const DataBuffer& data, const string& filename, BNTransformResult result, const std::string& message) { - BNTransformContext* child = BNTransformContextCreateChild(m_object, data.GetBufferObject(), filename.c_str()); + BNTransformContext* child = BNTransformContextSetChild(m_object, data.GetBufferObject(), filename.c_str(), result, message.c_str()); if (!child) return nullptr; return new TransformContext(child); diff --git a/transformsession.cpp b/transformsession.cpp index e839efb8..0f10f067 100644 --- a/transformsession.cpp +++ b/transformsession.cpp @@ -57,6 +57,12 @@ Ref<TransformContext> TransformSession::GetCurrentContext() const } +bool TransformSession::ProcessFrom(Ref<TransformContext> context) +{ + return BNTransformSessionProcessFrom(m_object, context->GetObject()); +} + + bool TransformSession::Process() { return BNTransformSessionProcess(m_object); diff --git a/ui/containerbrowser.h b/ui/containerbrowser.h index 08e04b2b..515a2836 100644 --- a/ui/containerbrowser.h +++ b/ui/containerbrowser.h @@ -19,12 +19,31 @@ class ContainerTreeModel : public QAbstractItemModel { Q_OBJECT + struct Node + { + QString displayName; // GetFileName() (or synthesized for root) + QString type; // GetTransformName() or "Leaf"/"Root" + QString breadcrumb; // human-readable path "a ▸ b ▸ c" + QStringList pathSegments; // list of filenames from root to this node + QString size; + TransformContextRef ctx; + Node* parent = nullptr; + std::vector<std::unique_ptr<Node>> children; + }; + + TransformSessionRef m_session; + std::unique_ptr<Node> m_root; + QLocale m_locale; + + const Node* nodeFromIndex(const QModelIndex& index) const; + static QString joinBreadcrumb(const QStringList& segments); + void createChildren(Node* parentNode, const std::vector<TransformContextRef>& children, const QStringList& parentSegments = {}); + public: enum Columns { ColName, ColType, ColSize, ColPath, ColCount }; - explicit ContainerTreeModel(TransformSessionRef session, QObject* parent = nullptr); + ContainerTreeModel(TransformSessionRef session, QObject* parent = nullptr); - // QAbstractItemModel interface int columnCount(const QModelIndex& parent = {}) const override; QModelIndex index(int row, int column, const QModelIndex& parent = {}) const override; QModelIndex parent(const QModelIndex& child) const override; @@ -33,33 +52,12 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role) const override; Qt::ItemFlags flags(const QModelIndex& index) const override; - // Public helpers for the dialog - bool isLeaf(const QModelIndex& index) const; + QString getDisplayName(const QModelIndex& index) const; + TransformContextRef getTransformContext(const QModelIndex& index) const; + QStringList pathFor(const QModelIndex& index) const; void selectNode(const QModelIndex& index); void rebuild(); - -private: - struct Node - { - QString displayName; // GetFileName() (or synthesized for root) - QString type; // GetTransformName() or "Leaf"/"Root" - QString breadcrumb; // human-readable path "a ▸ b ▸ c" - QStringList pathSegments; // list of filenames from root to this node - quint64 size = 0; // not exposed (kept for future metadata) - bool isLeaf = false; - bool selectable = true; // we allow selection only on leaves - TransformContextRef ctx; - Node* parent = nullptr; - std::vector<std::unique_ptr<Node>> children; - }; - - const Node* nodeFromIndex(const QModelIndex& index) const; - static QString joinBreadcrumb(const QStringList& segments); - void buildChildren(Node* parentNode, const TransformContextRef& ctx, const QStringList& parentSegments); - - TransformSessionRef m_session; - std::unique_ptr<Node> m_root; }; @@ -87,15 +85,20 @@ class BINARYNINJAUIAPI ContainerBrowser : public QDialog QTreeView* m_tree = nullptr; QPlainTextEdit* m_preview = nullptr; QLabel* m_status = nullptr; + QLabel* m_extractionStatus = nullptr; QDialogButtonBox* m_buttons = nullptr; AllColumnsFilterProxyModel* m_proxy = nullptr; + QStringList m_pendingSelectionPath; QStringList m_selectedPaths; void connectSignals(); - void loadRoot(); void updatePreviewForIndex(const QModelIndex& proxyIndex); + bool requiresPassword(TransformContextRef context); + void promptForPassword(TransformContextRef context, bool tryCachedPassword = false); + void showContextMenu(const QPoint& position); static QString toHexDump(const QByteArray& data, int bytesPerLine = 16); + QModelIndex findNodeByPath(const QStringList& path); public: ContainerBrowser(TransformSessionRef session, QWidget* parent = nullptr); diff --git a/ui/passworddialog.h b/ui/passworddialog.h new file mode 100644 index 00000000..9f1f01b4 --- /dev/null +++ b/ui/passworddialog.h @@ -0,0 +1,34 @@ +#pragma once + +#include <QDialog> +#include <QVBoxLayout> +#include <QHBoxLayout> +#include <QLabel> +#include <QPushButton> +#include <QCheckBox> +#include <QDialogButtonBox> +#include "uitypes.h" +#include "passwordedit.h" + + +class BINARYNINJAUIAPI PasswordDialog : public QDialog +{ + Q_OBJECT + + PasswordEdit* m_passwordEdit = nullptr; + QDialogButtonBox* m_buttons = nullptr; + QCheckBox* m_saveCheckBox = nullptr; + +public: + PasswordDialog(QWidget* parent, const QString& resource, bool showSaveOption = false); + + QString password() const; + bool shouldSavePassword() const; + void notifyInvalid(); + +signals: + void validate(const QString& password, bool shouldSave); + +private slots: + void onTextChanged(); +}; diff --git a/ui/passwordedit.h b/ui/passwordedit.h index 7c34c49e..f919803b 100644 --- a/ui/passwordedit.h +++ b/ui/passwordedit.h @@ -5,9 +5,11 @@ class BINARYNINJAUIAPI PasswordEdit: public QLineEdit { + Q_OBJECT + public: PasswordEdit(QWidget* parent = nullptr); - virtual void focusInEvent(QFocusEvent* e) override; - virtual void focusOutEvent(QFocusEvent* e) override; +private slots: + void showContextMenu(const QPoint& pos); }; diff --git a/view/kernelcache/core/transformers/KernelCacheTransforms.cpp b/view/kernelcache/core/transformers/KernelCacheTransforms.cpp index be06ad9e..9e7f97ff 100644 --- a/view/kernelcache/core/transformers/KernelCacheTransforms.cpp +++ b/view/kernelcache/core/transformers/KernelCacheTransforms.cpp @@ -66,7 +66,12 @@ public: filename += std::string((const char*)payload.version.data, payload.version.length); } - context->CreateChild(DataBuffer(payload.payload.data, payload.payload.length), filename); + if (payload.keybag.data && payload.keybag.length) + { + LogWarn("IMG4 payload contains keybag, which is not currently supported."); + } + + context->SetChild(DataBuffer(payload.payload.data, payload.payload.length), filename); return true; } |
