def _get_scopes(self): """Builds the scopes for this query.""" scopes = helpers.EFILTER_SCOPES.copy() scopes["timestamp"] = api.user_func( lambda x, **_: basic.UnixTimeStamp(value=x, session=self.session), arg_types=[float, int, long]) # This function is used to indicate that the string represents # a filename. This will cause the agent to upload it if the # user requested uploading files. # > select file(path.filename.name).filename.name from glob("/*") scopes["file"] = api.user_func( lambda x: common.FileInformation(session=self.session, filename=x), arg_types=[unicode, str]) return scopes
def _get_scopes(self): """Builds the scopes for this query.""" scopes = helpers.EFILTER_SCOPES.copy() scopes["timestamp"] = api.user_func( lambda x, **_: basic.UnixTimeStamp(value=x, session=self.session), arg_types=[float, int, long]) # This function is used to indicate that the string represents # a filename. This will cause the agent to upload it if the # user requested uploading files. # > select file(path.filename.name).filename.name from glob("/*") scopes["file"] = api.user_func( lambda x: common.FileInformation(session=self.session, filename=x), arg_types=[unicode, str]) return scopes
def main(): for description, query in QUERIES: print("# %s\n%s" % (description, query)) # We can find out what the EFILTER query will return by using the type # inference system. If it is a repeated value, we can render it in # multiple rows. result_type = api.infer(query, replacements=[CATALOG_PATH], libs=("stdcore", "stdio")) print("# Return type will be %s." % (result_type.__name__,)) # api.apply will give us the actual result of running the query, which # should be of the type we got above. results = api.apply(query, replacements=[CATALOG_PATH], allow_io=True, # We provide the top level variables in a 'vars' # argument. To bind 'parsec2ly' to the function of # the same name, we have to also wrap it in the # EFILTER user_func. This prevents EFILTER from # accidentally calling regular Python functions. vars={"parsec2ly": api.user_func(parsec2ly)}) # Because we don't know the cardinality of the query in 'query' we can # use 'getvalues' to always receive an iterator of results. This is just # a convenience function. for n, result in enumerate(api.getvalues(results)): print("%d - %r" % (n + 1, result)) print("\n\n")
def _prepare_efilter_scopes(self): """Create the callables which can be used in the efilter scopes.""" # Exported EFilter functions. These can be used within efilter # queries. For example select hex(cmd_address) from dis(0xfa8000895a32). def hex_function(value): """A Function to format the output as a hex string.""" if value == None: return return "%#x" % value def str_function(value): if value == None: return return utils.SmartUnicode(value) def int_function(value): if value == None: return return int(value) def noncase_search_function(regex, value): """Case insensitive regex search function.""" return bool(re.search(unicode(regex), unicode(value), re.I)) return dict( hex=api.user_func( hex_function, arg_types=[int], return_type=[str]), str=api.user_func( str_function, arg_types=[], return_type=[unicode]), int=api.user_func( int_function, arg_types=[], return_type=[int]), regex_search=api.user_func( noncase_search_function, arg_types=[unicode, unicode], return_type=[bool]), )
def _prepare_efilter_scopes(self): """Create the callables which can be used in the efilter scopes.""" # Exported EFilter functions. These can be used within efilter # queries. For example select hex(cmd_address) from dis(0xfa8000895a32). def hex_function(value): """A Function to format the output as a hex string.""" if value == None: return return "%#x" % value def str_function(value): if value == None: return return utils.SmartUnicode(value) def int_function(value): if value == None: return return int(value) def noncase_search_function(regex, value): """Case insensitive regex search function.""" return bool(re.search(unicode(regex), unicode(value), re.I)) return dict( hex=api.user_func(hex_function, arg_types=[int], return_type=[str]), str=api.user_func(str_function, arg_types=[], return_type=[unicode]), int=api.user_func(int_function, arg_types=[], return_type=[int]), regex_search=api.user_func(noncase_search_function, arg_types=[unicode, unicode], return_type=[bool]), )
def _prepare_efilter_scopes(self): """Create the callables which can be used in the efilter scopes.""" # Exported EFilter functions. These can be used within efilter # queries. For example select hex(cmd_address) from dis(0xfa8000895a32). def hex_function(value): """A Function to format the output as a hex string.""" return "%#x" % value return dict( hex=api.user_func( hex_function, arg_types=[int], return_type=[str]), )
def testUserFunc(self): with self.assertRaises(errors.EfilterKeyError): api.apply("my_func(1, 5)") def my_func(x, y): return x + y with self.assertRaises(NotImplementedError): api.apply("my_func(1, 5)", vars={"my_func": my_func}) # Need to define it as a user_func! result = api.apply("my_func(1, 5)", vars={"my_func": api.user_func(my_func)}) self.assertEqual(result, 6)
def testUserFunc(self): with self.assertRaises(errors.EfilterKeyError): api.apply("my_func(1, 5)") def my_func(x, y): return x + y with self.assertRaises(NotImplementedError): api.apply("my_func(1, 5)", vars={"my_func": my_func}) # Need to define it as a user_func! result = api.apply("my_func(1, 5)", vars={"my_func": api.user_func(my_func)}) self.assertEqual(result, 6)
def _get_scope(self): """Builds the scope for this query. We add some useful functions to be available to the query: timestamp(): Wrap an int or float in a UnixTimeStamp so it gets rendered properly. substr(): Allows a string to be substringed. file(): Marks a string as a file name. The Rekall Agent will then potentially upload this file. """ scope = helpers.EFILTER_SCOPES.copy() scope["timestamp"] = api.user_func( lambda x, **_: basic.UnixTimeStamp(value=x, session=self.session), arg_types=[float, int, long]) # This function is used to indicate that the string represents # a filename. This will cause the agent to upload it if the # user requested uploading files. # > select file(path.filename.name).filename.name from glob("/*") scope["file"] = api.scalar_function( lambda x: common.FileInformation(session=self.session, filename=x), arg_types=(string.IString,)) scope["substr"] = api.scalar_function( lambda x, start, end: utils.SmartUnicode(x)[int(start):int(end)], arg_types=(string.IString, number.INumber, number.INumber)) scope["hex"] = api.scalar_function( lambda x: hex(int(x)), arg_types=(number.INumber,)) scope["deref"] = api.scalar_function( lambda x: x.deref(), arg_types=(obj.Pointer,)) return scope
def main(): for description, query in QUERIES: print("# %s\n%s" % (description, query)) # api.apply will give us the actual result of running the query, which # should be of the type we got above. results = api.apply(query, replacements=[CATALOG_PATH], allow_io=True, # We provide the top level variables in a 'vars' # argument. To bind 'parsec2ly' to the function of # the same name, we have to also wrap it in the # EFILTER user_func. This prevents EFILTER from # accidentally calling regular Python functions. vars={"parsec2ly": api.user_func(parsec2ly)}) # Because we don't know the cardinality of the query in 'query' we can # use 'getvalues' to always receive an iterator of results. This is just # a convenience function. for n, result in enumerate(api.getvalues(results)): print("%d - %r" % (n + 1, result)) print("\n\n")
def substitute(pattern, repl, target): if target is None: return if isinstance(target, (list, tuple)): result = [] for item in target: result.append(substitute(pattern, repl, item)) return result else: return re.sub(pattern, repl, six.text_type(target), re.I) EFILTER_SCOPES = dict( hex=api.user_func(hex_function, arg_types=[int], return_type=[str]), str=api.user_func(str_function, arg_types=[], return_type=[str]), int=api.user_func(int_function, arg_types=[], return_type=[int]), regex_search=api.user_func(noncase_search_function, arg_types=[str, str], return_type=[bool]), concat=api.user_func(lambda *args: "".join(args)), sub=api.user_func(substitute), ) class GeneratorRunner(object): def __init__(self, cb): self.cb = cb def apply(self, args, kwargs):
def int_function(value): if value == None: return return int(value) def noncase_search_function(regex, value): """Case insensitive regex search function.""" return bool(re.search(unicode(regex), unicode(value), re.I)) EFILTER_SCOPES = dict( hex=api.user_func(hex_function, arg_types=[int], return_type=[str]), str=api.user_func(str_function, arg_types=[], return_type=[unicode]), int=api.user_func(int_function, arg_types=[], return_type=[int]), regex_search=api.user_func(noncase_search_function, arg_types=[unicode, unicode], return_type=[bool]), ) class GeneratorRunner(object): def __init__(self, cb): self.cb = cb def apply(self, args, kwargs): return repeated.lazy(functools.partial(self.cb, *args, **kwargs))
try: if re.search(pattern, target, re.I): return target except TypeError: pass def join(seperator, target): if isinstance(target, (list, tuple)): return seperator.join(target) return target EFILTER_SCOPES = dict( hex=api.user_func( hex_function, arg_types=[int], return_type=[str]), str=api.user_func( str_function, arg_types=[], return_type=[str]), int=api.user_func( int_function, arg_types=[], return_type=[int]), regex_search=api.user_func( noncase_search_function, arg_types=[str, str], return_type=[bool]), concat=api.user_func(lambda *args: "".join(args)), sub=api.user_func(substitute), re_filter=api.user_func(re_filter), join=api.user_func(join),