Skip to content

Commit 81d4b29

Browse files
committed
WARP 1.0
- Added FFI - Added a sidebar to the UI - Added project, directory and archive processing - Added generic `Container` interface for extensible stores of WARP data - Fixed type references being constructed and pulled incorrectly - Added HTML, Markdown and JSON report generation - Made the WARP information added as an analysis activity - Flattened the signatures directory, the target information is stored in the file now - Matched function information is stored as function metadata in the database to reliably persist, alongside the function GUID - Split the matching out from the application, allowing you to match on a given function without applying it - Added more/better tests - Added support for binaries with multiple architectures, the functions are now also queried based off the Target, see WARP spec for more details - Greatly improved support for RISC architectures, see WARP spec for more details - Greatly improved UX when loading files after the fact, will now sanely rerun the matcher - Omitted the function type if not a user type, this greatly reduces file size - Improved support for functions that reference a page aligned base pointer, see WARP spec for more details - Removed some extra cache structures that were causing erroneous behavior - Fixed edge-case in LLIL traversal missing some constant pointers, this was a bug in the Rust bindings - Added support for function comments - Made long running tasks, such as generating, matching and loading signatures, cancellable where possible - Made function constraints more versatile, allowing for easy extensions in the future, see WARP spec for details - Added options to signature generation, such as what data to store, and whether to compress the data or not - Made all long running tasks prompt the user for required information before the task starts, allowing users to "set it and forget it" and not have to baby sit the finalization of the task - Myriad of other changes to the actual WARP format that impact performance, file size and general feature set, see https://github.com/Vector35/warp for more details
1 parent ea6aae4 commit 81d4b29

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+8444
-3086
lines changed

plugins/dwarf/dwarfdump/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use binaryninja::{
2020
};
2121
use dwarfreader::is_valid;
2222

23+
use binaryninja::binary_view::StringType;
2324
use gimli::{
2425
AttributeValue::{Encoding, Flag, UnitRef},
2526
// BigEndian,
@@ -32,7 +33,6 @@ use gimli::{
3233
Unit,
3334
UnitSectionOffset,
3435
};
35-
use binaryninja::binary_view::StringType;
3636

3737
static PADDING: [&str; 23] = [
3838
"",

plugins/warp/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ file(GLOB_RECURSE PLUGIN_SOURCES CONFIGURE_DEPENDS
2121
${PROJECT_SOURCE_DIR}/Cargo.toml
2222
${PROJECT_SOURCE_DIR}/src/*.rs)
2323

24+
# Add API library.
25+
add_subdirectory(api)
26+
# Add UI plugin.
27+
if(NOT HEADLESS)
28+
add_subdirectory(ui)
29+
endif()
30+
2431
if(CMAKE_BUILD_TYPE MATCHES Debug)
2532
set(TARGET_DIR ${PROJECT_BINARY_DIR}/target/debug)
2633
set(CARGO_OPTS --target-dir=${PROJECT_BINARY_DIR}/target)

plugins/warp/Cargo.toml

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,31 @@ crate-type = ["lib", "cdylib"]
1010
[dependencies]
1111
binaryninja = { workspace = true, features = ["rayon"] }
1212
binaryninjacore-sys.workspace = true
13-
warp = { git = "https://github.com/Vector35/warp/", rev = "0ee5a6f" }
13+
warp = { git = "https://github.com/Vector35/warp/", branch = "next" }
1414
log = "0.4"
15-
arboard = "3.4"
15+
itertools = "0.14.0"
16+
dashmap = { version = "6.1", features = ["rayon"]}
1617
rayon = "1.10"
17-
dashmap = "6.1"
18+
arboard = "3.4"
1819
walkdir = "2.5"
19-
rfd = "0.15"
20+
serde = { version = "1.0", features = ["derive"] }
2021
serde_json = "1.0"
22+
uuid = { version = "1.12.0", features = ["v4"] }
23+
thiserror = "2.0"
24+
ar = { git = "https://github.com/mdsteele/rust-ar" }
25+
tempdir = "0.3.7"
26+
regex = "1.11"
2127

22-
# For sigem
23-
env_logger = { version = "0.11", optional = true }
24-
clap = { version = "4.5", features = ["derive"], optional = true }
25-
ar = { git = "https://github.com/mdsteele/rust-ar", optional = true }
26-
tempdir = { version = "0.3.7", optional = true }
28+
# For reports
29+
minijinja = "2.10.2"
30+
minijinja-embed = "2.10.2"
2731

28-
[dev-dependencies]
29-
criterion = "0.5.1"
30-
insta = { version = "1.38.0", features = ["yaml"] }
32+
[build-dependencies]
33+
minijinja-embed = "2.10.2"
3134

32-
[features]
33-
default = ["sigem"]
34-
sigem = ["env_logger", "clap", "ar", "tempdir"]
35-
36-
[[bin]]
37-
name = "sigem"
38-
required-features = ["sigem"]
35+
[dev-dependencies]
36+
criterion = "0.6"
37+
insta = { version = "1.42", features = ["yaml"] }
3938

4039
[[bench]]
4140
name = "guid"

plugins/warp/api/CMakeLists.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
2+
3+
project(warp_api CXX C)
4+
5+
add_library(warp_api STATIC warp.cpp warp.h warpcore.h)
6+
target_compile_definitions(warp_api PRIVATE ${COMPILE_DEFS})
7+
target_include_directories(warp_api PUBLIC ${PROJECT_SOURCE_DIR})
8+
9+
if (NOT BN_API_BUILD_EXAMPLES AND NOT BN_INTERNAL_BUILD)
10+
# Out-of-tree build
11+
find_path(
12+
BN_API_PATH
13+
NAMES binaryninjaapi.h
14+
HINTS ../.. binaryninjaapi $ENV{BN_API_PATH}
15+
REQUIRED
16+
)
17+
add_subdirectory(${BN_API_PATH} api)
18+
endif()
19+
20+
target_link_libraries(warp_api binaryninjaui)
21+
22+
# Link to the warp plugin.
23+
# TODO: Need to make this less scuffed, but this will do for now.
24+
if (APPLE)
25+
target_link_libraries(${PROJECT_NAME} ${BN_CORE_PLUGIN_DIR}/libwarp_ninja.dylib)
26+
elseif (UNIX)
27+
target_link_libraries(${PROJECT_NAME} ${BN_CORE_PLUGIN_DIR}/libwarp_ninja.so)
28+
else()
29+
target_link_libraries(${PROJECT_NAME} ${BN_CORE_PLUGIN_DIR}/warp_ninja.dll)
30+
endif()
31+
32+
set_target_properties(warp_api PROPERTIES
33+
CXX_STANDARD 17
34+
CXX_VISIBILITY_PRESET hidden
35+
CXX_STANDARD_REQUIRED ON
36+
VISIBILITY_INLINES_HIDDEN ON
37+
POSITION_INDEPENDENT_CODE ON
38+
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/out)

plugins/warp/api/warp.cpp

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
#include "warpcore.h"
2+
#include "warp.h"
3+
4+
using namespace Warp;
5+
6+
std::string UUID::ToString() const
7+
{
8+
char *str = BNWARPUUIDGetString(&uuid);
9+
std::string result = str;
10+
BNFreeString(str);
11+
return result;
12+
}
13+
14+
Target::Target(BNWARPTarget *target)
15+
{
16+
m_object = target;
17+
}
18+
19+
Ref<Target> Target::FromPlatform(const BinaryNinja::Platform &platform)
20+
{
21+
BNWARPTarget *result = BNWARPGetTarget(platform.m_object);
22+
if (!result)
23+
return nullptr;
24+
return new Target(result);
25+
}
26+
27+
Constraint::Constraint(BNWARPConstraint *constraint)
28+
{
29+
m_object = constraint;
30+
}
31+
32+
ConstraintGUID Constraint::GetGUID() const
33+
{
34+
return BNWARPConstraintGetGUID(m_object);
35+
}
36+
37+
std::optional<int64_t> Constraint::GetOffset() const
38+
{
39+
const int64_t offset = BNWARPConstraintGetOffset(m_object);
40+
if (offset == INT64_MAX)
41+
return std::nullopt;
42+
return offset;
43+
}
44+
45+
Function::Function(BNWARPFunction *function)
46+
{
47+
m_object = function;
48+
}
49+
50+
FunctionGUID Function::GetGUID() const
51+
{
52+
return BNWARPFunctionGetGUID(m_object);
53+
}
54+
55+
BinaryNinja::Ref<BinaryNinja::Symbol> Function::GetSymbol(const BinaryNinja::Function &function) const
56+
{
57+
BNSymbol *symbol = BNWARPFunctionGetSymbol(m_object, function.m_object);
58+
return new BinaryNinja::Symbol(symbol);
59+
}
60+
61+
BinaryNinja::Ref<BinaryNinja::Type> Function::GetType(const BinaryNinja::Function &function) const
62+
{
63+
BNType *type = BNWARPFunctionGetType(m_object, function.m_object);
64+
return new BinaryNinja::Type(type);
65+
}
66+
67+
std::vector<Ref<Constraint> > Function::GetConstraints() const
68+
{
69+
size_t count;
70+
BNWARPConstraint **constraints = BNWARPFunctionGetConstraints(m_object, &count);
71+
std::vector<Ref<Constraint> > result;
72+
result.reserve(count);
73+
for (int i = 0; i < count; i++)
74+
result.push_back(new Constraint(BNWARPNewConstraintReference(constraints[i])));
75+
BNWARPFreeConstraintList(constraints, count);
76+
return result;
77+
}
78+
79+
Ref<Function> Function::Get(const BinaryNinja::Function &function)
80+
{
81+
BNWARPFunction *result = BNWARPGetFunction(function.m_object);
82+
if (!result)
83+
return nullptr;
84+
return new Function(result);
85+
}
86+
87+
Ref<Function> Function::GetMatched(const BinaryNinja::Function &function)
88+
{
89+
BNWARPFunction *result = BNWARPGetMatchedFunction(function.m_object);
90+
if (!result)
91+
return nullptr;
92+
return new Function(result);
93+
}
94+
95+
void Function::Apply(const BinaryNinja::Function &function) const
96+
{
97+
BNWARPFunctionApply(m_object, function.m_object);
98+
}
99+
100+
Container::Container(BNWARPContainer *container)
101+
{
102+
m_object = container;
103+
}
104+
105+
std::vector<Ref<Container> > Container::All(const BinaryNinja::BinaryView &view)
106+
{
107+
size_t count;
108+
BNWARPContainer **containers = BNWARPGetContainers(view.m_object, &count);
109+
std::vector<Ref<Container> > result;
110+
result.reserve(count);
111+
for (int i = 0; i < count; i++)
112+
result.push_back(new Container(BNWARPNewContainerReference(containers[i])));
113+
BNWARPFreeContainerList(containers, count);
114+
return result;
115+
}
116+
117+
std::string Container::GetName() const
118+
{
119+
char *rawName = BNWARPContainerGetName(m_object);
120+
std::string name = rawName;
121+
BNFreeString(rawName);
122+
return name;
123+
}
124+
125+
std::optional<Source> Container::CreateSource(const std::string &sourcePath) const
126+
{
127+
Source source;
128+
if (!BNWARPContainerCreateSource(m_object, sourcePath.c_str(), source.RawMut()))
129+
return std::nullopt;
130+
return source;
131+
}
132+
133+
bool Container::CommitSource(const Source &source) const
134+
{
135+
return BNWARPContainerCommitSource(m_object, source.Raw());
136+
}
137+
138+
bool Container::IsSourceMutable(const Source &source) const
139+
{
140+
return BNWARPContainerIsSourceMutable(m_object, source.Raw());
141+
}
142+
143+
std::optional<std::string> Container::SourcePath(const Source &source) const
144+
{
145+
char *rawPath = BNWARPContainerGetSourcePath(m_object, source.Raw());
146+
if (!rawPath)
147+
return std::nullopt;
148+
std::string path = rawPath;
149+
BNFreeString(rawPath);
150+
return path;
151+
}
152+
153+
bool Container::AddFunctions(const Source &source, const std::vector<Ref<Function> > &functions) const
154+
{
155+
size_t count = functions.size();
156+
BNWARPFunction **apiFunctions = new BNWARPFunction *[count];
157+
for (size_t i = 0; i < count; i++)
158+
apiFunctions[i] = functions[i]->m_object;
159+
const bool result = BNWARPContainerAddFunctions(m_object, source.Raw(), apiFunctions, count);
160+
delete[] apiFunctions;
161+
return result;
162+
}
163+
164+
bool Container::AddTypes(const BinaryNinja::BinaryView &view, const Source &source,
165+
const std::vector<BinaryNinja::Ref<BinaryNinja::Type> > &types) const
166+
{
167+
size_t count = types.size();
168+
BNType **apiTypes = new BNType *[count];
169+
for (size_t i = 0; i < count; i++)
170+
apiTypes[i] = types[i]->m_object;
171+
const bool result = BNWARPContainerAddTypes(view.m_object, m_object, source.Raw(), apiTypes, count);
172+
delete[] apiTypes;
173+
return result;
174+
}
175+
176+
std::vector<Source> Container::GetSourcesWithFunctionGUID(const Target& target, const FunctionGUID &guid) const
177+
{
178+
size_t count;
179+
BNWARPSource *sources = BNWARPContainerGetSourcesWithFunctionGUID(m_object, target.m_object, guid.Raw(), &count);
180+
std::vector<Source> result;
181+
result.reserve(count);
182+
for (int i = 0; i < count; i++)
183+
result.emplace_back(sources[i]);
184+
BNWARPFreeUUIDList(sources, count);
185+
return result;
186+
}
187+
188+
std::vector<Source> Container::GetSourcesWithTypeGUID(const TypeGUID &guid) const
189+
{
190+
size_t count;
191+
BNWARPSource *sources = BNWARPContainerGetSourcesWithTypeGUID(m_object, guid.Raw(), &count);
192+
std::vector<Source> result;
193+
result.reserve(count);
194+
for (int i = 0; i < count; i++)
195+
result.emplace_back(sources[i]);
196+
BNWARPFreeUUIDList(sources, count);
197+
return result;
198+
}
199+
200+
std::vector<Ref<Function> > Container::GetFunctionsWithGUID(const Target& target, const Source &source, const FunctionGUID &guid) const
201+
{
202+
size_t count;
203+
BNWARPFunction **functions = BNWARPContainerGetFunctionsWithGUID(m_object, target.m_object, source.Raw(), guid.Raw(), &count);
204+
std::vector<Ref<Function> > result;
205+
result.reserve(count);
206+
for (int i = 0; i < count; i++)
207+
result.push_back(new Function(BNWARPNewFunctionReference(functions[i])));
208+
BNWARPFreeFunctionList(functions, count);
209+
return result;
210+
}
211+
212+
BinaryNinja::Ref<BinaryNinja::Type> Container::GetTypeWithGUID(const BinaryNinja::Architecture &arch,
213+
const Source &source, const TypeGUID &guid) const
214+
{
215+
BNType *type = BNWARPContainerGetTypeWithGUID(arch.m_object, m_object, source.Raw(), guid.Raw());
216+
return new BinaryNinja::Type(type);
217+
}
218+
219+
std::vector<TypeGUID> Container::GetTypeGUIDsWithName(const Source &source, const std::string &name) const
220+
{
221+
size_t count;
222+
BNWARPTypeGUID *guids = BNWARPContainerGetTypeGUIDsWithName(m_object, source.Raw(), name.c_str(), &count);
223+
std::vector<TypeGUID> result;
224+
result.reserve(count);
225+
for (int i = 0; i < count; i++)
226+
result.emplace_back(guids[i]);
227+
BNWARPFreeUUIDList(guids, count);
228+
return result;
229+
}
230+
231+
std::optional<FunctionGUID> Warp::GetAnalysisFunctionGUID(const BinaryNinja::Function &function)
232+
{
233+
FunctionGUID guid;
234+
if (!BNWARPGetAnalysisFunctionGUID(function.m_object, guid.RawMut()))
235+
return std::nullopt;
236+
return guid;
237+
}
238+
239+
std::optional<BasicBlockGUID> Warp::GetBasicBlockGUID(const BinaryNinja::BasicBlock &basicBlock)
240+
{
241+
BasicBlockGUID guid;
242+
if (!BNWARPGetBasicBlockGUID(basicBlock.m_object, guid.RawMut()))
243+
return std::nullopt;
244+
return guid;
245+
}

0 commit comments

Comments
 (0)