exeplot 0.5.2__tar.gz → 0.5.5__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.
- exeplot-0.5.5/.github/dependabot.yml +15 -0
- exeplot-0.5.5/.github/workflows/python-package.yml +142 -0
- exeplot-0.5.5/.github/workflows/security.yml +31 -0
- exeplot-0.5.2/.readthedocs.yml → exeplot-0.5.5/.readthedocs.yaml +1 -1
- {exeplot-0.5.2 → exeplot-0.5.5}/PKG-INFO +8 -4
- {exeplot-0.5.2 → exeplot-0.5.5}/README.md +4 -3
- exeplot-0.5.5/SECURITY.md +17 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/coverage.svg +1 -1
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/mkdocs.yml +28 -9
- exeplot-0.5.5/docs/pages/api.md +190 -0
- exeplot-0.5.5/docs/pages/cli/exeplot.md +191 -0
- exeplot-0.5.5/docs/pages/contributing.md +86 -0
- exeplot-0.5.5/docs/pages/index.md +65 -0
- exeplot-0.5.5/docs/pages/installation.md +73 -0
- exeplot-0.5.5/docs/pages/internals.md +105 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/requirements.txt +1 -1
- {exeplot-0.5.2 → exeplot-0.5.5}/pyproject.toml +4 -0
- exeplot-0.5.5/requirements.txt +11 -0
- exeplot-0.5.5/src/exeplot/VERSION.txt +1 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/__conf__.py +14 -8
- exeplot-0.5.5/src/exeplot/__init__.py +9 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/__main__.py +4 -1
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/__common__.py +11 -8
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/diff.py +1 -1
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/entropy.py +4 -4
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/graph.py +5 -3
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/utils.py +16 -12
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot.egg-info/PKG-INFO +8 -4
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot.egg-info/SOURCES.txt +9 -2
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot.egg-info/requires.txt +5 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/tests/test_others.py +4 -5
- exeplot-0.5.2/.github/workflows/python-package.yml +0 -109
- exeplot-0.5.2/docs/pages/css/extra.css +0 -26
- exeplot-0.5.2/docs/pages/index.md +0 -12
- exeplot-0.5.2/requirements.txt +0 -2
- exeplot-0.5.2/src/exeplot/VERSION.txt +0 -1
- exeplot-0.5.2/src/exeplot/__init__.py +0 -5
- {exeplot-0.5.2 → exeplot-0.5.5}/.coveragerc +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/.gitignore +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/LICENSE +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/_config.yml +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/calc_orig_entropy.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/calc_packed_byte.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/calc_packed_byte2.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/calc_packed_entropy.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/calc_packed_nested_pie.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/calc_packed_pie.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/icon.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/logo.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/upx_calc_byte.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/docs/pages/img/upx_calc_entropy.png +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/pytest.ini +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/setup.cfg +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/__info__.py +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/__init__.py +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/byte.py +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/nested_pie.py +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot/plots/pie.py +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot.egg-info/dependency_links.txt +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot.egg-info/entry_points.txt +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/src/exeplot.egg-info/top_level.txt +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/tests/__init__.py +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/tests/hello.elf +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/tests/hello.exe +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/tests/hello.macho +0 -0
- {exeplot-0.5.2 → exeplot-0.5.5}/tests/test_plots.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: github-actions
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: monthly
|
|
7
|
+
groups:
|
|
8
|
+
actions:
|
|
9
|
+
patterns: ["*"]
|
|
10
|
+
- package-ecosystem: pip
|
|
11
|
+
directory: /
|
|
12
|
+
schedule:
|
|
13
|
+
interval: monthly
|
|
14
|
+
# dependencies are minimum versions (>=) ; only open security updates, not routine upgrades
|
|
15
|
+
open-pull-requests-limit: 0
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
|
3
|
+
|
|
4
|
+
name: build
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ "main" ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ "main" ]
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
prepare:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
outputs:
|
|
19
|
+
package: ${{ steps.pkg.outputs.package }}
|
|
20
|
+
pypi_url: ${{ steps.pkg.outputs.pypi_url }}
|
|
21
|
+
steps:
|
|
22
|
+
- name: Compute package name from the repository's
|
|
23
|
+
id: pkg
|
|
24
|
+
run: |
|
|
25
|
+
name="${GITHUB_REPOSITORY##*/}"
|
|
26
|
+
echo "package=${name#python-}" >> $GITHUB_OUTPUT
|
|
27
|
+
echo "pypi_url=https://pypi.org/p/${name#python-}" >> $GITHUB_OUTPUT
|
|
28
|
+
build:
|
|
29
|
+
needs: prepare
|
|
30
|
+
runs-on: ${{ matrix.os }}
|
|
31
|
+
strategy:
|
|
32
|
+
fail-fast: false
|
|
33
|
+
matrix:
|
|
34
|
+
os: [ubuntu-latest]
|
|
35
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
36
|
+
env:
|
|
37
|
+
package: ${{ needs.prepare.outputs.package }}
|
|
38
|
+
cov_python_version: "3.13"
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v5
|
|
41
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
42
|
+
uses: actions/setup-python@v6
|
|
43
|
+
with:
|
|
44
|
+
python-version: ${{ matrix.python-version }}
|
|
45
|
+
- name: Install ${{ env.package }}
|
|
46
|
+
run: |
|
|
47
|
+
sudo apt-get update
|
|
48
|
+
sudo apt-get install -y graphviz libgraphviz-dev
|
|
49
|
+
python -m pip install --upgrade pip
|
|
50
|
+
python -m pip install pytest pytest-cov
|
|
51
|
+
pip install -r requirements.txt
|
|
52
|
+
pip install .
|
|
53
|
+
- name: Test ${{ env.package }} with pytest
|
|
54
|
+
run: |
|
|
55
|
+
pytest --cov=$package --cov-report=xml
|
|
56
|
+
- name: Upload coverage report
|
|
57
|
+
if: matrix.python-version == env.cov_python_version
|
|
58
|
+
uses: actions/upload-artifact@v7
|
|
59
|
+
with:
|
|
60
|
+
name: coverage-report
|
|
61
|
+
path: coverage.xml
|
|
62
|
+
coverage:
|
|
63
|
+
# only publish the badge for commits on main (not for pull requests)
|
|
64
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
65
|
+
needs: build
|
|
66
|
+
permissions:
|
|
67
|
+
contents: write
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
env:
|
|
70
|
+
cov_badge_path: docs/coverage.svg
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v5
|
|
73
|
+
- name: Set up Python
|
|
74
|
+
uses: actions/setup-python@v6
|
|
75
|
+
with:
|
|
76
|
+
python-version: "3.13"
|
|
77
|
+
- name: Download coverage report
|
|
78
|
+
uses: actions/download-artifact@v8
|
|
79
|
+
with:
|
|
80
|
+
name: coverage-report
|
|
81
|
+
- name: Make coverage badge
|
|
82
|
+
run: |
|
|
83
|
+
pip install genbadge[coverage]
|
|
84
|
+
genbadge coverage -i coverage.xml -o $cov_badge_path
|
|
85
|
+
- name: Push coverage badge
|
|
86
|
+
run: |
|
|
87
|
+
# keep the badge alone on an orphan branch so that main is never modified by the workflow
|
|
88
|
+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
89
|
+
git config --local user.name "github-actions[bot]"
|
|
90
|
+
if git fetch --depth=1 origin coverage-badge 2>/dev/null && \
|
|
91
|
+
git show FETCH_HEAD:$cov_badge_path | cmp -s - $cov_badge_path; then
|
|
92
|
+
echo "Coverage badge unchanged"
|
|
93
|
+
exit 0
|
|
94
|
+
fi
|
|
95
|
+
git checkout --orphan coverage-badge
|
|
96
|
+
git rm -rqf --cached .
|
|
97
|
+
git add $cov_badge_path
|
|
98
|
+
git commit -m "Update coverage badge"
|
|
99
|
+
git push origin coverage-badge --force
|
|
100
|
+
deploy:
|
|
101
|
+
# only release from main, never from pull requests
|
|
102
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
103
|
+
environment:
|
|
104
|
+
name: pypi
|
|
105
|
+
url: ${{ needs.prepare.outputs.pypi_url }}
|
|
106
|
+
permissions:
|
|
107
|
+
contents: read
|
|
108
|
+
id-token: write # for PyPI trusted publishing (OIDC)
|
|
109
|
+
runs-on: ubuntu-latest
|
|
110
|
+
needs: [prepare, build]
|
|
111
|
+
env:
|
|
112
|
+
package: ${{ needs.prepare.outputs.package }}
|
|
113
|
+
steps:
|
|
114
|
+
- uses: actions/checkout@v5
|
|
115
|
+
- name: Check whether the version is already on PyPI
|
|
116
|
+
# comparing with PyPI (not with the previous commit) also releases a version whose push did not trigger a deploy
|
|
117
|
+
id: version
|
|
118
|
+
run: |
|
|
119
|
+
version=$(tr -d '[:space:]' < src/$package/VERSION.txt)
|
|
120
|
+
status=$(curl -s -o /dev/null -w '%{http_code}' --retry 3 "https://pypi.org/pypi/$package/$version/json")
|
|
121
|
+
case "$status" in
|
|
122
|
+
200) echo "Version $version is already on PyPI" ; echo "new=false" >> "$GITHUB_OUTPUT" ;;
|
|
123
|
+
404) echo "Version $version is not on PyPI yet" ; echo "new=true" >> "$GITHUB_OUTPUT" ;;
|
|
124
|
+
*) echo "::error::Unexpected HTTP status $status from PyPI" ; exit 1 ;;
|
|
125
|
+
esac
|
|
126
|
+
- if: steps.version.outputs.new == 'true'
|
|
127
|
+
name: Set up Python
|
|
128
|
+
uses: actions/setup-python@v6
|
|
129
|
+
with:
|
|
130
|
+
python-version: "3.13"
|
|
131
|
+
- if: steps.version.outputs.new == 'true'
|
|
132
|
+
name: Cleanup README
|
|
133
|
+
run: |
|
|
134
|
+
sed -ri 's/^(##*)\s*:.*:\s*/\1 /g' README.md
|
|
135
|
+
awk '{if (match($0,"## Supporters")) exit; print}' README.md > README
|
|
136
|
+
mv -f README README.md
|
|
137
|
+
- if: steps.version.outputs.new == 'true'
|
|
138
|
+
name: Build ${{ needs.prepare.outputs.package }} package
|
|
139
|
+
run: python -m pip install --upgrade build && python -m build
|
|
140
|
+
- if: steps.version.outputs.new == 'true'
|
|
141
|
+
name: Publish to PyPI
|
|
142
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# This workflow audits the package dependencies for known vulnerabilities
|
|
2
|
+
# It is separate from python-package.yml so that a new advisory never blocks a release
|
|
3
|
+
|
|
4
|
+
name: security
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ "main" ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ "main" ]
|
|
11
|
+
schedule:
|
|
12
|
+
- cron: "0 6 * * 1" # weekly, catches new advisories between pushes
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
pip-audit:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v7
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
uses: actions/setup-python@v7
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
- name: Install pip-audit
|
|
28
|
+
run: python -m pip install --upgrade pip pip-audit
|
|
29
|
+
- name: Audit dependencies
|
|
30
|
+
# resolves the dependencies of pyproject.toml in an isolated environment, so only these are audited
|
|
31
|
+
run: pip-audit .
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exeplot
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.5
|
|
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
|
|
@@ -696,22 +696,25 @@ Requires-Dist: lief>=0.16.1
|
|
|
696
696
|
Requires-Dist: matplotlib
|
|
697
697
|
Provides-Extra: graph
|
|
698
698
|
Requires-Dist: angr>=9.2; extra == "graph"
|
|
699
|
+
Requires-Dist: bitstring<5; python_version < "3.12" and extra == "graph"
|
|
700
|
+
Requires-Dist: pycparser<3.12; python_version < "3.12" and extra == "graph"
|
|
699
701
|
Requires-Dist: networkx>=3.4.2; extra == "graph"
|
|
700
702
|
Requires-Dist: numpy; extra == "graph"
|
|
701
703
|
Requires-Dist: pygraphviz>=1.14; extra == "graph"
|
|
704
|
+
Requires-Dist: scipy; extra == "graph"
|
|
702
705
|
Requires-Dist: unicorn>2; extra == "graph"
|
|
703
706
|
Dynamic: license-file
|
|
704
707
|
|
|
705
708
|
<p align="center" id="top"><img src="https://github.com/packing-box/python-exeplot/raw/main/docs/pages/img/logo.png"></p>
|
|
706
709
|
<h1 align="center">ExePlot <a href="https://twitter.com/intent/tweet?text=ExePlot%20-%20Plot%20executable%20samples%20easy.%0D%0ALibrary%20for%20plotting%20executable%20samples%20supporting%20multiple%20formats.%0D%0Ahttps%3a%2f%2fgithub%2ecom%2fpacking-box%2fpython-exeplot%0D%0A&hashtags=python,programming,executable-samples,plot"><img src="https://img.shields.io/badge/Tweet--lightgrey?logo=twitter&style=social" alt="Tweet" height="20"/></a></h1>
|
|
707
|
-
<h3 align="center">
|
|
710
|
+
<h3 align="center">Plot executable samples easy.</h3>
|
|
708
711
|
|
|
709
712
|
[](https://pypi.python.org/pypi/exeplot/)
|
|
710
713
|
[](https://python-exeplot.readthedocs.io/en/latest/?badge=latest)
|
|
711
714
|
[](https://github.com/packing-box/python-exeplot/actions/workflows/python-package.yml)
|
|
712
|
-
[](https://github.com/packing-box/python-exeplot/actions/workflows/security.yml)
|
|
716
|
+
[](#)
|
|
713
717
|
[](https://pypi.python.org/pypi/exeplot/)
|
|
714
|
-
[](https://snyk.io/test/github/packing-box/python-exeplot?targetFile=requirements.txt)
|
|
715
718
|
[](https://pypi.python.org/pypi/exeplot/)
|
|
716
719
|
|
|
717
720
|
This library implements multiple plot types for illustrating executable samples. It currently supports the PE, ELF and Mach-O formats, relying on [`lief`](https://github.com/lief-project/LIEF) for abstracting them.
|
|
@@ -771,3 +774,4 @@ $ exeplot entropy calc_packed.exe --no-title --no-legend --no-label --no-entrypo
|
|
|
771
774
|

|
|
772
775
|
|
|
773
776
|
|
|
777
|
+
<p align="center"><a href="#top"><img src="https://img.shields.io/badge/Back%20to%20top--lightgrey?style=social" alt="Back to top" height="20"/></a></p>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<p align="center" id="top"><img src="https://github.com/packing-box/python-exeplot/raw/main/docs/pages/img/logo.png"></p>
|
|
2
2
|
<h1 align="center">ExePlot <a href="https://twitter.com/intent/tweet?text=ExePlot%20-%20Plot%20executable%20samples%20easy.%0D%0ALibrary%20for%20plotting%20executable%20samples%20supporting%20multiple%20formats.%0D%0Ahttps%3a%2f%2fgithub%2ecom%2fpacking-box%2fpython-exeplot%0D%0A&hashtags=python,programming,executable-samples,plot"><img src="https://img.shields.io/badge/Tweet--lightgrey?logo=twitter&style=social" alt="Tweet" height="20"/></a></h1>
|
|
3
|
-
<h3 align="center">
|
|
3
|
+
<h3 align="center">Plot executable samples easy.</h3>
|
|
4
4
|
|
|
5
5
|
[](https://pypi.python.org/pypi/exeplot/)
|
|
6
6
|
[](https://python-exeplot.readthedocs.io/en/latest/?badge=latest)
|
|
7
7
|
[](https://github.com/packing-box/python-exeplot/actions/workflows/python-package.yml)
|
|
8
|
-
[](https://github.com/packing-box/python-exeplot/actions/workflows/security.yml)
|
|
9
|
+
[](#)
|
|
9
10
|
[](https://pypi.python.org/pypi/exeplot/)
|
|
10
|
-
[](https://snyk.io/test/github/packing-box/python-exeplot?targetFile=requirements.txt)
|
|
11
11
|
[](https://pypi.python.org/pypi/exeplot/)
|
|
12
12
|
|
|
13
13
|
This library implements multiple plot types for illustrating executable samples. It currently supports the PE, ELF and Mach-O formats, relying on [`lief`](https://github.com/lief-project/LIEF) for abstracting them.
|
|
@@ -67,3 +67,4 @@ $ exeplot entropy calc_packed.exe --no-title --no-legend --no-label --no-entrypo
|
|
|
67
67
|

|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
<p align="center"><a href="#top"><img src="https://img.shields.io/badge/Back%20to%20top--lightgrey?style=social" alt="Back to top" height="20"/></a></p>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Only the latest release of ExePlot (`exeplot` on [PyPI](https://pypi.org/project/exeplot/)) receives security fixes.
|
|
6
|
+
|
|
7
|
+
## Reporting a Vulnerability
|
|
8
|
+
|
|
9
|
+
Please do **not** report security vulnerabilities through public GitHub issues.
|
|
10
|
+
|
|
11
|
+
Instead, report them privately through [GitHub's private vulnerability reporting](https://github.com/packing-box/python-exeplot/security/advisories/new) (the repository's *Security* tab, then *Report a vulnerability*). Please include:
|
|
12
|
+
|
|
13
|
+
- the ExePlot version (`exeplot --help` prints it);
|
|
14
|
+
- the steps to reproduce the issue, and a sample (or its hash) if relevant;
|
|
15
|
+
- the impact you expect.
|
|
16
|
+
|
|
17
|
+
You will get an answer as soon as possible. Once the issue is confirmed, a fix is released and the advisory is published.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 96.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 96.64%"><title>coverage: 96.64%</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.64%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">96.64%</text></g></svg>
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
site_author: dhondta
|
|
2
|
-
site_name:
|
|
3
|
-
|
|
2
|
+
site_name: ExePlot
|
|
3
|
+
site_description: Library for plotting executable samples supporting multiple formats
|
|
4
|
+
site_url: https://python-exeplot.readthedocs.io
|
|
5
|
+
repo_url: https://github.com/packing-box/python-exeplot
|
|
6
|
+
edit_uri: edit/main/docs/pages/
|
|
4
7
|
copyright: Copyright © 2024 Alexandre D'Hondt
|
|
5
8
|
docs_dir: pages
|
|
6
9
|
nav:
|
|
7
|
-
-
|
|
10
|
+
- Home: index.md
|
|
11
|
+
- Installation: installation.md
|
|
12
|
+
- Command-line tool:
|
|
13
|
+
- exeplot: cli/exeplot.md
|
|
14
|
+
- Python API: api.md
|
|
15
|
+
- How it works: internals.md
|
|
16
|
+
- Contributing: contributing.md
|
|
8
17
|
extra:
|
|
9
18
|
generator: false
|
|
10
19
|
social:
|
|
@@ -20,23 +29,33 @@ extra:
|
|
|
20
29
|
- icon: fontawesome/brands/twitter
|
|
21
30
|
link: https://twitter.com/alex_dhondt
|
|
22
31
|
name: Alex on Twitter
|
|
23
|
-
extra_css:
|
|
24
|
-
- css/extra.css
|
|
25
32
|
theme:
|
|
26
33
|
name: material
|
|
34
|
+
logo: img/logo.png
|
|
35
|
+
favicon: img/icon.png
|
|
27
36
|
palette:
|
|
28
37
|
- scheme: default
|
|
29
38
|
toggle:
|
|
30
|
-
icon: material/brightness-7
|
|
39
|
+
icon: material/brightness-7
|
|
31
40
|
name: Switch to dark mode
|
|
32
41
|
- scheme: slate
|
|
33
42
|
toggle:
|
|
34
43
|
icon: material/brightness-4
|
|
35
44
|
name: Switch to light mode
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
features:
|
|
46
|
+
- content.code.copy
|
|
47
|
+
- navigation.sections
|
|
48
|
+
- navigation.top
|
|
49
|
+
- toc.follow
|
|
38
50
|
use_directory_urls: false
|
|
39
51
|
markdown_extensions:
|
|
52
|
+
- admonition
|
|
53
|
+
- attr_list
|
|
54
|
+
- def_list
|
|
55
|
+
- pymdownx.details
|
|
56
|
+
- pymdownx.highlight
|
|
57
|
+
- pymdownx.inlinehilite
|
|
58
|
+
- pymdownx.superfences
|
|
59
|
+
- tables
|
|
40
60
|
- toc:
|
|
41
61
|
permalink: true
|
|
42
|
-
- admonition
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Python API
|
|
2
|
+
|
|
3
|
+
The `exeplot` package exposes one function per plot type:
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
from exeplot import byte, diff, entropy, graph, nested_pie, pie
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`exeplot.__all__` lists the plot types that are available. `graph` is only
|
|
10
|
+
there when its [extra](installation.md#the-graph-extra) is installed.
|
|
11
|
+
|
|
12
|
+
Every function draws the plot, saves it and returns the **list of saved
|
|
13
|
+
image paths**:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
>>> from exeplot import pie
|
|
17
|
+
>>> pie("calc_packed.exe", donut=True, img_format="svg")
|
|
18
|
+
['calc_packed_pie.svg']
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Common keyword arguments
|
|
24
|
+
|
|
25
|
+
All plot functions accept these keyword arguments, on top of their own:
|
|
26
|
+
|
|
27
|
+
| Argument | Default | Description |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `no_title` | `False` | Do not display the title. |
|
|
30
|
+
| `no_legend` | `False` | Do not display the legend. |
|
|
31
|
+
| `img_name` | `<name>_<plot>` | Path of the image, with or without its extension. Missing folders are created. |
|
|
32
|
+
| `img_format` | `png` | Image format and file extension. |
|
|
33
|
+
| `dpi` | `300` | Resolution of the image. |
|
|
34
|
+
| `transparent` | `False` | Save with a transparent background. |
|
|
35
|
+
| `bbox_inches` | `"tight"` | Bounding box of the saved figure. |
|
|
36
|
+
| `grayscale` | `False` | Use the `gray` colormap instead of `colormap_main`. |
|
|
37
|
+
| `interactive_mode` | `False` | Open a Python console before saving (see [Interactive mode](cli/exeplot.md#common-options)). |
|
|
38
|
+
|
|
39
|
+
The defaults come from the [configuration file](cli/exeplot.md#configuration-file)
|
|
40
|
+
when it sets them.
|
|
41
|
+
|
|
42
|
+
### Fonts
|
|
43
|
+
|
|
44
|
+
`font_family` and `font_size` set the base font. Each text element can then
|
|
45
|
+
be changed with `<element>_font_family`, `<element>_font_size` and
|
|
46
|
+
`<element>_font_weight`, where `<element>` is one of:
|
|
47
|
+
|
|
48
|
+
| Element | Default size | Default weight | Used for |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| `title` | 1.6 × `font_size` | `bold` | The title. |
|
|
51
|
+
| `suptitle` | 1.2 × `font_size` | `normal` | The subtitle. |
|
|
52
|
+
| `annotation` | 0.5 × `font_size` | `normal` | The hash under the title. |
|
|
53
|
+
| `xlabel`, `ylabel` | `font_size` | `normal` | Axis labels and pie percentages. |
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
entropy("a.exe", title_font_size=20, title_font_weight="normal")
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## `byte`
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
byte(executable, height=600, grayscale=False, **kwargs)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Parameter | Description |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `executable` | Path to the executable. |
|
|
70
|
+
| `height` | Height of the image, in pixels. |
|
|
71
|
+
| `grayscale` | One byte per gray pixel, instead of three bytes per RGB pixel. |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## `entropy`
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
entropy(*filenames, labels=None, sublabel=None, scale=False, target=None, **kwargs)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Parameter | Description |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `*filenames` | Paths to one or more executables. At least one is required (`ValueError` otherwise). |
|
|
84
|
+
| `labels` | One label per file. Each item is a string, or a function that takes the [data dictionary](#entropy-data) of the file and returns a string. |
|
|
85
|
+
| `sublabel` | Text under each label: a key of `exeplot.plots.__common__.SUBLABELS` (`"ep"`, `"size"`, `"size-ep"`, `"size-ent"`, `"size-ep-ent"`), or a function of the data dictionary. `None` (the default here, unlike the CLI) shows no sublabel. Sublabels that mention the entry point are skipped for files without one. |
|
|
86
|
+
| `scale` | Draw every file on the scale of the first one. |
|
|
87
|
+
| `target` | Name shown in the title, instead of the first file name. |
|
|
88
|
+
| `n_samples` | Number of entropy samples per file (default `2048`). |
|
|
89
|
+
| `legend_location` | Matplotlib location of the legend (default `"lower center"`). A location ending with `left` or `right` puts the legend on one column, beside the plot. |
|
|
90
|
+
| `no_entrypoint` | Do not display the entry point. |
|
|
91
|
+
| `no_label` | Do not display the labels, sublabels and section names. |
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
entropy("calc_orig.exe", "calc_packed.exe", scale=True,
|
|
95
|
+
labels=["Original", lambda d: f"Packed ({d['type']})"], sublabel="size-ent")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Entropy data
|
|
99
|
+
|
|
100
|
+
`labels` and `sublabel` functions receive the dictionary returned by
|
|
101
|
+
`exeplot.plots.entropy.data(executable)`:
|
|
102
|
+
|
|
103
|
+
| Key | Description |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `name`, `hash`, `size`, `type` | File name, SHA-256, size in bytes and format (`PE`, `ELF` or `MachO`). |
|
|
106
|
+
| `entropy` | The entropy samples, divided by 8 (so from 0 to 1). |
|
|
107
|
+
| `entropy*` | The entropy of the whole file, in bits per byte. |
|
|
108
|
+
| `ep` | `(position on the plot, file offset, section name)` of the entry point, or `None`. |
|
|
109
|
+
| `sections` | `(start, end, name, average entropy)` tuples, in samples. |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## `pie`
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
pie(executable, donut=False, **kwargs)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
| Parameter | Description |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `executable` | Path to the executable. |
|
|
122
|
+
| `donut` | Draw a donut instead of a pie. |
|
|
123
|
+
| `no_label` | Do not display the percentages. |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## `nested_pie`
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
nested_pie(executable, **kwargs)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| Parameter | Description |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `executable` | Path to the executable. |
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## `diff`
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
diff(executable, executable2, legend1="", legend2="", **kwargs)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
| Parameter | Description |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `executable` | Path to the reference executable. |
|
|
148
|
+
| `executable2` | Path to the modified executable. Both must have the same format (`ValueError` otherwise). |
|
|
149
|
+
| `legend1`, `legend2` | Labels of the two bars. The file names are used when empty. |
|
|
150
|
+
| `no_colormap` | Do not display the color bar. `no_colorbar` is accepted too. |
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## `graph`
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
graph(executable, algorithm="fast", engine="default", **kwargs)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| Parameter | Description |
|
|
161
|
+
|---|---|
|
|
162
|
+
| `executable` | Path to the executable. |
|
|
163
|
+
| `algorithm` | `"fast"` (`CFGFast`) or `"emulated"` (`CFGEmulated`). |
|
|
164
|
+
| `engine` | `"default"`, `"pcode"` or `"vex"`. |
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Utilities: `exeplot.utils`
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from exeplot.utils import ensure_str, human_readable_size, ngrams_counts, ngrams_distribution, shannon_entropy
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
| Function | Description |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `shannon_entropy(data)` | Shannon entropy of a byte string, in bits per byte (0 to 8). |
|
|
177
|
+
| `human_readable_size(size, precision=0)` | Formats a size in bytes, for example `human_readable_size(1536, 1)` gives `"1.5KB"`. |
|
|
178
|
+
| `ensure_str(s, encoding="utf-8", errors="strict")` | Decodes `bytes`, falling back to Latin-1. Raises `TypeError` for other types. |
|
|
179
|
+
| `ngrams_counts(byte_obj, n=1, step=1)` | Sorted list of `(n-gram, count)` pairs, for `n` from 1 to 3. `byte_obj` is a byte string, or an object with a `bytes` attribute, whose result is then cached on the object. |
|
|
180
|
+
| `ngrams_distribution(byte_obj, n=1, step=1, n_most_common=None, n_exclude_top=0, exclude=None)` | Like `ngrams_counts`, keeping the `n_most_common` n-grams after leaving out the `n_exclude_top` most common ones and the n-grams in `exclude`. |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Constants
|
|
185
|
+
|
|
186
|
+
| Name | Description |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `exeplot.__version__` | Package version, read from `VERSION.txt`. |
|
|
189
|
+
| `exeplot.config` | The plot style options (see the [configuration file](cli/exeplot.md#configuration-file)). It is updated from `~/.exeplot.conf` before each plot. |
|
|
190
|
+
| `exeplot.logger` | The `exeplot` logger. |
|