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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. 

2# 

3# This software is provided under under a slightly modified version 

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

5# for more information. 

6# 

7# Description: 

8# Helper used to build ProtocolPackets 

9# 

10# Author: 

11# Aureliano Calvo 

12 

13 

14import struct 

15import functools 

16from six import add_metaclass 

17 

18import impacket.ImpactPacket as ip 

19 

20 

21def rebind(f): 

22 functools.wraps(f) 

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

24 return f(*args, **kwargs) 

25 

26 return rebinder 

27 

28class Field(object): 

29 def __init__(self, index): 

30 self.index = index 

31 

32 def __call__(self, k, d): 

33 getter = rebind(self.getter) 

34 getter_name = "get_" + k 

35 getter.__name__ = getter_name 

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

37 d[getter_name] = getter 

38 

39 setter = rebind(self.setter) 

40 setter_name = "set_" + k 

41 setter.__name__ = setter_name 

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

43 d["set_" + k] = setter 

44 

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

46 

47class Bit(Field): 

48 def __init__(self, index, bit_number): 

49 Field.__init__(self, index) 

50 self.mask = 2 ** bit_number 

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

52 

53 def getter(self, o): 

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

55 

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

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

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

59 b |= self.mask 

60 else: 

61 b &= self.off_mask 

62 

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

64 

65class Byte(Field): 

66 

67 def __init__(self, index): 

68 Field.__init__(self, index) 

69 

70 def getter(self, o): 

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

72 

73 def setter(self, o, value): 

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

75 

76class Word(Field): 

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

78 Field.__init__(self, index) 

79 self.order = order 

80 

81 def getter(self, o): 

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

83 

84 def setter(self, o, value): 

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

86 

87class Long(Field): 

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

89 Field.__init__(self, index) 

90 self.order = order 

91 

92 def getter(self, o): 

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

94 

95 def setter(self, o, value): 

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

97 

98class ThreeBytesBigEndian(Field): 

99 def __init__(self, index): 

100 Field.__init__(self, index) 

101 

102 def getter(self, o): 

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

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

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

106 return value 

107 

108 def setter(self, o, value): 

109 # clear the bits 

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

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

112 # set the bits  

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

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

115 

116 

117class ProtocolPacketMetaklass(type): 

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

119 d["_fields"] = [] 

120 items = list(d.items()) 

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

122 bases += (object,) 

123 for k,v in items: 

124 if isinstance(v, Field): 

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

126 v(k, d) 

127 

128 d["_fields"].sort() 

129 

130 def _fields_repr(self): 

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

132 def __repr__(self): 

133 

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

135 "name": name, 

136 "fields": self._fields_repr(), 

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

138 } 

139 

140 d["_fields_repr"] = _fields_repr 

141 d["__repr__"] = __repr__ 

142 

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

144 

145@add_metaclass(ProtocolPacketMetaklass) 

146class ProtocolPacket(ip.ProtocolPacket): 

147 def __init__(self, buff = None): 

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

149 if buff: 

150 self.load_packet(buff)