volatilityfoundation / volatility3

Volatility 3.0 development
http://volatilityfoundation.org/
Other
2.73k stars 463 forks source link

Windows.pslist #440

Closed lprat closed 3 years ago

lprat commented 3 years ago

Describe the bug

$python3 /opt/volatility3/vol.py -vvvvvvv -f test.ram windows.pslist
Volatility 3 Framework 1.0.0
INFO     root        : Volatility plugins path: ['/opt/volatility3/volatility3/plugins', '/opt/volatility3/volatility3/framework/plugins']
INFO     root        : Volatility symbols path: ['/opt/volatility3/volatility3/symbols', '/opt/volatility3/volatility3/framework/symbols']
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/plugins, /opt/volatility3/volatility3/framework/plugins
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/automagic
Level 7  root        : Cache directory used: /root/.cache/volatility3
INFO     volatility3.framework.automagic: Detected a windows category plugin
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
INFO     volatility3.framework.automagic: Running automagic: ConstructionMagic
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList.primary
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList.nt_symbols
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework.automagic.construct_layers: Construction Exception occurred: Unexpected config value found: None
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
INFO     volatility3.framework.automagic: Running automagic: LayerStacker
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 7  volatility3.framework.layers.resources: Available URL handlers: HTTPErrorProcessor, HTTPDefaultErrorHandler, HTTPRedirectHandler, ProxyHandler, HTTPBasicAuthHandler, ProxyBasicAuthHandler, HTTPDigestAuthHandler, ProxyDigestAuthHandler, AbstractHTTPHandler, HTTPHandler, HTTPSHandler, HTTPCookieProcessor, UnknownHandler, FileHandler, FTPHandler, CacheFTPHandler, DataHandler, JarHandler
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using LimeStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using QemuStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using Elf64Stacker
Level 6  volatility3.framework.layers.elf: Exception: Bad magic 0x0 at file offset 0x0
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using WindowsCrashDumpStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using VmwareStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using WindowsIntelStacker
DEBUG    volatility3.framework.automagic.windows: DTB was found at: 0x1aa000
Level 8  volatility3.framework.automagic.stacker: Stacked IntelLayer using WindowsIntelStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using LimeStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using QemuStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using Elf64Stacker
Level 6  volatility3.framework.layers.elf: Exception: Offset 0x0 does not exist within the base layer
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using WindowsCrashDumpStacker
Level 8  volatility3.framework.automagic.stacker: Attempting to stack using VmwareStacker
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: IndexError - No configuration provided: plugins.PsList.primary.memory_layer
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.interfaces.configuration: TypeError - kernel_virtual_offset requirements only accept int type: None
Level 9  volatility3.framework.interfaces.configuration: TypeError - kernel_virtual_offset requirements only accept int type: None
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.interfaces.configuration: TypeError - kernel_banner requirements only accept str type: None
Level 9  volatility3.framework.interfaces.configuration: TypeError - kernel_banner requirements only accept str type: None
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList.nt_symbols
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 9  volatility3.framework.automagic.construct_layers: Failed on requirement: plugins.PsList
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
Level 6  volatility3.framework: Importing from the following paths: /opt/volatility3/volatility3/framework/layers
DEBUG    volatility3.framework.automagic.stacker: Stacked layers: ['IntelLayer', 'FileLayer']
INFO     volatility3.framework.automagic: Running automagic: WinSwapLayers
INFO     volatility3.framework.automagic: Running automagic: WintelHelper
INFO     volatility3.framework.automagic: Running automagic: KernelPDBScanner
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
Level 9  volatility3.framework.configuration.requirements: Symbol table requirement not yet fulfilled: plugins.PsList.nt_symbols
DEBUG    volatility3.framework.automagic.pdbscan: Kernel base determination - searching layer module list structure
DEBUG    volatility3.framework.automagic.pdbscan: Kernel base determination - searching layer module list structure
Level 6  volatility3.framework.symbols.intermed: Searching for symbols in /opt/volatility3/volatility3/symbols, /opt/volatility3/volatility3/framework/symbols
INFO     volatility3.framework.symbols.windows.pdbconv: Download PDB file...
DEBUG    volatility3.framework.symbols.windows.pdbconv: Attempting to retrieve http://msdl.microsoft.com/download/symbols/ntkrnlmp.pdb/6D523BCEBA7B4056879B95580644F8ED1/ntkrnlmp.pdb
DEBUG    volatility3.framework.layers.resources: Caching file at: /root/.cache/volatility3/data_6607392372526d87b1e5d3b977ead3393e374df4df7e742e894e3703abf1a13a00d5b64cfd4e86034bde24bced08a6922bdf86e682f4a5be15d75f38905ae304.cache
DEBUG    volatility3.framework.symbols.windows.pdbconv: Attempting to retrieve http://msdl.microsoft.com/download/symbols/ntkrnlmp.pdb/6D523BCEBA7B4056879B95580644F8ED1/ntkrnlmp.pd_
DEBUG    volatility3.framework.symbols.windows.pdbconv: Failed with HTTP Error 404: Not Found
Level 6  volatility3.framework.symbols.intermed: Searching for symbols in /opt/volatility3/volatility3/symbols, /opt/volatility3/volatility3/framework/symbols
DEBUG    volatility3.schemas: Validating JSON against schema...
DEBUG    volatility3.schemas: JSON validated against schema (result cached)
DEBUG    volatility3.framework.symbols.windows.pdbconv: Reading DBI stream
DEBUG    volatility3.framework.symbols.windows.pdbconv: Reading PDB Info
DEBUG    volatility3.framework.symbols.windows.pdbconv: Reading TPI
DEBUG    volatility3.framework.symbols.windows.pdbconv: Reading Symbols                                                                            
Level 6  volatility3.framework.symbols.intermed: Searching for symbols in /opt/volatility3/volatility3/symbols, /opt/volatility3/volatility3/framework/symbols
DEBUG    volatility3.framework.symbols.windows.pdbutil: Using symbol library: ntkrnlmp.pdb/6D523BCEBA7B4056879B95580644F8ED-1
DEBUG    volatility3.schemas: Validating JSON against schema...
DEBUG    volatility3.schemas: JSON validated against schema (result cached)
DEBUG    volatility3.framework.automagic.pdbscan: Setting kernel_virtual_offset to 0xf801e120c000
Progress:  100.00       PDB scanning finished                                                                                              
PID PPID    ImageFileName   Offset(V)   Threads Handles SessionId   Wow64   CreateTime  ExitTime    File output
Level 6  volatility3.framework.symbols.intermed: Searching for symbols in /opt/volatility3/volatility3/symbols, /opt/volatility3/volatility3/framework/symbols
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_EPROCESS_QUOTA_BLOCK
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_PAGEFAULT_HISTORY
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_JOB_ACCESS_STATE
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_JOB_CPU_RATE_CONTROL
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_JOB_NOTIFICATION_INFORMATION
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_ACTIVATION_CONTEXT_DATA
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_FLS_CALLBACK_INFO
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_ASSEMBLY_STORAGE_MAP
DEBUG    volatility3.framework.symbols: Unresolved reference: nt_symbols1!_SCSI_REQUEST_BLOCK

4   0   System  0xe001b9a32040  107 -   N/A False   2020-03-09 22:13:07.000000  N/A Disabled
212 4   smss.exe    0xe001ba34c400  2   -   N/A False   2020-03-09 22:13:07.000000  N/A Disabled
368 356 csrss.exe   0xe001ba509240  9   -   0   False   2020-03-09 22:13:09.000000  N/A Disabled
432 424 csrss.exe   0xe001ba543900  9   -   1   False   2020-03-09 22:13:09.000000  N/A Disabled
440 356 wininit.exe 0xe001ba5383c0  1   -   0   False   2020-03-09 22:13:09.000000  N/A Disabled
468 424 winlogon.exe    0xe001ba65b080  2   -   1   False   2020-03-09 22:13:09.000000  N/A Disabled
528 440 services.exe    0xe001ba682900  4   -   0   False   2020-03-09 22:13:10.000000  N/A Disabled
536 440 lsass.exe   0xe001ba5dd740  7   -   0   False   2020-03-09 22:13:10.000000  N/A Disabled
596 528 svchost.exe 0xe001ba61e900  10  -   0   False   2020-03-09 22:13:12.000000  N/A Disabled
640 528 svchost.exe 0xe001baa57900  11  -   0   False   2020-03-09 22:13:12.000000  N/A Disabled
756 468 dwm.exe 0xe001baae4080  9   -   1   False   2020-03-09 22:13:12.000000  N/A Disabled
764 528 svchost.exe 0xe001bab7d900  16  -   0   False   2020-03-09 22:13:12.000000  N/A Disabled
812 528 svchost.exe 0xe001bab7b900  51  -   0   False   2020-03-09 22:13:12.000000  N/A Disabled
840 528 svchost.exe 0xe001bab79900  16  -   0   False   2020-03-09 22:13:12.000000  N/A Disabled
924 528 svchost.exe 0xe001babd6080  18  -   0   False   2020-03-09 22:13:13.000000  N/A Disabled
356 528 svchost.exe 0xe001bab6f900  18  -   0   False   2020-03-09 22:13:13.000000  N/A Disabled
...
5968    1512    winpmem_x64.ex  0xe001d26690c0  1   -   1   False   2021-01-27 15:50:58.000000  N/A Disabled
5732    5968    conhost.exe 0xe001d262e080  1   -   1   False   2021-01-27 15:50:59.000000  N/A Disabled
4524    596 WmiPrvSE.exe    0xe001d2624900  7   -   0   False   2021-01-27 15:51:02.000000  N/A Disabled
0   0       0xe001cfebe080  3384393152  -   N/A False   N/A N/A Disabled

DEBUG    root        : Traceback (most recent call last):
  File "/opt/volatility3/volatility3/cli/__init__.py", line 319, in run
    renderers[args.renderer]().render(constructed.run())
  File "/opt/volatility3/volatility3/cli/text_renderer.py", line 178, in render
    grid.populate(visitor, outfd)
  File "/opt/volatility3/volatility3/framework/renderers/__init__.py", line 211, in populate
    for (level, item) in self._generator:
  File "/opt/volatility3/volatility3/framework/plugins/windows/pslist.py", line 197, in _generator
    yield (0, (proc.UniqueProcessId, proc.InheritedFromUniqueProcessId,
  File "/opt/volatility3/volatility3/framework/objects/__init__.py", line 741, in __getattr__
    member = template(context = self._context, object_info = object_info)
  File "/opt/volatility3/volatility3/framework/objects/templates.py", line 72, in __call__
    return self.vol.object_class(context = context, object_info = object_info, **arguments)
  File "/opt/volatility3/volatility3/framework/objects/__init__.py", line 119, in __new__
    value = cls._unmarshall(context, data_format, object_info)
  File "/opt/volatility3/volatility3/framework/objects/__init__.py", line 306, in _unmarshall
    data = context.layers.read(object_info.layer_name, object_info.offset, length)
  File "/opt/volatility3/volatility3/framework/interfaces/layers.py", line 535, in read
    return self[layer].read(offset, length, pad)
  File "/opt/volatility3/volatility3/framework/layers/linear.py", line 37, in read
    for (offset, _, mapped_offset, mapped_length, layer) in self.mapping(offset, length, ignore_errors = pad):
  File "/opt/volatility3/volatility3/framework/layers/intel.py", line 204, in mapping
    chunk_offset, page_size, layer_name = self._translate(offset)
  File "/opt/volatility3/volatility3/framework/layers/intel.py", line 325, in _translate
    return self._translate_swap(self, offset, self._bits_per_register // 2)
  File "/opt/volatility3/volatility3/framework/layers/intel.py", line 283, in _translate_swap
    return super()._translate(offset)
  File "/opt/volatility3/volatility3/framework/layers/intel.py", line 101, in _translate
    entry, position = self._translate_entry(offset)
  File "/opt/volatility3/volatility3/framework/layers/intel.py", line 144, in _translate_entry
    "Page Fault at entry " + hex(entry) + " in table " + name)
volatility3.framework.exceptions.PagedInvalidAddressException: Page Fault at entry 0xb20063 in table page table

Volatility was unable to read a requested page:
Page error 0xfffffffffff8 in layer primary (Page Fault at entry 0xb20063 in table page table)

    * Memory smear during acquisition (try re-acquiring if possible)
    * An intentionally invalid page lookup (operating system protection)
    * A bug in the plugin/volatility3 (re-run with -vvv and file a bug)

No further results will be produced

-------------
When i use vadinfo:
rk.symbols.windows.extensions: Vad tree is too deep, something went wrong!
Traceback (most recent call last):
  File "/opt/volatility3/vol.py", line 10, in <module>
    volatility3.cli.main()
  File "/opt/volatility3/volatility3/cli/__init__.py", line 589, in main
    CommandLine().run()
  File "/opt/volatility3/volatility3/cli/__init__.py", line 319, in run
    renderers[args.renderer]().render(constructed.run())
  File "/opt/volatility3/volatility3/cli/text_renderer.py", line 178, in render
    grid.populate(visitor, outfd)
  File "/opt/volatility3/volatility3/framework/renderers/__init__.py", line 211, in populate
    for (level, item) in self._generator:
  File "/opt/volatility3/volatility3/framework/plugins/windows/vadinfo.py", line 186, in _generator
    for vad in self.list_vads(proc, filter_func = filter_func):
  File "/opt/volatility3/volatility3/framework/plugins/windows/vadinfo.py", line 106, in list_vads
    for vad in proc.get_vad_root().traverse():
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 105, in traverse
    for vad_node in self.get_left_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 111, in traverse
    for vad_node in self.get_right_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 111, in traverse
    for vad_node in self.get_right_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 111, in traverse
    for vad_node in self.get_right_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 105, in traverse
    for vad_node in self.get_left_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 111, in traverse
    for vad_node in self.get_right_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 111, in traverse
    for vad_node in self.get_right_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 111, in traverse
    for vad_node in self.get_right_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 105, in traverse
    for vad_node in self.get_left_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 105, in traverse
    for vad_node in self.get_left_child().dereference().traverse(visited, depth + 1):
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 105, in traverse
    for vad_node in self.get_left_child().dereference().traverse(visited, depth + 1):
  [Previous line repeated 90 more times]
  File "/opt/volatility3/volatility3/framework/symbols/windows/extensions/__init__.py", line 71, in traverse
    raise RuntimeError("Vad tree is too deep")
RuntimeError: Vad tree is too deep

Context Volatility Version: git current master (today) Operating System: Docker Debian 10 Python Version: Python 3.7.3 Suspected Operating System: Win 2012 R2 Command: windows.pslist (bug on some command: vadinfo, malfind, VadYaraScan)

temporary solution Is it possible to do "try" on "volatility3/volatility3/framework/renderers/init.py", line 211 to avoid to stop analyze on error, in wait to fix the real problem?

ikelos commented 3 years ago

From looking at the output, it looks like the top option on the list:

Memory smear during acquisition (try re-acquiring if possible)

It's returned what look to be a number of valid results, and then points off to somewhere that isn't mapped, and volatility couldn't then read further entries in the list. This is expected behaviour when volatility encounters an address that isn't readable (in the develop branch we've moved the python code telling us where the problem is, so that it's only exposed with at least on -v flag).

If this memory used to work in volatility3, or you've acquired memory multiple times and always get the same result, then please feel free to reopen this issue, but it's unlikely we'll be able to change the outcome I'm afraid. 5:(

(The commands that you mentioned didn't work require the yara-python package to be installed)

ikelos commented 3 years ago

The vadtree issue looks more like a separate issue, please could you file a separate issue to discuss it? Otherwise it keeps information about both bugs around even when only one might be necessary.

lprat commented 3 years ago

From looking at the output, it looks like the top option on the list:

Memory smear during acquisition (try re-acquiring if possible)

It's returned what look to be a number of valid results, and then points off to somewhere that isn't mapped, and volatility couldn't then read further entries in the list. This is expected behaviour when volatility encounters an address that isn't readable (in the develop branch we've moved the python code telling us where the problem is, so that it's only exposed with at least on -v flag).

If this memory used to work in volatility3, or you've acquired memory multiple times and always get the same result, then please feel free to reopen this issue, but it's unlikely we'll be able to change the outcome I'm afraid. 5:(

(The commands that you mentioned didn't work require the yara-python package to be installed)

Is it possible to do "try" on "volatility3/volatility3/framework/renderers/init.py", line 211 to avoid to stop analyze on error (just pass the address isn't readable) ?

ikelos commented 3 years ago

We made a conscious decision to very clearly indicate when an error has occurred so that users are aware something has gone wrong (otherwise, as with volatility 2 which simply consumed errors without feedback) it's impossible to tell the difference between one that ran fine and one that didn't return complete results.

ikelos commented 3 years ago

We have added the fail_on_errors options to TreeRenderers, so that other user interfaces can decide whether to continue accumulating results or not:

https://github.com/volatilityfoundation/volatility3/blob/develop/volatility3/framework/renderers/__init__.py#L190

Within the official CLI we've made the decision that results after a known issue are likely questionable and as a forensics tool we need to make certain the user is aware of this. We may in the future alter how this operates, but for now this seemed the best way of ensuring that anyone using the results of the tool knew that an issue had occurred.