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# 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#
16import struct
17import functools
18from six import add_metaclass
20import impacket.ImpactPacket as ip
23def rebind(f):
24 functools.wraps(f)
25 def rebinder(*args, **kwargs):
26 return f(*args, **kwargs)
28 return rebinder
30class Field(object):
31 def __init__(self, index):
32 self.index = index
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
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
47 d[k] = property(getter, setter, doc="%s property" % k)
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
55 def getter(self, o):
56 return (o.header.get_byte(self.index) & self.mask) != 0
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
65 o.header.set_byte(self.index, b)
67class Byte(Field):
69 def __init__(self, index):
70 Field.__init__(self, index)
72 def getter(self, o):
73 return o.header.get_byte(self.index)
75 def setter(self, o, value):
76 o.header.set_byte(self.index, value)
78class Word(Field):
79 def __init__(self, index, order="!"):
80 Field.__init__(self, index)
81 self.order = order
83 def getter(self, o):
84 return o.header.get_word(self.index, self.order)
86 def setter(self, o, value):
87 o.header.set_word(self.index, value, self.order)
89class Long(Field):
90 def __init__(self, index, order="!"):
91 Field.__init__(self, index)
92 self.order = order
94 def getter(self, o):
95 return o.header.get_long(self.index, self.order)
97 def setter(self, o, value):
98 o.header.set_long(self.index, value, self.order)
100class ThreeBytesBigEndian(Field):
101 def __init__(self, index):
102 Field.__init__(self, index)
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
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, ">")
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)
130 d["_fields"].sort()
132 def _fields_repr(self):
133 return " ".join( "%s:%s" % (f, repr(getattr(self, f))) for f in self._fields )
134 def __repr__(self):
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 }
142 d["_fields_repr"] = _fields_repr
143 d["__repr__"] = __repr__
145 return type.__new__(cls, name, bases, d)
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)