diff --git a/.github/flake8.ini b/.github/flake8.ini index f501ea67..f97dacc2 100644 --- a/.github/flake8.ini +++ b/.github/flake8.ini @@ -14,3 +14,16 @@ extend-ignore = B010, # G200 Logging statement uses exception in arguments G200 + + +per-file-ignores = + # T201 print found. + # + # scripts are meant to print output + scripts/*: T201 + # capa.exe is meant to print output + capa/main.py: T201 + # IDA tests emit results to output window so need to print + tests/test_ida_features.py: T201 + # utility used to find the Binary Ninja API via invoking python.exe + capa/features/extractors/binja/find_binja_api.py: T201 \ No newline at end of file diff --git a/capa/features/extractors/binja/basicblock.py b/capa/features/extractors/binja/basicblock.py index 6649fc92..02855ad8 100644 --- a/capa/features/extractors/binja/basicblock.py +++ b/capa/features/extractors/binja/basicblock.py @@ -6,7 +6,6 @@ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and limitations under the License. -import sys import string import struct from typing import Tuple, Iterator @@ -182,30 +181,3 @@ BASIC_BLOCK_HANDLERS = ( extract_bb_tight_loop, extract_bb_stackstring, ) - - -def main(): - if len(sys.argv) < 2: - return - - from binaryninja import BinaryViewType - - from capa.features.extractors.binja.extractor import BinjaFeatureExtractor - - bv: BinaryView = BinaryViewType.get_view_of_file(sys.argv[1]) - if bv is None: - return - - features = [] - extractor = BinjaFeatureExtractor(bv) - for fh in extractor.get_functions(): - for bbh in extractor.get_basic_blocks(fh): - features.extend(list(extract_features(fh, bbh))) - - import pprint - - pprint.pprint(features) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/binja/file.py b/capa/features/extractors/binja/file.py index edc11ed4..c36b5b48 100644 --- a/capa/features/extractors/binja/file.py +++ b/capa/features/extractors/binja/file.py @@ -6,7 +6,6 @@ # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and limitations under the License. -import sys import struct from typing import Tuple, Iterator @@ -166,23 +165,3 @@ FILE_HANDLERS = ( extract_file_function_names, extract_file_format, ) - - -def main(): - """ """ - if len(sys.argv) < 2: - return - - from binaryninja import BinaryViewType - - bv: BinaryView = BinaryViewType.get_view_of_file(sys.argv[1]) - if bv is None: - return - - import pprint - - pprint.pprint(list(extract_features(bv))) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/binja/function.py b/capa/features/extractors/binja/function.py index 981650b7..2bf735db 100644 --- a/capa/features/extractors/binja/function.py +++ b/capa/features/extractors/binja/function.py @@ -5,7 +5,6 @@ # Unless required by applicable law or agreed to in writing, software distributed under the License # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and limitations under the License. -import sys from typing import Tuple, Iterator from binaryninja import Function, BinaryView, LowLevelILOperation @@ -67,30 +66,3 @@ def extract_features(fh: FunctionHandle) -> Iterator[Tuple[Feature, Address]]: FUNCTION_HANDLERS = (extract_function_calls_to, extract_function_loop, extract_recursive_call) - - -def main(): - """ """ - if len(sys.argv) < 2: - return - - from binaryninja import BinaryViewType - - from capa.features.extractors.binja.extractor import BinjaFeatureExtractor - - bv: BinaryView = BinaryViewType.get_view_of_file(sys.argv[1]) - if bv is None: - return - - features = [] - extractor = BinjaFeatureExtractor(bv) - for fh in extractor.get_functions(): - features.extend(list(extract_features(fh))) - - import pprint - - pprint.pprint(features) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/binja/insn.py b/capa/features/extractors/binja/insn.py index 9f22beae..998462b1 100644 --- a/capa/features/extractors/binja/insn.py +++ b/capa/features/extractors/binja/insn.py @@ -5,7 +5,6 @@ # Unless required by applicable law or agreed to in writing, software distributed under the License # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and limitations under the License. -import sys from typing import Any, List, Tuple, Iterator, Optional from binaryninja import Function @@ -585,32 +584,3 @@ INSTRUCTION_HANDLERS = ( extract_function_calls_from, extract_function_indirect_call_characteristic_features, ) - - -def main(): - """ """ - if len(sys.argv) < 2: - return - - from binaryninja import BinaryViewType - - from capa.features.extractors.binja.extractor import BinjaFeatureExtractor - - bv: BinaryView = BinaryViewType.get_view_of_file(sys.argv[1]) - if bv is None: - return - - features = [] - extractor = BinjaFeatureExtractor(bv) - for fh in extractor.get_functions(): - for bbh in extractor.get_basic_blocks(fh): - for insn in extractor.get_instructions(fh, bbh): - features.extend(list(extract_features(fh, bbh, insn))) - - import pprint - - pprint.pprint(features) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/ida/basicblock.py b/capa/features/extractors/ida/basicblock.py index 34f7d1ce..88a1247e 100644 --- a/capa/features/extractors/ida/basicblock.py +++ b/capa/features/extractors/ida/basicblock.py @@ -104,19 +104,3 @@ BASIC_BLOCK_HANDLERS = ( extract_bb_tight_loop, extract_bb_stackstring, ) - - -def main(): - features = [] - for fhandle in helpers.get_functions(skip_thunks=True, skip_libs=True): - f: idaapi.func_t = fhandle.inner - for bb in idaapi.FlowChart(f, flags=idaapi.FC_PREDS): - features.extend(list(extract_features(fhandle, bb))) - - import pprint - - pprint.pprint(features) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/ida/file.py b/capa/features/extractors/ida/file.py index a3da4c6a..e75d59e1 100644 --- a/capa/features/extractors/ida/file.py +++ b/capa/features/extractors/ida/file.py @@ -199,14 +199,3 @@ FILE_HANDLERS = ( extract_file_function_names, extract_file_format, ) - - -def main(): - """ """ - import pprint - - pprint.pprint(list(extract_features())) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/ida/function.py b/capa/features/extractors/ida/function.py index 8d0c6778..cb4d6329 100644 --- a/capa/features/extractors/ida/function.py +++ b/capa/features/extractors/ida/function.py @@ -50,18 +50,3 @@ def extract_features(fh: FunctionHandle) -> Iterator[Tuple[Feature, Address]]: FUNCTION_HANDLERS = (extract_function_calls_to, extract_function_loop, extract_recursive_call) - - -def main(): - """ """ - features = [] - for fhandle in capa.features.extractors.ida.helpers.get_functions(skip_thunks=True, skip_libs=True): - features.extend(list(extract_features(fhandle))) - - import pprint - - pprint.pprint(features) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/ida/insn.py b/capa/features/extractors/ida/insn.py index 7e3b6b40..932df2c7 100644 --- a/capa/features/extractors/ida/insn.py +++ b/capa/features/extractors/ida/insn.py @@ -501,20 +501,3 @@ INSTRUCTION_HANDLERS = ( extract_function_calls_from, extract_function_indirect_call_characteristic_features, ) - - -def main(): - """ """ - features = [] - for f in capa.features.extractors.ida.helpers.get_functions(skip_thunks=True, skip_libs=True): - for bb in idaapi.FlowChart(f, flags=idaapi.FC_PREDS): - for insn in capa.features.extractors.ida.helpers.get_instructions_in_range(bb.start_ea, bb.end_ea): - features.extend(list(extract_features(f, bb, insn))) - - import pprint - - pprint.pprint(features) - - -if __name__ == "__main__": - main() diff --git a/capa/features/extractors/strings.py b/capa/features/extractors/strings.py index 924b9be9..4896e045 100644 --- a/capa/features/extractors/strings.py +++ b/capa/features/extractors/strings.py @@ -85,20 +85,3 @@ def extract_unicode_strings(buf, n=4): yield String(match.group().decode("utf-16"), match.start()) except UnicodeDecodeError: pass - - -def main(): - import sys - - with open(sys.argv[1], "rb") as f: - b = f.read() - - for s in extract_ascii_strings(b): - print("0x{:x}: {:s}".format(s.offset, s.s)) - - for s in extract_unicode_strings(b): - print("0x{:x}: {:s}".format(s.offset, s.s)) - - -if __name__ == "__main__": - main() diff --git a/capa/helpers.py b/capa/helpers.py index b098a4f2..9b344fc7 100644 --- a/capa/helpers.py +++ b/capa/helpers.py @@ -96,7 +96,7 @@ def redirecting_print_to_tqdm(disable_progress): with one that is compatible with tqdm. via: https://stackoverflow.com/a/42424890/87207 """ - old_print = print + old_print = print # noqa: T202 [reserved word print used] def new_print(*args, **kwargs): # If tqdm.tqdm.write raises error, use builtin print diff --git a/setup.py b/setup.py index ef9b3465..5bbd858b 100644 --- a/setup.py +++ b/setup.py @@ -80,6 +80,7 @@ setuptools.setup( "flake8-comprehensions==3.13.0", "flake8-logging-format==0.9.0", "flake8-no-implicit-concat==0.3.4", + "flake8-print==5.0.0", "ruff==0.0.275", "black==23.3.0", "isort==5.11.4", diff --git a/tests/test_scripts.py b/tests/test_scripts.py index b37531d0..04c091de 100644 --- a/tests/test_scripts.py +++ b/tests/test_scripts.py @@ -8,11 +8,14 @@ import os import sys +import logging import textwrap import subprocess import pytest +logger = logging.getLogger(__name__) + CD = os.path.dirname(__file__) @@ -63,7 +66,7 @@ def test_bulk_process(tmpdir): def run_program(script_path, args): args = [sys.executable] + [script_path] + args - print(f"running: '{args}'") + logger.debug("running: %r", args) return subprocess.run(args, stdout=subprocess.PIPE)