Hide keyboard shortcuts

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 

16import struct 

17import functools 

18from six import add_metaclass 

19 

20import impacket.ImpactPacket as ip 

21 

22 

23def rebind(f): 

24 functools.wraps(f) 

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

26 return f(*args, **kwargs) 

27 

28 return rebinder 

29 

30class 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 

49class 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 

67class 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 

78class 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 

89class 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 

100class 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 

119class 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) 

148class 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)