Декомпилировать exe-файлы Python в сценарии Python
Декомпилировать exe-файлы Python в сценарии Python

Предисловие

  • Воля Python Исполняемый документ(.exe)Декомпилироватьдля Python Скриптда Интересная техническая задача, которая помогает нам понять, как работает программа и какую логику и алгоритмы она может содержать. Хотя декомпилировать — непростая задача и может оказаться неэффективной для программ, использующих различные меры защиты, в целом Python Исполняемый документ,мы можем попробоватьиспользоватьнекоторые инструменты для выполнения Декомпилировать。
  • Давайте научимся Воля Python Исполняемый документ(.exe)Декомпилироватьдля Python Скрипт。

Версия

  • Python 3.9

Декомпилировать

  • Декомпилированиеда Воля Процесс восстановления скомпилированного кода программы до исходного исходного кода. существовать Python Из-за его интерпретируемой природы обычно не существует сгенерированного двоичного документа, такого как компилируемый язык, но мы можем Python Скрипт преобразуется в байт-код документа (.pyc), а .exe документв целомда由 pyinstaller、cx_Freeze Компилируется и генерируется другими инструментами.

Python Исполняемый документ(.exe)Декомпилировать

  • Python Исполняемый документ(.exe)Декомпилироватьдля Python Скрипт в основном делится на два этапа: (1) от .exe документсередина Извлечь файлы pyc (2)Воля pyc файл конвертирован в Python Скрипт。

Упакуйте простой исполняемый файл .exe.

Язык кода:python
кодКоличество запусков:0
копировать
# student.py
class Student:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def get_name(self):
        return self.name

    def get_age(self):
        return self.age

    def get_gender(self):
        return self.gender

    def set_name(self, name):
        self.name = name

    def set_age(self, age):
        self.age = age

    def set_gender(self, gender):
        self.gender = gender

    def display_info(self):
        print("Name:", self.name)
        print("Age:", self.age)
        print("Gender:", self.gender)

# main.py
import time

from student import Student

if __name__ == "__main__":
    # Create a student object
    student1 = Student("Alice", 20, "Female")

    # Display student information
    student1.display_info()

    # Update student information
    student1.set_age(21)
    student1.display_info()

    time.sleep(10)

# использовать pyinstaller построить исполняемый файл .exe
pyinstaller --onefile   -p venv/Lib/site-packages .\print-student\main.py

Извлечь файлы pyc

использовать Скриптизвлекать

Язык кода:python
кодКоличество запусков:0
копировать
# использовать pyi-archive_viewer Проверятьдокументиизвлекать
> pyi-archive_viewer .\main.exe

Options in 'main.exe' (PKG/CArchive):
 pyi-contents-directory _internal
Contents of 'main.exe' (PKG/CArchive):
 position, length, uncompressed_length, is_compressed, typecode, name
 0, 199, 269, 1, 'm', 'struct'
 199, 2008, 3700, 1, 'm', 'pyimod01_archive'
 2207, 7671, 17413, 1, 'm', 'pyimod02_importers'
 9878, 1760, 4029, 1, 'm', 'pyimod03_ctypes'
 11638, 644, 1074, 1, 'm', 'pyimod04_pywin32'
 12282, 603, 851, 1, 's', 'pyiboot01_bootstrap'
 12885, 229, 295, 1, 's', 'main'
......
 4721057, 408332, 1123832, 1, 'b', 'unicodedata.pyd'
 5129389, 702999, 702999, 0, 'z', 'PYZ-00.pyz'
?
U: go up one level
O <name>: open embedded archive with given name // Откройте пакет для просмотра документа
X <name>: extract file with given name // извлекатьдокумент
S: list the contents of current archive again
Q: quit
? x main        
Output filename? main.pyc
? o PYZ-00.pyz
Contents of 'PYZ-00.pyz' (PYZ):
 is_package, position, length, name
 0, 17, 2647, '_compat_pickle'
......
 0, 543553, 531, 'student'
 0, 544084, 19733, 'subprocess'
 0, 563817, 27425, 'tarfile'
 0, 591242, 5936, 'textwrap'
 0, 597178, 15612, 'threading'
 0, 612790, 1398, 'token'
 0, 614188, 8969, 'tokenize'
 0, 623157, 6659, 'tracemalloc'
 0, 629816, 27711, 'typing'
 1, 657527, 70, 'urllib'
 0, 657597, 13861, 'urllib.parse'
 0, 671458, 2188, 'uu'
 0, 673646, 26812, 'zipfile'
? x student
Output filename? student.pyc
? ls
U: go up one level
O <name>: open embedded archive with given name
X <name>: extract file with given name
S: list the contents of current archive again
Q: quit
? q
  • В описанной выше операции мы используем pyi-archive_viewer извлеченный main.pyc и student.pyc документ,В то время все могли ясно видеть недостатки,То есть нужно вручную излечивать,Это очень хлопотно для больших проектов.,рекомендоватьиспользоватьинструменты нижеизвлекать。

Извлечение с помощью инструментов

  • Мы можем использовать проекты с открытым исходным кодом Python-exe-unpacker серединаиз Скрипт pyinstxtractor.py Скриптруководитьизвлекать,адрес:https://github.com/countercept/Python-exe-unpacker
Язык кода:python
кодКоличество запусков:0
копировать
\print-student> Python pyinstxtractor.py .\main.exe                                            
DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
  import imp
[*] Processing .\main.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 309
[*] Length of package: 5835756 bytes
[*] Found 59 files in CArchive
[*] Beginning extraction...please standby
[*] Found 81 files in PYZ archive
[*] Successfully extracted pyinstaller archive: .\main.exe

You can now use a python decompiler on the pyc files within the extracted directory
После распаковки документа
После распаковки документа
После распаковки документа
После распаковки документа

Воля .pyc файл конвертирован в Python Скрипт

Вступительный класс бега

  • Для от pyinstaller извлеченный pyc документи不能直接Декомпилировать,Вступительный класс бегу всего 16 байт magic и Временные метки удаляются. Если вы выполняете Декомпилирование напрямую, например, выполняя uncompyle6 main.pyc,Будет сообщено о следующей ошибке:
Язык кода:python
кодКоличество запусков:0
копировать
ImportError: Unknown magic number 227 in main.pyc
  • мы можемиспользоватьподдерживать16进制编辑из文本编辑器руководить处理,например:UltraEdit32
Сравнение различий
Сравнение различий
  • Вы можете видеть, что первые 16 байт были удалены.,Первые четыре байта дамагического значения,Эти четыре байта будут меняться вместе с системой и PythonВерсия.,Нужно быть последовательным. Последние четыре байта содержат метку времени и некоторую другую информацию.,Вы можете заполнить его по своему желанию。мы можем通过 UltraEdit32 Добавьте сообщение обратно в документ из-за болезни.
  • Здесь я написал python Скрипт реализует этот процесс:
Язык кода:python
кодКоличество запусков:0
копировать
// Прочитайте первые 4 байта pycдокумента, извлеченного из каталога pyz, в качестве эталона.
pyz_dir = "./main.exe_extracted/PYZ-00.pyz_extracted"
for pyc_file in os.listdir(pyz_dir):
    if pyc_file.endswith(".pyc"):
        file = f"{pyz_dir}/{pyc_file}"
        break
with open(file, "rb") as f:
    head = f.read(4)

// Полный документ начального класса
if os.path.exists("pycfile_tmp"):
    shutil.rmtree("pycfile_tmp")
os.mkdir("pycfile_tmp")
main_file_result = "pycfile_tmp/main.pyc"
with open("./main.exe_extracted/main.pyc", "rb") as read, open(main_file_result, "wb") as write:
    write.write(head)
    write.write(b"\0" * 12)
    write.write(read.read())

Нет Вступительный класс бега

  • Для прогонов без ввода pycdocument начинается с 12 байтов и пропускает 4 байта.
Сравнение различий
Сравнение различий
Язык кода:python
кодКоличество запусков:0
копировать
# Заполните документ категории запрещения въезда.
pyz_dir = "main.exe_extracted/PYZ-00.pyz_extracted"
for pyc_file in os.listdir(pyz_dir):
    pyc_file_src = f"{pyz_dir}/{pyc_file}"
    pyc_file_dest = f"pycfile_tmp/{pyc_file}"
    print(pyc_file_src, pyc_file_dest)
    with open(pyc_file_src, "rb") as read, open(pyc_file_dest, "wb") as write:
        write.write(read.read(12))
        write.write(b"\0"*4)
        write.write(read.read())

После преобразования и завершения pyc документ

uncompyle6 Декомпилировать
Язык кода:python
кодКоличество запусков:0
копировать
pip install uncompyle6
uncompyle6 xxx.pyc>xxx.py

Например: uncompile6 .\pycfile_tmp\main.pyc
# uncompyle6 version 3.9.0
# Python bytecode version base 3.9.0 (3425)
# Decompiled from: Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: main.py

Unsupported Python version, 3.9.0, for decompilation


# Unsupported bytecode in file .\pycfile_tmp\main.pyc
# Unsupported Python version, 3.9.0, for decompilation
  • из-за меняиспользоватьизда 3.9.0 Версия,uncompyle6 Больше не поддерживается decompilation,Друзья, кому интересно, могут попробовать.
Онлайн-инструменты
Декомпилироватьрезультат
Декомпилироватьрезультат

Возможные проблемы

PYZ-00.pyz_extracted Файл пуст

  • строить .exe документ Python Версияи При распаковке пакетаиспользоватьиз Версиянепоследовательный,например我использовать Python 2.7 Чтобы распаковать:
Язык кода:python
кодКоличество запусков:0
копировать
>Python .\pyinstxtractor.py .\main.exe

[*] Processing .\main.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 312
[*] Length of package: 7675728 bytes
[*] Found 60 files in CArchive
[*] Beginning extraction...please standby
[!] Warning: The script is running in a different python version than the one used to build the executable
    Run this script in Python312 to prevent extraction errors(if any) during unmarshalling
[!] Unmarshalling FAILED. Cannot extract PYZ-00.pyz. Extracting remaining files.
[*] Successfully extracted pyinstaller archive: .\main.exe

You can now use a python decompiler on the pyc files within the extracted directory

# Посмотреть разархивированный документ
\print-student\main.exe_extracted\PYZ-00.pyz_extracted> ls
\print-student\main.exe_extracted\PYZ-00.pyz_extracted>

Как предотвратить блокировку exe программой Декомпилировать

  • Мы можем добавить после команды упаковки --key параметры для выполнения шифрования, например:
Язык кода:python
кодКоличество запусков:0
копировать
 pyinstaller --onefile   -p venv/Lib/site-packages .\print-student\main.py --key '1234'
  • После повторной распаковки промежуточный результат извлечения становится .pyc.encrypted,Невозможно нормально функционировать Декомпилировать。

думать

  • Bytecode encryption was removed in PyInstaller v6.0. Please remove your --key=xxx argument. For the rationale and alternatives see https://github.com/pyinstaller/pyinstaller/pull/6999
  • можно увидеть в PyInstaller v6.0 Параметры шифрования устарели. Вы можете сказать нам, почему.

Подвести итог

  • Декомпилировать Python Исполняемый документ Может помочь нам понять, как работает программаилогика,Но на практике это может быть ограничено многими факторами. Для сложных процедур,Декомпилировать может быть лишь первым шагом к пониманию того, как это работает.,Могут потребоваться дальнейшие анализы и исследования. наконец,Нам нужно понять, что технологии — это не хорошо и не плохо.,Необходимо соблюдать основы морали и права.

Профиль

👋 привет, я Lorin Лорейн, один Java 后端技术开发者!девиз:Technology has the power to make the world a better place.

🚀 Моя страсть к технологиям — это моя мотивация продолжать учиться и делиться ими. Мой блог — это место об экосистеме Java, серверной разработке и последних технологических тенденциях.

🧠 Будучи энтузиастом серверных технологий Java, я не только с энтузиазмом изучаю новые возможности языка и глубину технологий, но также с энтузиазмом делюсь своими идеями и передовым опытом. Я верю, что обмен знаниями и сотрудничество с сообществом могут помочь нам расти вместе.

💡 В моем блоге вы можете найти информацию об основных концепциях Java, JVM. В основе технологии лежат общие фреймворки, такие как Spring и Mybatis. 、Управление базами данных, например MySQL、RabbitMQ、Rocketmq и другое промежуточное программное обеспечение для сообщений、性能优化等内容из深入文章。Я также Воля分享Некоторый编程技巧и解决问题из方法,Чтобы помочь вам лучше освоить программирование на Java.

🌐 Я поощряю взаимодействие и создание сообщества,Поэтому, пожалуйста, оставляйте свои вопросы, предложения или запросы по теме.,Дайте мне знать, что вас интересует. также,Я Воля делюсь последними новостями Интернета и технологий,Чтобы вы всегда были в курсе последних событий в мире технологий. Я с нетерпением жду совместной работы с вами на пути к технологиям,Давайте исследуем безграничные возможности мира технологий.

📖 Следите за обновлениями моего блога и давайте вместе стремиться к техническому совершенству.

Я участвую в последнем конкурсе эссе для специального учебного лагеря Tencent Technology Creation 2024. Приходите и разделите со мной приз!

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.