From cc338f46f03a8f009e9a8fdbb7fbc62b82d67841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20=E2=84=B1an?= Date: Tue, 14 May 2019 22:01:13 +0200 Subject: [PATCH] Delete structure.py --- py2-kms/structure.py | 728 ------------------------------------------- 1 file changed, 728 deletions(-) delete mode 100644 py2-kms/structure.py diff --git a/py2-kms/structure.py b/py2-kms/structure.py deleted file mode 100644 index 3b90ba4..0000000 --- a/py2-kms/structure.py +++ /dev/null @@ -1,728 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2003-2016 CORE Security Technologies -# -# This software is provided under under a slightly modified version -# of the Apache Software License. See the accompanying LICENSE file -# for more information. -# - -""" -Stripped down version of: https://github.com/CoreSecurity/impacket/blob/master/impacket/structure.py -with modifications in the function dump(...). -""" - -from struct import pack, unpack, calcsize - -class Structure: - """ sublcasses can define commonHdr and/or structure. - each of them is an tuple of either two: (fieldName, format) or three: (fieldName, ':', class) fields. - [it can't be a dictionary, because order is important] - - where format specifies how the data in the field will be converted to/from bytes (string) - class is the class to use when unpacking ':' fields. - - each field can only contain one value (or an array of values for *) - i.e. struct.pack('Hl',1,2) is valid, but format specifier 'Hl' is not (you must use 2 dfferent fields) - - format specifiers: - specifiers from module pack can be used with the same format - see struct.__doc__ (pack/unpack is finally called) - x [padding byte] - c [character] - b [signed byte] - B [unsigned byte] - h [signed short] - H [unsigned short] - l [signed long] - L [unsigned long] - i [signed integer] - I [unsigned integer] - q [signed long long (quad)] - Q [unsigned long long (quad)] - s [string (array of chars), must be preceded with length in format specifier, padded with zeros] - p [pascal string (includes byte count), must be preceded with length in format specifier, padded with zeros] - f [float] - d [double] - = [native byte ordering, size and alignment] - @ [native byte ordering, standard size and alignment] - ! [network byte ordering] - < [little endian] - > [big endian] - - usual printf like specifiers can be used (if started with %) - [not recommeneded, there is no why to unpack this] - - %08x will output an 8 bytes hex - %s will output a string - %s\\x00 will output a NUL terminated string - %d%d will output 2 decimal digits (against the very same specification of Structure) - ... - - some additional format specifiers: - : just copy the bytes from the field into the output string (input may be string, other structure, or anything responding to __str__()) (for unpacking, all what's left is returned) - z same as :, but adds a NUL byte at the end (asciiz) (for unpacking the first NUL byte is used as terminator) [asciiz string] - u same as z, but adds two NUL bytes at the end (after padding to an even size with NULs). (same for unpacking) [unicode string] - w DCE-RPC/NDR string (it's a macro for [ ' 2: - dataClassOrCode = field[2] - try: - self[field[0]] = self.unpack(field[1], data[:size], dataClassOrCode = dataClassOrCode, field = field[0]) - except Exception,e: - e.args += ("When unpacking field '%s | %s | %r[:%d]'" % (field[0], field[1], data, size),) - raise - - size = self.calcPackSize(field[1], self[field[0]], field[0]) - if self.alignment and size % self.alignment: - size += self.alignment - (size % self.alignment) - data = data[size:] - - return self - - def __setitem__(self, key, value): - self.fields[key] = value - self.data = None # force recompute - - def __getitem__(self, key): - return self.fields[key] - - def __delitem__(self, key): - del self.fields[key] - - def __str__(self): - return self.getData() - - def __len__(self): - # XXX: improve - return len(self.getData()) - - def pack(self, format, data, field = None): - if self.debug: - print " pack( %s | %r | %s)" % (format, data, field) - - if field: - addressField = self.findAddressFieldFor(field) - if (addressField is not None) and (data is None): - return '' - - # void specifier - if format[:1] == '_': - return '' - - # quote specifier - if format[:1] == "'" or format[:1] == '"': - return format[1:] - - # code specifier - two = format.split('=') - if len(two) >= 2: - try: - return self.pack(two[0], data) - except: - fields = {'self':self} - fields.update(self.fields) - return self.pack(two[0], eval(two[1], {}, fields)) - - # address specifier - two = format.split('&') - if len(two) == 2: - try: - return self.pack(two[0], data) - except: - if (self.fields.has_key(two[1])) and (self[two[1]] is not None): - return self.pack(two[0], id(self[two[1]]) & ((1<<(calcsize(two[0])*8))-1) ) - else: - return self.pack(two[0], 0) - - # length specifier - two = format.split('-') - if len(two) == 2: - try: - return self.pack(two[0],data) - except: - return self.pack(two[0], self.calcPackFieldSize(two[1])) - - # array specifier - two = format.split('*') - if len(two) == 2: - answer = '' - for each in data: - answer += self.pack(two[1], each) - if two[0]: - if two[0].isdigit(): - if int(two[0]) != len(data): - raise Exception, "Array field has a constant size, and it doesn't match the actual value" - else: - return self.pack(two[0], len(data))+answer - return answer - - # "printf" string specifier - if format[:1] == '%': - # format string like specifier - return format % data - - # asciiz specifier - if format[:1] == 'z': - return str(data)+'\0' - - # unicode specifier - if format[:1] == 'u': - return str(data)+'\0\0' + (len(data) & 1 and '\0' or '') - - # DCE-RPC/NDR string specifier - if format[:1] == 'w': - if len(data) == 0: - data = '\0\0' - elif len(data) % 2: - data += '\0' - l = pack('= 2: - return self.unpack(two[0],data) - - # length specifier - two = format.split('-') - if len(two) == 2: - return self.unpack(two[0],data) - - # array specifier - two = format.split('*') - if len(two) == 2: - answer = [] - sofar = 0 - if two[0].isdigit(): - number = int(two[0]) - elif two[0]: - sofar += self.calcUnpackSize(two[0], data) - number = self.unpack(two[0], data[:sofar]) - else: - number = -1 - - while number and sofar < len(data): - nsofar = sofar + self.calcUnpackSize(two[1],data[sofar:]) - answer.append(self.unpack(two[1], data[sofar:nsofar], dataClassOrCode)) - number -= 1 - sofar = nsofar - return answer - - # "printf" string specifier - if format[:1] == '%': - # format string like specifier - return format % data - - # asciiz specifier - if format == 'z': - if data[-1] != '\x00': - raise Exception, ("%s 'z' field is not NUL terminated: %r" % (field, data)) - return data[:-1] # remove trailing NUL - - # unicode specifier - if format == 'u': - if data[-2:] != '\x00\x00': - raise Exception, ("%s 'u' field is not NUL-NUL terminated: %r" % (field, data)) - return data[:-2] # remove trailing NUL - - # DCE-RPC/NDR string specifier - if format == 'w': - l = unpack('= 2: - return self.calcPackSize(two[0], data) - - # length specifier - two = format.split('-') - if len(two) == 2: - return self.calcPackSize(two[0], data) - - # array specifier - two = format.split('*') - if len(two) == 2: - answer = 0 - if two[0].isdigit(): - if int(two[0]) != len(data): - raise Exception, "Array field has a constant size, and it doesn't match the actual value" - elif two[0]: - answer += self.calcPackSize(two[0], len(data)) - - for each in data: - answer += self.calcPackSize(two[1], each) - return answer - - # "printf" string specifier - if format[:1] == '%': - # format string like specifier - return len(format % data) - - # asciiz specifier - if format[:1] == 'z': - return len(data)+1 - - # asciiz specifier - if format[:1] == 'u': - l = len(data) - return l + (l & 1 and 3 or 2) - - # DCE-RPC/NDR string specifier - if format[:1] == 'w': - l = len(data) - return 12+l+l % 2 - - # literal specifier - if format[:1] == ':': - return len(data) - - # struct like specifier - return calcsize(format) - - def calcUnpackSize(self, format, data, field = None): - if self.debug: - print " calcUnpackSize( %s | %s | %r)" % (field, format, data) - - # void specifier - if format[:1] == '_': - return 0 - - addressField = self.findAddressFieldFor(field) - if addressField is not None: - if not self[addressField]: - return 0 - - try: - lengthField = self.findLengthFieldFor(field) - return self[lengthField] - except: - pass - - # XXX: Try to match to actual values, raise if no match - - # quote specifier - if format[:1] == "'" or format[:1] == '"': - return len(format)-1 - - # address specifier - two = format.split('&') - if len(two) == 2: - return self.calcUnpackSize(two[0], data) - - # code specifier - two = format.split('=') - if len(two) >= 2: - return self.calcUnpackSize(two[0], data) - - # length specifier - two = format.split('-') - if len(two) == 2: - return self.calcUnpackSize(two[0], data) - - # array specifier - two = format.split('*') - if len(two) == 2: - answer = 0 - if two[0]: - if two[0].isdigit(): - number = int(two[0]) - else: - answer += self.calcUnpackSize(two[0], data) - number = self.unpack(two[0], data[:answer]) - - while number: - number -= 1 - answer += self.calcUnpackSize(two[1], data[answer:]) - else: - while answer < len(data): - answer += self.calcUnpackSize(two[1], data[answer:]) - return answer - - # "printf" string specifier - if format[:1] == '%': - raise Exception, "Can't guess the size of a printf like specifier for unpacking" - - # asciiz specifier - if format[:1] == 'z': - return data.index('\x00')+1 - - # asciiz specifier - if format[:1] == 'u': - l = data.index('\x00\x00') - return l + (l & 1 and 3 or 2) - - # DCE-RPC/NDR string specifier - if format[:1] == 'w': - l = unpack('L'), - ('code1','>L=len(arr1)*2+0x1000'), - ) - - def populate(self, a): - a['default'] = 'hola' - a['int1'] = 0x3131 - a['int3'] = 0x45444342 - a['z1'] = 'hola' - a['u1'] = 'hola'.encode('utf_16_le') - a[':1'] = ':1234:' - a['arr1'] = (0x12341234,0x88990077,0x41414141) - # a['len1'] = 0x42424242 - -class _Test_fixedLength(_Test_simple): - def populate(self, a): - _Test_simple.populate(self, a) - a['len1'] = 0x42424242 - -class _Test_simple_aligned4(_Test_simple): - alignment = 4 - -class _Test_nested(_StructureTest): - class theClass(Structure): - class _Inner(Structure): - structure = (('data', 'z'),) - - structure = ( - ('nest1', ':', _Inner), - ('nest2', ':', _Inner), - ('int', '> 8)'), - ('pad', '_','((iv >>2) & 0x3F)'), - ('keyid', '_','( iv & 0x03 )'), - ('dataLen', '_-data', 'len(inputDataLeft)-4'), - ('data',':'), - ('icv','>L'), - ) - - def populate(self, a): - a['init_vector']=0x01020304 - #a['pad']=int('01010101',2) - a['pad']=int('010101',2) - a['keyid']=0x07 - a['data']="\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9" - a['icv'] = 0x05060708 - #a['iv'] = 0x01020304 - -if __name__ == '__main__': - _Test_simple().run() - - try: - _Test_fixedLength().run() - except: - print "cannot repack because length is bogus" - - _Test_simple_aligned4().run() - _Test_nested().run() - _Test_Optional().run() - _Test_Optional_sparse().run() - _Test_AsciiZArray().run() - _Test_UnpackCode().run() - _Test_AAA().run()