1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
use log::LevelFilter;
use binaryninja::binaryview::{BinaryView, BinaryViewExt};
use binaryninja::command::{Command, FunctionCommand};
use binaryninja::function::Function;
use binaryninja::rc::Ref;
use binaryninja::tags::TagType;
use warp::signature::function::Function as WarpFunction;
use crate::build_function;
use crate::cache::{ViewID, FUNCTION_CACHE, GUID_CACHE};
use crate::convert::{to_bn_symbol_at_address, to_bn_type};
use crate::matcher::{PlatformID, PLAT_MATCHER_CACHE};
mod apply;
mod copy;
mod create;
mod find;
mod types;
mod workflow;
// TODO: This icon is a little much
const TAG_ICON: &str = "🌏";
const TAG_NAME: &str = "WARP";
fn get_warp_tag_type(view: &BinaryView) -> Ref<TagType> {
view.get_tag_type(TAG_NAME)
.unwrap_or_else(|| view.create_tag_type(TAG_NAME, TAG_ICON))
}
// What happens to the function when it is matched.
// TODO: add user: bool
// TODO: Rename to markup_function or something.
pub fn on_matched_function(function: &Function, matched: &WarpFunction) {
let view = function.view();
view.define_auto_symbol(&to_bn_symbol_at_address(
&view,
&matched.symbol,
function.symbol().address(),
));
function.set_auto_type(&to_bn_type(&function.arch(), &matched.ty));
// TODO: Add metadata. (both binja metadata and warp metadata)
function.add_tag(
&get_warp_tag_type(&view),
matched.guid.to_string(),
None,
true,
None,
);
}
struct DebugFunction;
impl FunctionCommand for DebugFunction {
fn action(&self, _view: &BinaryView, func: &Function) {
if let Ok(llil) = func.low_level_il() {
log::info!("{:#?}", build_function(func, &llil));
}
}
fn valid(&self, _view: &BinaryView, _func: &Function) -> bool {
true
}
}
struct DebugCache;
impl Command for DebugCache {
fn action(&self, view: &BinaryView) {
let function_cache = FUNCTION_CACHE.get_or_init(Default::default);
let view_id = ViewID::from(view);
if let Some(cache) = function_cache.get(&view_id) {
log::info!("View functions: {}", cache.cache.len());
}
let function_guid_cache = GUID_CACHE.get_or_init(Default::default);
if let Some(cache) = function_guid_cache.get(&view_id) {
log::info!("View function guids: {}", cache.cache.len());
}
let plat_cache = PLAT_MATCHER_CACHE.get_or_init(Default::default);
if let Some(plat) = view.default_platform() {
let platform_id = PlatformID::from(plat);
if let Some(cache) = plat_cache.get(&platform_id) {
log::info!("Platform functions: {}", cache.functions.len());
log::info!("Platform types: {}", cache.types.len());
log::info!(
"Platform matched functions: {}",
cache.matched_functions.len()
);
}
}
}
fn valid(&self, _view: &BinaryView) -> bool {
true
}
}
#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CorePluginInit() -> bool {
binaryninja::logger::init(LevelFilter::Debug).unwrap();
workflow::insert_matcher_workflow();
binaryninja::command::register(
"WARP\\Apply Signature File Types",
"Load all types from a signature file and ignore functions",
types::LoadTypesCommand {},
);
binaryninja::command::register(
"WARP\\Debug Cache",
"Debug cache sizes... because...",
DebugCache {},
);
binaryninja::command::register_for_function(
"WARP\\Debug Signature",
"Print the entire signature for the function",
DebugFunction {},
);
binaryninja::command::register_for_function(
"WARP\\Copy Pattern",
"Copy the computed pattern for the function",
copy::CopyFunctionGUID {},
);
binaryninja::command::register(
"WARP\\Find Function From GUID",
"Locate the function in the view using a GUID",
find::FindFunctionFromGUID {},
);
binaryninja::command::register(
"WARP\\Generate Signature File",
"Generates a signature file containing all binary view functions",
create::CreateSignatureFile {},
);
binaryninja::command::register(
"WARP\\Apply Signature File",
"Applies a signature file to the current view",
apply::ApplySignatureFile {},
);
true
}
|