summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h16
-rw-r--r--binaryninjacore.h32
-rw-r--r--transformcontext.cpp71
-rw-r--r--transformsession.cpp6
-rw-r--r--ui/containerbrowser.h57
-rw-r--r--ui/passworddialog.h34
-rw-r--r--ui/passwordedit.h6
-rw-r--r--view/kernelcache/core/transformers/KernelCacheTransforms.cpp7
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;
}