exeplot 0.5.2__tar.gz → 0.5.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {exeplot-0.5.2 → exeplot-0.5.4}/PKG-INFO +1 -1
  2. {exeplot-0.5.2 → exeplot-0.5.4}/docs/coverage.svg +1 -1
  3. exeplot-0.5.4/src/exeplot/VERSION.txt +1 -0
  4. exeplot-0.5.4/src/exeplot/__init__.py +9 -0
  5. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/utils.py +12 -9
  6. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot.egg-info/PKG-INFO +1 -1
  7. {exeplot-0.5.2 → exeplot-0.5.4}/tests/test_others.py +3 -4
  8. exeplot-0.5.2/src/exeplot/VERSION.txt +0 -1
  9. exeplot-0.5.2/src/exeplot/__init__.py +0 -5
  10. {exeplot-0.5.2 → exeplot-0.5.4}/.coveragerc +0 -0
  11. {exeplot-0.5.2 → exeplot-0.5.4}/.github/workflows/python-package.yml +0 -0
  12. {exeplot-0.5.2 → exeplot-0.5.4}/.gitignore +0 -0
  13. {exeplot-0.5.2 → exeplot-0.5.4}/.readthedocs.yml +0 -0
  14. {exeplot-0.5.2 → exeplot-0.5.4}/LICENSE +0 -0
  15. {exeplot-0.5.2 → exeplot-0.5.4}/README.md +0 -0
  16. {exeplot-0.5.2 → exeplot-0.5.4}/_config.yml +0 -0
  17. {exeplot-0.5.2 → exeplot-0.5.4}/docs/mkdocs.yml +0 -0
  18. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/css/extra.css +0 -0
  19. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/calc_orig_entropy.png +0 -0
  20. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/calc_packed_byte.png +0 -0
  21. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/calc_packed_byte2.png +0 -0
  22. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/calc_packed_entropy.png +0 -0
  23. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/calc_packed_nested_pie.png +0 -0
  24. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/calc_packed_pie.png +0 -0
  25. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/icon.png +0 -0
  26. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/logo.png +0 -0
  27. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/upx_calc_byte.png +0 -0
  28. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/img/upx_calc_entropy.png +0 -0
  29. {exeplot-0.5.2 → exeplot-0.5.4}/docs/pages/index.md +0 -0
  30. {exeplot-0.5.2 → exeplot-0.5.4}/docs/requirements.txt +0 -0
  31. {exeplot-0.5.2 → exeplot-0.5.4}/pyproject.toml +0 -0
  32. {exeplot-0.5.2 → exeplot-0.5.4}/pytest.ini +0 -0
  33. {exeplot-0.5.2 → exeplot-0.5.4}/requirements.txt +0 -0
  34. {exeplot-0.5.2 → exeplot-0.5.4}/setup.cfg +0 -0
  35. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/__conf__.py +0 -0
  36. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/__info__.py +0 -0
  37. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/__main__.py +0 -0
  38. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/__common__.py +0 -0
  39. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/__init__.py +0 -0
  40. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/byte.py +0 -0
  41. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/diff.py +0 -0
  42. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/entropy.py +0 -0
  43. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/graph.py +0 -0
  44. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/nested_pie.py +0 -0
  45. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot/plots/pie.py +0 -0
  46. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot.egg-info/SOURCES.txt +0 -0
  47. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot.egg-info/dependency_links.txt +0 -0
  48. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot.egg-info/entry_points.txt +0 -0
  49. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot.egg-info/requires.txt +0 -0
  50. {exeplot-0.5.2 → exeplot-0.5.4}/src/exeplot.egg-info/top_level.txt +0 -0
  51. {exeplot-0.5.2 → exeplot-0.5.4}/tests/__init__.py +0 -0
  52. {exeplot-0.5.2 → exeplot-0.5.4}/tests/hello.elf +0 -0
  53. {exeplot-0.5.2 → exeplot-0.5.4}/tests/hello.exe +0 -0
  54. {exeplot-0.5.2 → exeplot-0.5.4}/tests/hello.macho +0 -0
  55. {exeplot-0.5.2 → exeplot-0.5.4}/tests/test_plots.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exeplot
3
- Version: 0.5.2
3
+ Version: 0.5.4
4
4
  Summary: Library for plotting executable samples supporting multiple formats
5
5
  Author-email: Alexandre D'Hondt <alexandre.dhondt@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -1 +1 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 96.54%"><title>coverage: 96.54%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#4c1"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">96.54%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">96.54%</text></g></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 96.62%"><title>coverage: 96.62%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#4c1"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">96.62%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">96.62%</text></g></svg>
@@ -0,0 +1 @@
1
+ 0.5.4
@@ -0,0 +1,9 @@
1
+ # -*- coding: UTF-8 -*-
2
+ """Exeplot package.
3
+
4
+ """
5
+ from .__conf__ import *
6
+ from .__info__ import __author__, __copyright__, __license__, __version__
7
+ from .plots import *
8
+ from .plots import __all__
9
+
@@ -30,19 +30,22 @@ def human_readable_size(size: int, precision: int = 0) -> str:
30
30
  return "%.*f%s" % (precision, size, units[i])
31
31
 
32
32
 
33
- def ngrams_counts(byte_obj: bytes | object, n: int = 1, step: int = 1) -> dict[bytes, int]:
34
- """ Output the Counter instance for an input byte sequence or byte object based on n-grams.
35
- If the input is a byte object, cache the result.
33
+ def ngrams_counts(byte_obj: bytes | object, n: int = 1, step: int = 1) -> list[tuple[bytes, int]]:
34
+ """ Output a sorted list of tuples (n-gram, counts) for an input byte sequence or byte object.
35
+ If the input is a byte object, the result is cached.
36
36
 
37
- :param byte_obj: byte sequence ('bytes') or byte object with "bytes" and "size" attributes (i.e. pathlib2.Path)
38
- :param n: n determining the size of n-grams, defaults to 1
39
- :param step: step for sliding the n-grams
40
- :param start: number of bytes to start from
37
+ :param byte_obj: byte sequence ('bytes') or byte object with "bytes" and "size" attributes (i.e. pathlib2.Path)
38
+ :param n: n determining the size of n-grams, defaults to 1
39
+ :param step: step for sliding the n-grams
41
40
  """
42
41
  if n not in (1, 2, 3):
43
42
  raise ValueError("n must be 1, 2, or 3")
44
43
  if step <= 0:
45
44
  raise ValueError("step must be positive")
45
+ try:
46
+ return byte_obj._ngram_counts_cache[n]
47
+ except (AttributeError, KeyError):
48
+ pass
46
49
  if isinstance(byte_obj, bytes) or hasattr(byte_obj, "bytes"):
47
50
  a = np.frombuffer(data := byte_obj if isinstance(byte_obj, bytes) else byte_obj.bytes, dtype=np.uint8)
48
51
  l = a.size
@@ -56,6 +59,7 @@ def ngrams_counts(byte_obj: bytes | object, n: int = 1, step: int = 1) -> dict[b
56
59
  grams = np.stack((a[0:end:step], a[1:1+end:step]), axis=1) if n == 2 else \
57
60
  np.stack((a[0:end:step], a[1:1+end:step], a[2:2+end:step]), axis=1)
58
61
  counts = {bytes(row): int(c) for row, c in zip(*np.unique(grams, axis=0, return_counts=True))}
62
+ counts = sorted(counts.items(), key=lambda p: p[1], reverse=True)
59
63
  if isinstance(byte_obj, bytes):
60
64
  return counts
61
65
  elif hasattr(byte_obj, "bytes"):
@@ -80,8 +84,7 @@ def ngrams_distribution(byte_obj: bytes | object, n: int = 1, step: int = 1, n_m
80
84
  :return: list of n_most_common (n-gram, count) pairs
81
85
  """
82
86
  c = ngrams_counts(byte_obj, n, step)
83
- n = len(c) if n_most_common is None else n_most_common + n_exclude_top + len(exclude or [])
84
- r = sorted(c.items(), key=lambda p: p[1], reverse=True)[:n]
87
+ r = c[:len(c) if n_most_common is None else n_most_common + n_exclude_top + len(exclude or [])]
85
88
  if exclude is not None:
86
89
  r = [(ngram, count) for ngram, count in r if ngram not in exclude]
87
90
  return r[n_exclude_top:n_exclude_top+(n_most_common or len(c))]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exeplot
3
- Version: 0.5.2
3
+ Version: 0.5.4
4
4
  Summary: Library for plotting executable samples supporting multiple formats
5
5
  Author-email: Alexandre D'Hondt <alexandre.dhondt@gmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -24,12 +24,11 @@ class TestUtils(TestCase):
24
24
  self.assertRaises(ValueError, ngrams_counts, b"abc", n=n)
25
25
  self.assertRaises(ValueError, ngrams_counts, b"abc", step=-1)
26
26
  self.assertEqual(ngrams_counts(b"a", n=2), {})
27
- self.assertTrue(isinstance(ngrams_counts(seq := b"\x00" * 4 + os.urandom(120) + b"\xff" * 4), dict))
28
- self.assertTrue(isinstance(ngrams_counts(seq := b"\x00" * 4 + os.urandom(120) + b"\xff" * 4, n=2), dict))
27
+ self.assertTrue(isinstance(ngrams_counts(seq := b"\x00" * 4 + os.urandom(120) + b"\xff" * 4), list))
28
+ self.assertTrue(isinstance(ngrams_counts(seq := b"\x00" * 4 + os.urandom(120) + b"\xff" * 4, n=2), list))
29
29
  class Test:
30
30
  bytes = seq
31
- histogram = ngrams_distribution(t := Test(), exclude=(b"\x00", b"\xff"))
32
- self.assertTrue(isinstance(histogram, list))
31
+ self.assertTrue(isinstance(histogram := ngrams_distribution(t := Test(), exclude=(b"\x00", b"\xff")), list))
33
32
  self.assertNotIn(b"\x00", [b for b, c in histogram])
34
33
  self.assertNotIn(b"\xff", [b for b, c in histogram])
35
34
  histogram2 = ngrams_distribution(t, n_most_common=300)
@@ -1 +0,0 @@
1
- 0.5.2
@@ -1,5 +0,0 @@
1
- # -*- coding: UTF-8 -*-
2
- from .__conf__ import *
3
- from .plots import *
4
- from .plots import __all__
5
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes