Add PyPI support

This commit is contained in:
You Nakatsuru
2018-05-07 23:23:42 +09:00
parent 8f85100ac8
commit bb4432f3f2
4 changed files with 80 additions and 59 deletions
+16 -11
View File
@@ -4,25 +4,30 @@ Python implementation of LZNT1 compression/decompression.
Note that the compression algorithm is not perfect, but compressed data can be decompressed by RtlDecompressBuffer.
# How to use
## Install
```
pip install lznt1
```
## Compress / decompress
```
>>> import lznt1
>>> compressed = lznt1.compress(data)
>>> decompressed = lznt1.decompress(data)
>>> decompressed = lznt1.decompress(compressed)
```
## Test
```
C:\Users\you\Desktop>lznt1.py lznt1.py
[*] input size = 6610 bytes, sha1 hash = 933dffa94c6ad78fb7f0396b2b1c39aa90065d57
[*] size of compressed1: 2961
[*] size of compressed2: 2512
[*] sha1 hash of compressed1: d1116a2e5b0471de956e0df031466231c8cc7831
[*] sha1 hash of compressed2: 6e8262dbe4988fe9b6d119b203c94201b0f6a4c4
[*] sha1 hash of decompressed11: 933dffa94c6ad78fb7f0396b2b1c39aa90065d57
[*] sha1 hash of decompressed12: 933dffa94c6ad78fb7f0396b2b1c39aa90065d57
[*] sha1 hash of decompressed21: 933dffa94c6ad78fb7f0396b2b1c39aa90065d57
[*] sha1 hash of decompressed22: 933dffa94c6ad78fb7f0396b2b1c39aa90065d57
C:\Users\you\Desktop\ln>python test.py lznt1.py
[*] input size = 4067 bytes, sha1 hash = 9887522d4088152ca434a5f275adcd99c2de338d
[*] size of compressed1: 1280
[*] size of compressed2: 1553
[*] sha1 hash of compressed1: 64b9b5f92274e60d10f3ef0e517f563cc8d46bd6
[*] sha1 hash of compressed2: 92e737ee1d2b468800169cc7b28854b392ac8395
[*] sha1 hash of decompressed11: 9887522d4088152ca434a5f275adcd99c2de338d
[*] sha1 hash of decompressed12: 9887522d4088152ca434a5f275adcd99c2de338d
[*] sha1 hash of decompressed21: 9887522d4088152ca434a5f275adcd99c2de338d
[*] sha1 hash of decompressed22: 9887522d4088152ca434a5f275adcd99c2de338d
```
## References
+1 -48
View File
@@ -1,8 +1,6 @@
import struct
import sys
import copy
import ctypes
from hashlib import sha1
def _decompress_chunk(chunk):
size = len(chunk)
@@ -103,7 +101,7 @@ def _compress_chunk(chunk):
# try to find more compressed pattern
offset2, length2 = _find(chunk[:len(chunk) - len(blob)+1], blob[1:], max_len)
if length < length2+1:
if length < length2:
length = 0
if length > 0:
@@ -138,48 +136,3 @@ def compress(buf, chunk_size=0x1000):
buf = buf[chunk_size:]
return out
def main():
import argparse
parser = argparse.ArgumentParser(description='LZNT1 tester (You must run this on Windows)')
parser.add_argument("FILE", help="Specify a file for compression/decompression test")
args = parser.parse_args()
with open(args.FILE, 'rb') as fp:
data = fp.read()
#data = "Hello world!" * 800
print('[*] input size = {} bytes, sha1 hash = {}'.format(len(data), sha1(data).hexdigest()))
compressed1 = compress(data)
decompressed11 = decompress(compressed1)
buf_decompressed = ctypes.create_string_buffer(len(data)*2)
final_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlDecompressBuffer(2, buf_decompressed, ctypes.sizeof(buf_decompressed), ctypes.c_char_p(compressed1), len(compressed1), ctypes.byref(final_size))
decompressed12 = buf_decompressed.raw[:final_size.value]
buf_compressed = ctypes.create_string_buffer(len(data)*2)
work_size = ctypes.c_ulong(0)
work_frag_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlGetCompressionWorkSpaceSize(2, ctypes.byref(work_size), ctypes.byref(work_frag_size))
workspace = ctypes.create_string_buffer(work_size.value)
final_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlCompressBuffer(2, ctypes.c_char_p(data), len(data), buf_compressed, ctypes.sizeof(buf_compressed), 4096, ctypes.byref(final_size), workspace)
compressed2 = buf_compressed.raw[:final_size.value]
decompressed21 = decompress(compressed2)
buf_decompressed = ctypes.create_string_buffer(len(data)*2)
final_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlDecompressBuffer(2, buf_decompressed, ctypes.sizeof(buf_decompressed), buf_compressed, ctypes.sizeof(buf_compressed), ctypes.byref(final_size))
decompressed22 = buf_decompressed.raw[:final_size.value]
print('[*] size of compressed1: {}'.format(len(compressed1)))
print('[*] size of compressed2: {}'.format(len(compressed2)))
print('[*] sha1 hash of compressed1: {}'.format(sha1(compressed1).hexdigest()))
print('[*] sha1 hash of compressed2: {}'.format(sha1(compressed2).hexdigest()))
print('[*] sha1 hash of decompressed11: {}'.format(sha1(decompressed11).hexdigest()))
print('[*] sha1 hash of decompressed12: {}'.format(sha1(decompressed12).hexdigest()))
print('[*] sha1 hash of decompressed21: {}'.format(sha1(decompressed21).hexdigest()))
print('[*] sha1 hash of decompressed22: {}'.format(sha1(decompressed22).hexdigest()))
if __name__ == '__main__':
main()
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env python
from setuptools import setup
setup(
name="lznt1",
version="0.1.2",
author="You Nakatsuru",
author_email="you0708@users.noreply.github.com",
license="Apache License 2.0",
description="Python module for LZNT1 compression/decompression",
long_description="A Python module which provides compress/decompress features uzing LZNT1 algorithm. This doesn't reuqire ntdll.RtlCompressBuffer/RtlDecompressBuffer",
py_modules=["lznt1"],
url="https://github.com/you0708/lznt1/",
)
Executable
+49
View File
@@ -0,0 +1,49 @@
import argparse
import ctypes
from hashlib import sha1
import lznt1
parser = argparse.ArgumentParser(description='LZNT1 tester (You must run this on Windows)')
parser.add_argument("FILE", help="Specify a file for compression/decompression test")
args = parser.parse_args()
def main():
with open(args.FILE, 'rb') as fp:
data = fp.read()
#data = "Hello world!" * 800
print('[*] input size = {} bytes, sha1 hash = {}'.format(len(data), sha1(data).hexdigest()))
compressed1 = lznt1.compress(data)
decompressed11 = lznt1.decompress(compressed1)
buf_decompressed = ctypes.create_string_buffer(len(data)*2)
final_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlDecompressBuffer(2, buf_decompressed, ctypes.sizeof(buf_decompressed), ctypes.c_char_p(compressed1), len(compressed1), ctypes.byref(final_size))
decompressed12 = buf_decompressed.raw[:final_size.value]
buf_compressed = ctypes.create_string_buffer(len(data)*2)
work_size = ctypes.c_ulong(0)
work_frag_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlGetCompressionWorkSpaceSize(2, ctypes.byref(work_size), ctypes.byref(work_frag_size))
workspace = ctypes.create_string_buffer(work_size.value)
final_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlCompressBuffer(2, ctypes.c_char_p(data), len(data), buf_compressed, ctypes.sizeof(buf_compressed), 4096, ctypes.byref(final_size), workspace)
compressed2 = buf_compressed.raw[:final_size.value]
decompressed21 = lznt1.decompress(compressed2)
buf_decompressed = ctypes.create_string_buffer(len(data)*2)
final_size = ctypes.c_ulong(0)
ctypes.windll.ntdll.RtlDecompressBuffer(2, buf_decompressed, ctypes.sizeof(buf_decompressed), buf_compressed, ctypes.sizeof(buf_compressed), ctypes.byref(final_size))
decompressed22 = buf_decompressed.raw[:final_size.value]
print('[*] size of compressed1: {}'.format(len(compressed1)))
print('[*] size of compressed2: {}'.format(len(compressed2)))
print('[*] sha1 hash of compressed1: {}'.format(sha1(compressed1).hexdigest()))
print('[*] sha1 hash of compressed2: {}'.format(sha1(compressed2).hexdigest()))
print('[*] sha1 hash of decompressed11: {}'.format(sha1(decompressed11).hexdigest()))
print('[*] sha1 hash of decompressed12: {}'.format(sha1(decompressed12).hexdigest()))
print('[*] sha1 hash of decompressed21: {}'.format(sha1(decompressed21).hexdigest()))
print('[*] sha1 hash of decompressed22: {}'.format(sha1(decompressed22).hexdigest()))
if __name__ == '__main__':
main()