Skip to content

Commit 6088be6

Browse files
author
0cyn
committed
Expose all version-specific info for extensions in API
1 parent 4e6453c commit 6088be6

7 files changed

Lines changed: 248 additions & 38 deletions

File tree

binaryninjaapi.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,31 +207,30 @@ string BinaryNinja::GetVersionString()
207207
}
208208

209209

210-
VersionInfo BinaryNinja::GetVersionInfo()
210+
static VersionInfo VersionInfoFromCoreStruct(const BNVersionInfo& result)
211211
{
212-
BNVersionInfo result = BNGetVersionInfo();
213212
VersionInfo info;
214213
info.major = result.major;
215214
info.minor = result.minor;
216215
info.build = result.build;
217-
info.channel = "";
218-
if (result.channel)
219-
info.channel = result.channel;
216+
info.channel = result.channel ? result.channel : "";
217+
return info;
218+
}
219+
220+
221+
VersionInfo BinaryNinja::GetVersionInfo()
222+
{
223+
BNVersionInfo result = BNGetVersionInfo();
224+
VersionInfo info = VersionInfoFromCoreStruct(result);
220225
BNFreeString(result.channel);
221226
return info;
222227
}
223228

224229

225-
VersionInfo ParseVersionString(const string &version)
230+
VersionInfo BinaryNinja::ParseVersionString(const string &version)
226231
{
227232
BNVersionInfo result = BNParseVersionString(version.c_str());
228-
VersionInfo info;
229-
info.major = result.major;
230-
info.minor = result.minor;
231-
info.build = result.build;
232-
info.channel = "";
233-
if (result.channel)
234-
info.channel = result.channel;
233+
VersionInfo info = VersionInfoFromCoreStruct(result);
235234
BNFreeString(result.channel);
236235
return info;
237236
}

binaryninjaapi.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,8 +1962,16 @@ namespace BinaryNinja {
19621962
{
19631963
char* smallerChan = BNAllocString(channel.c_str());
19641964
char* largerChan = BNAllocString(other.channel.c_str());
1965-
BNVersionInfo smaller = { major, minor, build, smallerChan };
1966-
BNVersionInfo larger = { other.major, other.minor, other.build, largerChan };
1965+
BNVersionInfo smaller = {};
1966+
smaller.major = major;
1967+
smaller.minor = minor;
1968+
smaller.build = build;
1969+
smaller.channel = smallerChan;
1970+
BNVersionInfo larger = {};
1971+
larger.major = other.major;
1972+
larger.minor = other.minor;
1973+
larger.build = other.build;
1974+
larger.channel = largerChan;
19671975
bool result = BNVersionLessThan(smaller, larger);
19681976
BNFreeString(smallerChan);
19691977
BNFreeString(largerChan);
@@ -19145,13 +19153,21 @@ namespace BinaryNinja {
1914519153

1914619154
struct ExtensionVersion
1914719155
{
19156+
struct PlatformInfo
19157+
{
19158+
std::string name;
19159+
std::string downloadUrl;
19160+
std::string untrackedDownloadUrl;
19161+
};
19162+
1914819163
std::string id;
1914919164
std::string version;
1915019165

1915119166
std::string longDescription;
1915219167
std::string changelog;
1915319168

1915419169
uint64_t minimumClientVersion;
19170+
std::vector<PlatformInfo> platforms;
1915519171
std::string created;
1915619172
};
1915719173

binaryninjacore.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,20 @@ extern "C"
354354
typedef struct BNStringRecognizer BNStringRecognizer;
355355
typedef struct BNCustomStringType BNCustomStringType;
356356

357+
typedef struct BNVersionInfo {
358+
uint32_t major;
359+
uint32_t minor;
360+
uint32_t build;
361+
char* channel;
362+
} BNVersionInfo;
363+
364+
typedef struct BNPluginVersionPlatform
365+
{
366+
char* name;
367+
char* downloadUrl;
368+
char* untrackedDownloadUrl;
369+
} BNPluginVersionPlatform;
370+
357371
typedef struct BNPluginVersion
358372
{
359373
char* id;
@@ -362,6 +376,8 @@ extern "C"
362376
char* changelog;
363377

364378
uint64_t minimumClientVersion;
379+
BNPluginVersionPlatform* platforms;
380+
size_t platformCount;
365381
char* created;
366382

367383
} BNPluginVersion;
@@ -2743,13 +2759,6 @@ extern "C"
27432759
char* latestVersion;
27442760
} BNUpdateChannel;
27452761

2746-
typedef struct BNVersionInfo {
2747-
uint32_t major;
2748-
uint32_t minor;
2749-
uint32_t build;
2750-
char* channel;
2751-
} BNVersionInfo;
2752-
27532762
typedef struct BNChangelogEntry {
27542763
BNVersionInfo version;
27552764
char* notes;

pluginmanager.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,37 @@ string Extension::GetDescription() const
7070
RETURN_STRING(BNPluginGetDescription(m_object));
7171
}
7272

73-
VersionInfo Extension::GetMinimumVersionInfo() const
73+
static VersionInfo ConvertVersionInfo(const BNVersionInfo& coreInfo)
7474
{
75-
auto coreInfo = BNPluginGetMinimumVersionInfo(m_object);
7675
VersionInfo result;
7776
result.major = coreInfo.major;
7877
result.minor = coreInfo.minor;
7978
result.build = coreInfo.build;
80-
result.channel = coreInfo.channel;
79+
result.channel = coreInfo.channel ? coreInfo.channel : "";
80+
return result;
81+
}
82+
83+
static ExtensionVersion::PlatformInfo ConvertVersionPlatform(const BNPluginVersionPlatform& corePlatform)
84+
{
85+
ExtensionVersion::PlatformInfo result;
86+
result.name = corePlatform.name ? corePlatform.name : "";
87+
result.downloadUrl = corePlatform.downloadUrl ? corePlatform.downloadUrl : "";
88+
result.untrackedDownloadUrl = corePlatform.untrackedDownloadUrl ? corePlatform.untrackedDownloadUrl : "";
89+
return result;
90+
}
91+
92+
VersionInfo Extension::GetMinimumVersionInfo() const
93+
{
94+
auto coreInfo = BNPluginGetMinimumVersionInfo(m_object);
95+
VersionInfo result = ConvertVersionInfo(coreInfo);
8196
BNFreeString(coreInfo.channel);
8297
return result;
8398
}
8499

85100
VersionInfo Extension::GetMaximumVersionInfo() const
86101
{
87102
auto coreInfo = BNPluginGetMaximumVersionInfo(m_object);
88-
VersionInfo result;
89-
result.major = coreInfo.major;
90-
result.minor = coreInfo.minor;
91-
result.build = coreInfo.build;
92-
result.channel = coreInfo.channel;
103+
VersionInfo result = ConvertVersionInfo(coreInfo);
93104
BNFreeString(coreInfo.channel);
94105
return result;
95106
}
@@ -146,6 +157,9 @@ std::vector<ExtensionVersion> Extension::GetVersions() const
146157
version.longDescription = versionsPtr[i].longDescription ? versionsPtr[i].longDescription : "";
147158
version.changelog = versionsPtr[i].changelog ? versionsPtr[i].changelog : "";
148159
version.minimumClientVersion = versionsPtr[i].minimumClientVersion;
160+
version.platforms.reserve(versionsPtr[i].platformCount);
161+
for (size_t j = 0; j < versionsPtr[i].platformCount; j++)
162+
version.platforms.push_back(ConvertVersionPlatform(versionsPtr[i].platforms[j]));
149163
version.created = versionsPtr[i].created ? versionsPtr[i].created : "";
150164
versions.push_back(version);
151165
}
@@ -163,6 +177,9 @@ ExtensionVersion Extension::GetCurrentVersion() const
163177
version.longDescription = currentVersion.longDescription ? currentVersion.longDescription : "";
164178
version.changelog = currentVersion.changelog ? currentVersion.changelog : "";
165179
version.minimumClientVersion = currentVersion.minimumClientVersion;
180+
version.platforms.reserve(currentVersion.platformCount);
181+
for (size_t i = 0; i < currentVersion.platformCount; i++)
182+
version.platforms.push_back(ConvertVersionPlatform(currentVersion.platforms[i]));
166183
version.created = currentVersion.created ? currentVersion.created : "";
167184
BNPluginFreeVersion(currentVersion);
168185
return version;

python/pluginmanager.py

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import ctypes
2222
import json
23+
from dataclasses import dataclass
2324
from datetime import datetime, date
2425
from typing import List, Dict, Optional
2526

@@ -29,6 +30,24 @@
2930
from .enums import PluginType
3031

3132

33+
@dataclass(frozen=True)
34+
class ExtensionVersionPlatform:
35+
name: str
36+
download_url: str
37+
untracked_download_url: str
38+
39+
40+
@dataclass(frozen=True)
41+
class ExtensionVersion:
42+
id: str
43+
version: str
44+
long_description: str
45+
changelog: str
46+
minimum_client_version: int
47+
platforms: List[ExtensionVersionPlatform]
48+
created: str
49+
50+
3251
class Extension:
3352
"""
3453
``Extension`` is mostly read-only, however you can install/uninstall enable/disable plugins. Extensions are
@@ -152,13 +171,23 @@ def minimum_version(self) -> int:
152171
def minimum_version_info(self) -> 'binaryninja.CoreVersionInfo':
153172
"""Minimum version info the plugin was tested on"""
154173
core_version_info = core.BNPluginGetMinimumVersionInfo(self.handle)
155-
return binaryninja.CoreVersionInfo(core_version_info.major, core_version_info.minor, core_version_info.build)
174+
return binaryninja.CoreVersionInfo(
175+
core_version_info.major,
176+
core_version_info.minor,
177+
core_version_info.build,
178+
core_version_info.channel or ""
179+
)
156180

157181
@property
158182
def maximum_version_info(self) -> 'binaryninja.CoreVersionInfo':
159183
"""Maximum version info the plugin will support"""
160184
core_version_info = core.BNPluginGetMaximumVersionInfo(self.handle)
161-
return binaryninja.CoreVersionInfo(core_version_info.major, core_version_info.minor, core_version_info.build)
185+
return binaryninja.CoreVersionInfo(
186+
core_version_info.major,
187+
core_version_info.minor,
188+
core_version_info.build,
189+
core_version_info.channel or ""
190+
)
162191

163192
@property
164193
def name(self) -> str:
@@ -206,14 +235,65 @@ def author(self) -> Optional[str]:
206235
@deprecation.deprecated(deprecated_in="5.3", details='Use :py:attr:`current_version` in combination with :py:attr:`versions` instead.')
207236
def version(self) -> Optional[str]:
208237
"""String version of the plugin"""
238+
return self.current_version.version
239+
240+
@property
241+
def current_version(self) -> ExtensionVersion:
242+
"""Current version metadata for the plugin"""
209243
version: core.BNPluginVersion = core.BNPluginGetCurrentVersion(self.handle)
210244
try:
211-
version_string = version.versionString
212-
except AttributeError:
213-
version_string = ""
245+
platforms = []
246+
for i in range(version.platformCount):
247+
platform = version.platforms[i]
248+
platforms.append(ExtensionVersionPlatform(
249+
name=platform.name or "",
250+
download_url=platform.downloadUrl or "",
251+
untracked_download_url=platform.untrackedDownloadUrl or ""
252+
))
253+
return ExtensionVersion(
254+
id=version.id or "",
255+
version=version.versionString or "",
256+
long_description=version.longDescription or "",
257+
changelog=version.changelog or "",
258+
minimum_client_version=version.minimumClientVersion,
259+
platforms=platforms,
260+
created=version.created or ""
261+
)
214262
finally:
215263
core.BNPluginFreeVersion(version)
216-
return version_string
264+
265+
@property
266+
def versions(self) -> List[ExtensionVersion]:
267+
"""Version metadata for all available plugin versions"""
268+
result = []
269+
count = ctypes.c_ulonglong(0)
270+
versions = core.BNPluginGetVersions(self.handle, count)
271+
try:
272+
if versions is None:
273+
return result
274+
for i in range(count.value):
275+
version = versions[i]
276+
platforms = []
277+
for j in range(version.platformCount):
278+
platform = version.platforms[j]
279+
platforms.append(ExtensionVersionPlatform(
280+
name=platform.name or "",
281+
download_url=platform.downloadUrl or "",
282+
untracked_download_url=platform.untrackedDownloadUrl or ""
283+
))
284+
result.append(ExtensionVersion(
285+
id=version.id or "",
286+
version=version.versionString or "",
287+
long_description=version.longDescription or "",
288+
changelog=version.changelog or "",
289+
minimum_client_version=version.minimumClientVersion,
290+
platforms=platforms,
291+
created=version.created or ""
292+
))
293+
return result
294+
finally:
295+
if versions is not None:
296+
core.BNFreePluginVersions(versions, count.value)
217297

218298
@property
219299
def install_platforms(self) -> List[str]:

rust/src/repository.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ use std::ptr::NonNull;
1111
use binaryninjacore_sys::*;
1212

1313
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
14-
use crate::repository::plugin::Extension;
1514
use crate::string::{BnString, IntoCStr};
1615

1716
pub use manager::RepositoryManager;
17+
pub use plugin::{Extension, ExtensionVersion, ExtensionVersionPlatform};
1818

1919
pub type PluginType = BNPluginType;
2020
pub type PluginStatus = BNPluginStatus;

0 commit comments

Comments
 (0)