Coverage for /root/GitHubProjects/impacket/impacket/helper.py: 94%

# Coverage for /root/GitHubProjects/impacket/impacket/helper.py : 94%

## 96 statements

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1# Impacket - Collection of Python classes for working with network protocols.

2#

3# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.

4#

5# This software is provided under a slightly modified version

6# of the Apache Software License. See the accompanying LICENSE file

7# for more information.

8#

9# Description:

10# Helper used to build ProtocolPackets

11#

12# Author:

13# Aureliano Calvo

14#

15

16 import struct

17 import functools

18 from six import add_metaclass

19

20 import impacket.ImpactPacket as ip

21

22

23 def rebind(f):

24 functools.wraps(f)

25 def rebinder(*args, **kwargs):

26 return f(*args, **kwargs)

27

28 return rebinder

29

30 class Field(object):

31 def __init__(self, index):

32 self.index = index

33

34 def __call__(self, k, d):

35 getter = rebind(self.getter)

36 getter_name = "get_" + k

37 getter.__name__ = getter_name

38 getter.__doc__ = "Get the %s field" % k

39 d[getter_name] = getter

40

41 setter = rebind(self.setter)

42 setter_name = "set_" + k

43 setter.__name__ = setter_name

44 setter.__doc__ = "Set the %s field" % k

45 d["set_" + k] = setter

46

47 d[k] = property(getter, setter, doc="%s property" % k)

48

49 class Bit(Field):

50 def __init__(self, index, bit_number):

51 Field.__init__(self, index)

52 self.mask = 2 ** bit_number

53 self.off_mask = (~self.mask) & 0xff

54

55 def getter(self, o):

56 return (o.header.get_byte(self.index) & self.mask) != 0

57

58 def setter(self, o, value=True):

59 b = o.header.get_byte(self.index)

60 if value: 60 ↛ 61line 60 didn't jump to line 61, because the condition on line 60 was never true

61 b |= self.mask

62 else:

63 b &= self.off_mask

64

65 o.header.set_byte(self.index, b)

66

67 class Byte(Field):

68

69 def __init__(self, index):

70 Field.__init__(self, index)

71

72 def getter(self, o):

73 return o.header.get_byte(self.index)

74

75 def setter(self, o, value):

76 o.header.set_byte(self.index, value)

77

78 class Word(Field):

79 def __init__(self, index, order="!"):

80 Field.__init__(self, index)

81 self.order = order

82

83 def getter(self, o):

84 return o.header.get_word(self.index, self.order)

85

86 def setter(self, o, value):

87 o.header.set_word(self.index, value, self.order)

88

89 class Long(Field):

90 def __init__(self, index, order="!"):

91 Field.__init__(self, index)

92 self.order = order

93

94 def getter(self, o):

95 return o.header.get_long(self.index, self.order)

96

97 def setter(self, o, value):

98 o.header.set_long(self.index, value, self.order)

99

100 class ThreeBytesBigEndian(Field):

101 def __init__(self, index):

102 Field.__init__(self, index)

103

104 def getter(self, o):

105 b = ip.array_tobytes(o.header.get_bytes()[self.index: self.index+3])

106 #unpack requires a string argument of length 4 and b is 3 bytes long

107 (value,) = struct.unpack('!L', b'\x00'+b)

108 return value

109

110 def setter(self, o, value):

111 # clear the bits

112 mask = ((~0xFFFFFF00) & 0xFF)

113 masked = o.header.get_long(self.index, ">") & mask

114 # set the bits

115 nb = masked | ((value & 0x00FFFFFF) << 8)

116 o.header.set_long(self.index, nb, ">")

117

118

119 class ProtocolPacketMetaklass(type):

120 def __new__(cls, name, bases, d):

121 d["_fields"] = []

122 items = list(d.items())

123 if not object in bases: 123 ↛ 125line 123 didn't jump to line 125, because the condition on line 123 was never false

124 bases += (object,)

125 for k,v in items:

126 if isinstance(v, Field):

127 d["_fields"].append(k)

128 v(k, d)

129

130 d["_fields"].sort()

131

132 def _fields_repr(self):

133 return " ".join( "%s:%s" % (f, repr(getattr(self, f))) for f in self._fields )

134 def __repr__(self):

135

136 return "<%(name)s %(fields)s \nchild:%(r_child)s>" % {

137 "name": name,

138 "fields": self._fields_repr(),

139 "r_child": repr(self.child()),

140 }

141

142 d["_fields_repr"] = _fields_repr

143 d["__repr__"] = __repr__

144

145 return type.__new__(cls, name, bases, d)

146

147@add_metaclass(ProtocolPacketMetaklass)

148 class ProtocolPacket(ip.ProtocolPacket):

149 def __init__(self, buff = None):

150 ip.ProtocolPacket.__init__(self, self.header_size, self.tail_size)

151 if buff:

152 self.load_packet(buff)