我一直在努力让代理工作。我需要解密来自服务器和客户端的数据包((这可能是乱序...)),然后解压缩除数据包标题之外的所有内容。
前两个数据包((10101
和20104
))未经过压缩,无法正确解密,破坏和反编译。
zlib.error: Error -5 while decompressing data: incomplete or truncated stream
当我尝试解压缩数据包的加密版本时出现相同的错误。
当我包含数据包标头时,我得到一个随机选择的-3
错误。
我也尝试将-zlib.MAX_WBITS
更改为zlib.MAX_WBITS
以及其他一些,但仍然会遇到同样的错误。
这是代码;
import socket, sys, os, struct, zlib
from Crypto.Cipher import ARC4 as rc4
cwd = os.getcwd()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.2.12',9339))
s.listen(1)
client, addr = s.accept()
key = "fhsd6f86f67rt8fw78fw789we78r9789wer6renonce"
cts = rc4.new(key)
stc = rc4.new(key)
skip = 'a'*len(key)
cts.encrypt(skip)
stc.encrypt(skip)
ss.connect(('game.boombeachgame.com',9339))
ss.settimeout(0.25)
s.settimeout(0.25)
def io():
while True:
try:
pack = client.recv(65536)
decpack = cts.decrypt(pack[7:])
msgid, paylen = dechead(pack)
if msgid != 10101:
decopack = zlib.decompress(decpack, -zlib.MAX_WBITS)
print "ID:",msgid
print "Payload Length",paylen
print "Payload:\n",decpack
ss.send(pack)
dump(msgid, decpack)
except socket.timeout:
pass
try:
pack = ss.recv(65536)
msgid, paylen = dechead(pack)
decpack = stc.decrypt(pack[7:])
if msgid != 20104:
decopack = zlib.decompress(decpack, -zlib.MAX_WBITS)
print "ID:",msgid
print "Payload Length",paylen
print "Payload:\n",decpack
client.send(pack)
dump(msgid, decpack)
except socket.timeout:
pass
def dump(msgid, decpack):
global cwd
pdf = open(cwd+"/"+str(msgid)+".bin",'wb')
pdf.write(decpack)
pdf.close()
def dechead(pack):
msgid = struct.unpack('>H', pack[0:2])[0]
print int(struct.unpack('>H', pack[5:7])[0])
payload_bytes = struct.unpack('BBB', pack[2:5])
payload_len = ((payload_bytes[0] & 255) << 16) | ((payload_bytes[1] & 255) << 8) | (payload_bytes[2] & 255)
return msgid, payload_len
io()
我意识到它很乱,杂乱而且非常糟糕,但这一切都按预期工作减去减压。
是的,我确信数据包是zlib
压缩的。
这里出了什么问题,为什么?
完整追溯:
Traceback (most recent call last):
File "bbproxy.py", line 68, in <module>
io()
File "bbproxy.py", line 33, in io
decopack = zlib.decompress(decpack, zlib.MAX_WBITS)
zlib.error: Error -5 while decompressing data: incomplete or truncated stream
答案 0 :(得分:2)
我尝试使用zlib和Python 2.7解压缩文件时遇到了同样的问题。问题与流(或文件输入)的大小有关,超过了可以存储在内存中的大小。 (我的电脑有16 GB的内存,所以它没有超过物理内存大小,但缓冲区默认大小是16384.)
最简单的修复方法是更改代码:
import zlib
f_in = open('my_data.zz', 'rb')
comp_data = f_in.read()
data = zlib.decompress(comp_data)
要:
import zlib
f_in = open('my_data.zz', 'rb')
comp_data = f_in.read()
zobj = zlib.decompressojb() # obj for decompressing data streams that won’t fit into memory at once.
data = zobj.decompress(comp_data)
它通过缓冲流来处理流,并以可管理的块的形式输入解压缩器。
我希望这有助于您节省时间来解决问题。我得到了我朋友乔丹的帮助!我正在尝试各种不同的窗口大小(wbits)。
答案 1 :(得分:0)
编辑:即使以下内容在部分gz文件上工作,当我解压缩时,我得到的还是空字节数组,尽管函数成功,但我尝试的所有内容始终会返回空。最终,我依靠运行始终有效的gunzip
进程:
def gunzip_string(the_string):
proc = subprocess.Popen('gunzip',stdout=subprocess.PIPE,
stdin=subprocess.PIPE, stderr=subprocess.DEVNULL)
proc.stdin.write(the_body)
proc.stdin.close()
body = proc.stdout.read()
proc.wait()
return body
请注意,上面的代码可以返回非零错误代码,指示输入字符串不完整,但仍执行解压缩,因此吞下了stderr。您可能希望检查错误以允许这种情况。
/编辑
我认为zlib解压缩库引发异常,因为您没有传递完整的文件,而只是传递了65536块ss.recv(65536)
。如果您对此进行更改:
decopack = zlib.decompress(decpack, -zlib.MAX_WBITS)
到
decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
decopack = decompressor(decpack)
它应该可以通过这种方式处理流媒体。
文档say
zlib.decompressobj - Returns a decompression object, to be used for decompressing data streams that won’t fit into memory at once.
或者即使它确实适合内存,您可能只想做文件的开头
答案 2 :(得分:-1)
试试这个:
decopack = zlib.decompressobj()。decompress(decpack,zlib.MAX_WBITS)