Skip to content

Instantly share code, notes, and snippets.

@zylo117
Last active February 19, 2024 09:03
Show Gist options
  • Save zylo117/cb2794c84b459eba301df7b82ddbc1ec to your computer and use it in GitHub Desktop.
Save zylo117/cb2794c84b459eba301df7b82ddbc1ec to your computer and use it in GitHub Desktop.
python zip decryption in cython
# cython: language_level=3
# distutils: language = c
# cython: cdivision = True
# cython: boundscheck = False
# cython: wraparound = False
# cython: nonecheck = False
# cython: profile = False
# Author: Zylo117
"""
cython implementation of zip decryption
"""
from cython.view cimport array as cvarray
def _gen_crc(long crc):
cdef int j
cdef long a = 0xEDB88320
for j in range(8):
if crc & 1:
crc = (crc >> 1) ^ a
else:
crc >>= 1
return crc
def _ZipDecrypter_C(bytes pwd):
cdef long key0 = 305419896
cdef long key1 = 591751049
cdef long key2 = 878082192
cdef int p, i
# cdef list crctable = list(map(_gen_crc, range(256)))
cdef long[:] crctable = cvarray(shape=(256,), itemsize=sizeof(long), format="l")
for i in range(256):
crctable[i] = _gen_crc(i)
def crc32(long ch, long crc):
cdef int a = 8
cdef int b = 0xFF
"""Compute the CRC32 primitive on one byte."""
return (crc >> a) ^ crctable[(crc ^ ch) & b]
def update_keys(long c):
nonlocal key0, key1, key2
cdef int a = 0xFF
cdef long b = 0xFFFFFFFF
cdef int d = 134775813
key0 = crc32(c, key0)
key1 = (key1 + (key0 & a)) & b
key1 = (key1 * d + 1) & b
key2 = crc32(key1 >> 24, key2)
for p in pwd:
update_keys(p)
def decrypter(bytes data):
"""Decrypt a bytes object."""
cdef long k
cdef unsigned int c
cdef unsigned char cb
cdef bytearray result = bytearray()
for c in data:
k = key2 | 2
c ^= ((k * (k ^ 1)) >> 8) & 0xFF
update_keys(c)
cb = c
result.append(cb)
return bytes(result)
return decrypter
import os
from glob import glob
from setuptools import setup
from Cython.Build import cythonize
from Cython.Distutils import Extension
extra_compile_args = ['-O3', '-ffast-math', '-fopenmp']
extra_link_args = ['-fopenmp']
lib_modules = []
lib_modules.append(
Extension('dezip',
['dezip.pyx'],
language='c',
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,),
)
setup(
name='dezip',
zip_safe=False,
ext_modules=cythonize(lib_modules, language_level=3, compiler_directives={'always_allow_keywords': True}),
)
import zipfile
from dezip import _ZipDecrypter_C
setattr(zipfile, '_ZipDecrypter', _ZipDecrypter_C)
z = zipfile.ZipFile('./test.zip', 'r')
z.extractall('/tmp/123', None, b'password')
@zylo117
Copy link
Author

zylo117 commented Jun 6, 2022

Just run

pip3 install cython
python3 setup.py build_ext --inplace
python3 test.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment