运行constructs.py遇TypeError:PascalString缺失encoding参数求助
修复PascalString()缺少encoding参数的错误
PascalString() missing 1 required positional argument: 'encoding'
运行他人编写的constructs.py脚本时出现上述错误,以下是完整脚本代码与错误详情:
constructs.py
from construct import ( Array, Bytes, Struct, VarInt, Int8ub, Int16ub, Int24ub, Int32ub, PascalString, Prefixed, GreedyRange, Switch, Optional, ) ProtocolVersion = "version" / Struct( "major" / Int8ub, "minor" / Int8ub, ) TLSPlaintext = "TLSPlaintext" / Struct( "type" / Int8ub, ProtocolVersion, "length" / Int16ub, "fragment" / Bytes(lambda ctx: ctx.length), ) TLSCompressed = "TLSCompressed" / Struct( "type" / Int8ub, ProtocolVersion, "length" / Int16ub, "fragment" / Bytes(lambda ctx: ctx.length), ) TLSCiphertext = "TLSCiphertext" / Struct( "type" / Int8ub, ProtocolVersion, "length" / Int16ub, "fragment" / Bytes(lambda ctx: ctx.length), ) Random = "random" / Struct( "gmt_unix_time" / Int32ub, "random_bytes" / Bytes(28), ) SessionID = "session_id" / Struct( "length" / Int8ub, "session_id" / Bytes(lambda ctx: ctx.length), ) CipherSuites = "cipher_suites" / Struct( "length" / Int16ub, Array(lambda ctx: ctx.length // 2, "cipher_suites" / Int16ub), ) CompressionMethods = "compression_methods" / Struct( "length" / Int8ub, Array(lambda ctx: ctx.length, "compression_methods" / Int8ub), ) ServerName = Struct( "type" / Int8ub, "name" / PascalString("length" / Int16ub), ) SNIExtension = Prefixed( Int16ub, Struct( Int16ub, "server_names" / GreedyRange( "server_name" / Struct( "name_type" / Int8ub, "host_name" / PascalString("length" / Int16ub), ) ) ) ) ALPNExtension = Prefixed( Int16ub, Struct( Int16ub, "alpn_protocols" / GreedyRange( "name" / PascalString(Int8ub), ), ) ) UnknownExtension = Struct( "bytes" / PascalString("length" / Int16ub) ) Extension = "Extension" / Struct( "type" / Int16ub, Switch( lambda ctx: ctx.type, { 0x00: SNIExtension, 0x10: ALPNExtension, }, default=UnknownExtension ) ) extensions = "extensions" / Struct( Int16ub, "extensions" / GreedyRange(Extension) ) ClientHello = "ClientHello" / Struct( ProtocolVersion, Random, SessionID, CipherSuites, CompressionMethods, extensions, ) ServerHello = "ServerHello" / Struct( ProtocolVersion, Random, SessionID, "cipher_suite" / Bytes(2), "compression_method" / Int8ub, extensions, ) ClientCertificateType = "certificate_types" / Struct( "length" / Int8ub, Array(lambda ctx: ctx.length, "certificate_types" / Int8ub), ) SignatureAndHashAlgorithm = "algorithms" / Struct( "hash" / Int8ub, "signature" / Int8ub, ) SupportedSignatureAlgorithms = "supported_signature_algorithms" / Struct( "supported_signature_algorithms_length" / Int16ub, # TODO: Reject packets of length 0 Array( lambda ctx: ctx.supported_signature_algorithms_length / 2, SignatureAndHashAlgorithm, ), ) DistinguishedName = "certificate_authorities" / Struct( "length" / Int16ub, "certificate_authorities" / Bytes(lambda ctx: ctx.length), ) CertificateRequest = "CertificateRequest" / Struct( ClientCertificateType, SupportedSignatureAlgorithms, DistinguishedName, ) ServerDHParams = "ServerDHParams" / Struct( "dh_p_length" / Int16ub, "dh_p" / Bytes(lambda ctx: ctx.dh_p_length), "dh_g_length" / Int16ub, "dh_g" / Bytes(lambda ctx: ctx.dh_g_length), "dh_Ys_length" / Int16ub, "dh_Ys" / Bytes(lambda ctx: ctx.dh_Ys_length), ) PreMasterSecret = "pre_master_secret" / Struct( ProtocolVersion, "random_bytes" / Bytes(46), ) ASN1Cert = "ASN1Cert" / Struct( "length" / Int32ub, "asn1_cert" / Bytes(lambda ctx: ctx.length), ) Certificate = "Certificate" / Struct( # TODO: Reject packets with length > 2 ** 24 - 1 "certificates_length" / Int32ub, "certificates_bytes" / Bytes(lambda ctx: ctx.length), ) Handshake = "Handshake" / Struct( "msg_type" / Int8ub, "length" / Int24ub, "body" / Bytes(lambda ctx: ctx.length), ) Alert = "Alert" / Struct( "level" / Int8ub, "description" / Int8ub, )
错误信息
File "/root/bdfproxy/mitmproxy/mitmproxy/contrib/tls/_constructs.py", line 71, in <module> "name" / PascalString("length" / Int16ub), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: PascalString() missing 1 required positional argument: 'encoding'
修复方案
错误原因是当前使用的construct库版本较新,而原脚本基于旧版本编写。新版本中PascalString必须传入encoding参数指定字符串编码。
需要修改脚本中所有PascalString的调用,添加编码参数(TLS协议相关字段通常用'ascii',也可根据实际需求用'utf-8'):
- ServerName结构体:
ServerName = Struct( "type" / Int8ub, "name" / PascalString("length" / Int16ub, encoding='ascii'), )
- SNIExtension中的host_name字段:
"host_name" / PascalString("length" / Int16ub, encoding='ascii'),
- ALPNExtension中的name字段:
"name" / PascalString(Int8ub, encoding='ascii'),
- UnknownExtension结构体:
UnknownExtension = Struct( "bytes" / PascalString("length" / Int16ub, encoding='ascii') )
备选方案:降级construct库
如果不想修改代码,可以降级到不需要encoding参数的旧版本(比如construct<2.10),执行命令:
pip install construct==2.9.52
内容的提问来源于stack exchange,提问作者MadDemon
相关产品推荐
相关产品推荐

