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

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
14import struct
15import functools
16from six import add_metaclass
18import impacket.ImpactPacket as ip
21def rebind(f):
22 functools.wraps(f)
23 def rebinder(*args, **kwargs):
24 return f(*args, **kwargs)
26 return rebinder
28class Field(object):
29 def __init__(self, index):
30 self.index = index
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
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
45 d[k] = property(getter, setter, doc="%s property" % k)
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
53 def getter(self, o):
54 return (o.header.get_byte(self.index) & self.mask) != 0
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
63 o.header.set_byte(self.index, b)
65class Byte(Field):
67 def __init__(self, index):
68 Field.__init__(self, index)
70 def getter(self, o):
71 return o.header.get_byte(self.index)
73 def setter(self, o, value):
74 o.header.set_byte(self.index, value)
76class Word(Field):
77 def __init__(self, index, order="!"):
78 Field.__init__(self, index)
79 self.order = order
81 def getter(self, o):
82 return o.header.get_word(self.index, self.order)
84 def setter(self, o, value):
85 o.header.set_word(self.index, value, self.order)
87class Long(Field):
88 def __init__(self, index, order="!"):
89 Field.__init__(self, index)
90 self.order = order
92 def getter(self, o):
93 return o.header.get_long(self.index, self.order)
95 def setter(self, o, value):
96 o.header.set_long(self.index, value, self.order)
98class ThreeBytesBigEndian(Field):
99 def __init__(self, index):
100 Field.__init__(self, index)
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
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, ">")
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)
128 d["_fields"].sort()
130 def _fields_repr(self):
131 return " ".join( "%s:%s" % (f, repr(getattr(self, f))) for f in self._fields )
132 def __repr__(self):
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 }
140 d["_fields_repr"] = _fields_repr
141 d["__repr__"] = __repr__
143 return type.__new__(cls, name, bases, d)
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)