Skip to content

Commit 3cb441f

Browse files
committed
Sketch of FindInFunction API
1 parent e1efc28 commit 3cb441f

File tree

5 files changed

+269
-1
lines changed

5 files changed

+269
-1
lines changed

binaryninjaapi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7688,9 +7688,17 @@ namespace BinaryNinja {
76887688
const ProgressFunction& progress,
76897689
const std::function<bool(uint64_t addr, const std::string& match, const LinearDisassemblyLine& line)>&
76907690
matchCallback);
7691+
bool FindAllText(Function* func, const std::string& data, Ref<DisassemblySettings> settings,
7692+
BNFindFlag flags, const FunctionViewType& viewType,
7693+
const ProgressFunction& progress,
7694+
const std::function<bool(uint64_t addr, const std::string& match, const LinearDisassemblyLine& line)>&
7695+
matchCallback);
76917696
bool FindAllConstant(uint64_t start, uint64_t end, uint64_t constant, Ref<DisassemblySettings> settings,
76927697
const FunctionViewType& viewType, const ProgressFunction& progress,
76937698
const std::function<bool(uint64_t addr, const LinearDisassemblyLine& line)>& matchCallback);
7699+
bool FindAllConstant(Function* func, uint64_t constant, Ref<DisassemblySettings> settings,
7700+
const FunctionViewType& viewType, const ProgressFunction& progress,
7701+
const std::function<bool(uint64_t addr, const LinearDisassemblyLine& line)>& matchCallback);
76947702

76957703
std::string DetectSearchMode(const std::string& query);
76967704

binaryninjacore.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4686,10 +4686,18 @@ extern "C"
46864686
const char* data, BNDisassemblySettings* settings, BNFindFlag flags, BNFunctionViewType viewType, void* ctxt,
46874687
BNProgressFunction progress, void* matchCtxt,
46884688
bool (*matchCallback)(void* matchCtxt, uint64_t addr, const char* match, BNLinearDisassemblyLine* line));
4689+
BINARYNINJACOREAPI bool BNFindAllTextInFunctionWithProgress(BNFunction* func,
4690+
const char* data, BNDisassemblySettings* settings, BNFindFlag flags, BNFunctionViewType viewType, void* ctxt,
4691+
BNProgressFunction progress, void* matchCtxt,
4692+
bool (*matchCallback)(void* matchCtxt, uint64_t addr, const char* match, BNLinearDisassemblyLine* line));
46894693
BINARYNINJACOREAPI bool BNFindAllConstantWithProgress(BNBinaryView* view, uint64_t start, uint64_t end,
46904694
uint64_t constant, BNDisassemblySettings* settings, BNFunctionViewType viewType, void* ctxt,
46914695
BNProgressFunction progress, void* matchCtxt,
46924696
bool (*matchCallback)(void* matchCtxt, uint64_t addr, BNLinearDisassemblyLine* line));
4697+
BINARYNINJACOREAPI bool BNFindAllConstantInFunctionWithProgress(BNFunction* func,
4698+
uint64_t constant, BNDisassemblySettings* settings, BNFunctionViewType viewType, void* ctxt,
4699+
BNProgressFunction progress, void* matchCtxt,
4700+
bool (*matchCallback)(void* matchCtxt, uint64_t addr, BNLinearDisassemblyLine* line));
46934701

46944702
BINARYNINJACOREAPI bool BNSearch(BNBinaryView* view, const char* query, void* context, BNProgressFunction progressCallback, void* matchContext, bool (*callback)(void*, uint64_t, BNDataBuffer*));
46954703
BINARYNINJACOREAPI char* BNDetectSearchMode(const char* query);

binaryview.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5095,6 +5095,20 @@ bool BinaryView::FindAllText(uint64_t start, uint64_t end, const std::string& da
50955095
}
50965096

50975097

5098+
bool BinaryView::FindAllText(Function* func, const std::string& data, Ref<DisassemblySettings> settings,
5099+
BNFindFlag flags, const FunctionViewType& viewType, const ProgressFunction& progress,
5100+
const std::function<bool(uint64_t addr, const std::string& match, const LinearDisassemblyLine& line)>&
5101+
matchCallback)
5102+
{
5103+
ProgressContext fp;
5104+
fp.callback = progress;
5105+
MatchCallbackContextForText mc;
5106+
mc.func = matchCallback;
5107+
return BNFindAllTextInFunctionWithProgress(func->GetObject(), data.c_str(), settings->GetObject(), flags,
5108+
viewType.ToAPIObject(), &fp, ProgressCallback, &mc, MatchCallbackForText);
5109+
}
5110+
5111+
50985112
bool BinaryView::FindAllConstant(uint64_t start, uint64_t end, uint64_t constant, Ref<DisassemblySettings> settings,
50995113
const FunctionViewType& viewType, const ProgressFunction& progress,
51005114
const std::function<bool(uint64_t addr, const LinearDisassemblyLine& line)>& matchCallback)
@@ -5108,6 +5122,19 @@ bool BinaryView::FindAllConstant(uint64_t start, uint64_t end, uint64_t constant
51085122
}
51095123

51105124

5125+
bool BinaryView::FindAllConstant(Function* func, uint64_t constant, Ref<DisassemblySettings> settings,
5126+
const FunctionViewType& viewType, const ProgressFunction& progress,
5127+
const std::function<bool(uint64_t addr, const LinearDisassemblyLine& line)>& matchCallback)
5128+
{
5129+
ProgressContext fp;
5130+
fp.callback = progress;
5131+
MatchCallbackContextForConstant mc;
5132+
mc.func = matchCallback;
5133+
return BNFindAllConstantInFunctionWithProgress(func->GetObject(), constant, settings->GetObject(),
5134+
viewType.ToAPIObject(), &fp, ProgressCallback, &mc, MatchCallbackForConstant);
5135+
}
5136+
5137+
51115138
string BinaryView::DetectSearchMode(const string& query)
51125139
{
51135140
char* searchMode = BNDetectSearchMode(query.c_str());

python/binaryview.py

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10058,6 +10058,146 @@ def find_all_constant(
1005810058

1005910059
return self.QueueGenerator(t, results)
1006010060

10061+
@overload
10062+
def find_all_text_in_function(
10063+
self, func: '_function.Function', text: str, settings: Optional[_function.DisassemblySettings] = None,
10064+
flags=FindFlag.FindCaseSensitive, graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph,
10065+
progress_func=None, match_callback=None
10066+
) -> QueueGenerator: ...
10067+
10068+
@overload
10069+
def find_all_text_in_function(
10070+
self, func: '_function.Function', text: str, settings: Optional[_function.DisassemblySettings] = None,
10071+
flags=FindFlag.FindCaseSensitive, graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph,
10072+
progress_func=None, match_callback: TextMatchCallbackType = None
10073+
) -> bool: ...
10074+
10075+
def find_all_text_in_function(
10076+
self, func: '_function.Function', text: str, settings: Optional[_function.DisassemblySettings] = None,
10077+
flags=FindFlag.FindCaseSensitive, graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph,
10078+
progress_func=None, match_callback: Optional[TextMatchCallbackType] = None
10079+
) -> Union[QueueGenerator, bool]:
10080+
if not isinstance(func, _function.Function):
10081+
raise TypeError("func parameter is not Function type")
10082+
if settings is None:
10083+
settings = _function.DisassemblySettings()
10084+
settings.set_option(DisassemblyOption.ShowAddress, False)
10085+
settings.set_option(DisassemblyOption.ShowOpcode, False)
10086+
settings.set_option(DisassemblyOption.ShowVariableTypesWhenAssigned, True)
10087+
settings.set_option(DisassemblyOption.WaitForIL, True)
10088+
if not isinstance(settings, _function.DisassemblySettings):
10089+
raise TypeError("settings parameter is not DisassemblySettings type")
10090+
if not isinstance(flags, FindFlag):
10091+
raise TypeError('flag parameter must have type FindFlag')
10092+
graph_type = _function.FunctionViewType(graph_type)._to_core_struct()
10093+
10094+
if progress_func:
10095+
progress_func_obj = ctypes.CFUNCTYPE(
10096+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong
10097+
)(lambda ctxt, cur, total: progress_func(cur, total))
10098+
else:
10099+
progress_func_obj = ctypes.CFUNCTYPE(
10100+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong
10101+
)(lambda ctxt, cur, total: True)
10102+
10103+
if match_callback:
10104+
match_callback_obj = ctypes.CFUNCTYPE(
10105+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_char_p,
10106+
ctypes.POINTER(core.BNLinearDisassemblyLine)
10107+
)(
10108+
lambda ctxt, addr, match, line:
10109+
not match_callback(addr, core.pyNativeStr(match), self._LinearDisassemblyLine_convertor(line)) is False
10110+
)
10111+
10112+
return core.BNFindAllTextInFunctionWithProgress(
10113+
func.handle, text, settings.handle, flags, graph_type, None, progress_func_obj, None,
10114+
match_callback_obj
10115+
)
10116+
else:
10117+
results = queue.Queue()
10118+
match_callback_obj = ctypes.CFUNCTYPE(
10119+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_char_p,
10120+
ctypes.POINTER(core.BNLinearDisassemblyLine)
10121+
)(
10122+
lambda ctxt, addr, match, line: results.put((addr, core.pyNativeStr(match), self._LinearDisassemblyLine_convertor(line)))
10123+
or True
10124+
)
10125+
10126+
t = threading.Thread(
10127+
target=lambda: core.BNFindAllTextInFunctionWithProgress(
10128+
func.handle, text, settings.handle, flags, graph_type, None, progress_func_obj, None,
10129+
match_callback_obj
10130+
)
10131+
)
10132+
10133+
return self.QueueGenerator(t, results)
10134+
10135+
@overload
10136+
def find_all_constant_in_function(
10137+
self, func: '_function.Function', constant: int, settings: Optional[_function.DisassemblySettings] = None,
10138+
graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, progress_func: Optional[ProgressFuncType] = None,
10139+
match_callback: None = None
10140+
) -> QueueGenerator: ...
10141+
10142+
@overload
10143+
def find_all_constant_in_function(
10144+
self, func: '_function.Function', constant: int, settings: Optional[_function.DisassemblySettings] = None,
10145+
graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, progress_func: Optional[ProgressFuncType] = None,
10146+
match_callback: LineMatchCallbackType = None
10147+
) -> bool: ...
10148+
10149+
def find_all_constant_in_function(
10150+
self, func: '_function.Function', constant: int, settings: Optional[_function.DisassemblySettings] = None,
10151+
graph_type: _function.FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, progress_func: Optional[ProgressFuncType] = None,
10152+
match_callback: Optional[LineMatchCallbackType] = None
10153+
) -> Union[QueueGenerator, bool]:
10154+
if not isinstance(func, _function.Function):
10155+
raise TypeError("func parameter is not Function type")
10156+
if not isinstance(constant, int):
10157+
raise TypeError("constant parameter is not integral type")
10158+
if settings is None:
10159+
settings = _function.DisassemblySettings()
10160+
settings.set_option(DisassemblyOption.ShowAddress, False)
10161+
settings.set_option(DisassemblyOption.ShowOpcode, False)
10162+
settings.set_option(DisassemblyOption.ShowVariableTypesWhenAssigned, True)
10163+
settings.set_option(DisassemblyOption.WaitForIL, True)
10164+
if not isinstance(settings, _function.DisassemblySettings):
10165+
raise TypeError("settings parameter is not DisassemblySettings type")
10166+
graph_type = _function.FunctionViewType(graph_type)._to_core_struct()
10167+
10168+
if progress_func:
10169+
progress_func_obj = ctypes.CFUNCTYPE(
10170+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong
10171+
)(lambda ctxt, cur, total: progress_func(cur, total))
10172+
else:
10173+
progress_func_obj = ctypes.CFUNCTYPE(
10174+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong
10175+
)(lambda ctxt, cur, total: True)
10176+
10177+
if match_callback:
10178+
match_callback_obj = ctypes.CFUNCTYPE(
10179+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.POINTER(core.BNLinearDisassemblyLine)
10180+
)(lambda ctxt, addr, line: not match_callback(addr, self._LinearDisassemblyLine_convertor(line)) is False)
10181+
10182+
return core.BNFindAllConstantInFunctionWithProgress(
10183+
func.handle, constant, settings.handle, graph_type, None, progress_func_obj, None,
10184+
match_callback_obj
10185+
)
10186+
else:
10187+
results = queue.Queue()
10188+
match_callback_obj = ctypes.CFUNCTYPE(
10189+
ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.POINTER(core.BNLinearDisassemblyLine)
10190+
)(lambda ctxt, addr, line: results.put((addr, self._LinearDisassemblyLine_convertor(line))) or True)
10191+
10192+
t = threading.Thread(
10193+
target=lambda: core.BNFindAllConstantInFunctionWithProgress(
10194+
func.handle, constant, settings.handle, graph_type, None, progress_func_obj, None,
10195+
match_callback_obj
10196+
)
10197+
)
10198+
10199+
return self.QueueGenerator(t, results)
10200+
1006110201
def search(self, pattern: str, start: Optional[int] = None, end: Optional[int] = None, raw: bool = False, ignore_case: bool = False, overlap: bool = False, align: int = 1,
1006210202
limit: Optional[int] = None, progress_callback: Optional[ProgressFuncType] = None, match_callback: Optional[DataMatchCallbackType] = None) -> QueueGenerator:
1006310203
r"""

rust/src/binary_view.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ use crate::variable::DataVariable;
5656
use crate::workflow::Workflow;
5757
use crate::{Endianness, BN_FULL_CONFIDENCE};
5858
use std::collections::{BTreeMap, HashMap};
59-
use std::ffi::{c_char, c_void, CString};
59+
use std::ffi::{c_char, c_void, CStr, CString};
6060
use std::fmt::{Display, Formatter};
6161
use std::ops::Range;
6262
use std::path::{Path, PathBuf};
@@ -494,6 +494,91 @@ pub trait BinaryViewExt: BinaryViewBase {
494494
}
495495
}
496496

497+
fn find_all_text_in_function_with_opts<
498+
P: ProgressCallback,
499+
C: FnMut(u64, &str, &LinearDisassemblyLine) -> bool,
500+
>(
501+
&self,
502+
func: &Function,
503+
text: &str,
504+
disasm_settings: &DisassemblySettings,
505+
flag: FindFlag,
506+
view_type: FunctionViewType,
507+
mut on_match: C,
508+
mut progress: P,
509+
) -> bool {
510+
unsafe extern "C" fn cb_on_match<C: FnMut(u64, &str, &LinearDisassemblyLine) -> bool>(
511+
ctxt: *mut c_void,
512+
addr: u64,
513+
match_text: *const c_char,
514+
line: *mut BNLinearDisassemblyLine,
515+
) -> bool {
516+
let ctxt: &mut C = &mut *(ctxt as *mut C);
517+
let match_text = CStr::from_ptr(match_text).to_string_lossy().into_owned();
518+
let wrapped_line = LinearDisassemblyLine::from_raw(&*line);
519+
BNFreeLinearDisassemblyLines(line, 1);
520+
ctxt(addr, &match_text, &wrapped_line)
521+
}
522+
523+
let text = text.to_cstr();
524+
let raw_view_type = FunctionViewType::into_raw(view_type);
525+
let found = unsafe {
526+
BNFindAllTextInFunctionWithProgress(
527+
func.handle,
528+
text.as_ptr(),
529+
disasm_settings.handle,
530+
flag,
531+
raw_view_type,
532+
&mut progress as *mut P as *mut c_void,
533+
Some(P::cb_progress_callback),
534+
&mut on_match as *mut C as *mut c_void,
535+
Some(cb_on_match::<C>),
536+
)
537+
};
538+
FunctionViewType::free_raw(raw_view_type);
539+
found
540+
}
541+
542+
fn find_all_constant_in_function_with_opts<
543+
P: ProgressCallback,
544+
C: FnMut(u64, &LinearDisassemblyLine) -> bool,
545+
>(
546+
&self,
547+
func: &Function,
548+
constant: u64,
549+
disasm_settings: &DisassemblySettings,
550+
view_type: FunctionViewType,
551+
mut on_match: C,
552+
mut progress: P,
553+
) -> bool {
554+
unsafe extern "C" fn cb_on_match<C: FnMut(u64, &LinearDisassemblyLine) -> bool>(
555+
ctxt: *mut c_void,
556+
addr: u64,
557+
line: *mut BNLinearDisassemblyLine,
558+
) -> bool {
559+
let ctxt: &mut C = &mut *(ctxt as *mut C);
560+
let wrapped_line = LinearDisassemblyLine::from_raw(&*line);
561+
BNFreeLinearDisassemblyLines(line, 1);
562+
ctxt(addr, &wrapped_line)
563+
}
564+
565+
let raw_view_type = FunctionViewType::into_raw(view_type);
566+
let found = unsafe {
567+
BNFindAllConstantInFunctionWithProgress(
568+
func.handle,
569+
constant,
570+
disasm_settings.handle,
571+
raw_view_type,
572+
&mut progress as *mut P as *mut c_void,
573+
Some(P::cb_progress_callback),
574+
&mut on_match as *mut C as *mut c_void,
575+
Some(cb_on_match::<C>),
576+
)
577+
};
578+
FunctionViewType::free_raw(raw_view_type);
579+
found
580+
}
581+
497582
fn notify_data_written(&self, offset: u64, len: usize) {
498583
unsafe {
499584
BNNotifyDataWritten(self.as_ref().handle, offset, len);

0 commit comments

Comments
 (0)