def __init__(self, filename): self.db = sqa.Model(Base) self.session = self.db.session self._images = dict() self._sections_by_name = OrderedDict() self.asciiCString = CString(encoding = "ascii") self.fp = create_memorymapped_fileview(filename) print(filename, flush = True) self._basic_header = ElfParser.BasicHeader.parse(self.fp) self.b64 = (self.ei_class == 2) self.endianess = self.ei_data if self.ei_data == 1: # Little-Endian offset = 0 elif self.ei_data == 2: # Big-Endian offset = 1 else: offset = 0 # TODO: Error!!! datatypes = ElfParser.DATATYPES64.items() if self.b64 else ElfParser.DATATYPES32.items() for key, value in datatypes: setattr(self, key, value[offset]) print(self._basic_header) self._parser_extended_header() self._parse_section_headers() self._parse_program_headers() self.create_section_to_segment_mapping() self.session.commit()
def __init__(self, filename): self.fp = create_memorymapped_fileview(filename) sha = calculate_crypto_hash(self.fp.tobytes()) self.db = model.Model() self.session = self.db.session self.symbols = SymbolAPI(self) self.sections = SectionAPI(self) self._images = dict() self._sections_by_name = OrderedDict() self.asciiCString = CString(encoding="ascii") self._basic_header = ElfParser.BasicHeader.parse(self.fp) self.b64 = (self.ei_class == 2) if self.ei_data == 1: # Little-Endian offset = 0 elif self.ei_data == 2: # Big-Endian offset = 1 else: raise ValueError("EI_DATA has an invalid value. Got: {}".format( self.ei_data)) self._endianess = "<" if self.ei_data == 1 else ">" datatypes = ElfParser.DATATYPES64.items( ) if self.b64 else ElfParser.DATATYPES32.items() for key, value in datatypes: setattr(self, key, value[offset]) self._parser_extended_header() self._parse_section_headers() self._parse_program_headers() self.create_section_to_segment_mapping() for section in self._symbol_sections: self._parse_symbol_section(section) self.session.commit()
def _build_resource_info(**kwargs): return Struct( index=VarInt, long_name=CString("utf8"), short_name=CString("utf8"), **kwargs, )
class Bind(FrontendMessage): key = 'B' struct = Struct( "destination_portal" / CString("ASCII"), "prepared_statement" / CString("ASCII"), "_parameter_format_code_count" / Int16ub, "parameter_format_codes" / Array(this._parameter_format_code_count, Int16ub), "_parameter_value_count" / Int16ub, "parameter_values" / Array(this._parameter_value_count, Struct("length" / Int32ub, "value" / Bytes(this.length))), "result_column_format_count" / Int16ub, "result_column_format_codes" / Array(this.result_column_format_count, Int16ub))
class ParameterStatus(BackendMessage): key = 'S' struct = Struct( "name" / CString("ASCII"), "value" / CString("ASCII"), ) def print(message): name, value = ParameterStatus.normalize(message.name, message.value) return "ParameterStatus({}={})".format(name, value) @staticmethod def normalize(name, value): if name in ('TimeZone', 'server_version'): value = 'XXX' return (name, value)
def str_with_len(name): return Struct(name, UNInt32("len"), Anchor("start"), CString(name), Anchor("offset"), pad())
def symbolName(self, name): if name.startswith(b'\x00\x00\x00\x00'): vs = Struct(Padding(4), "value" / Int32ul).parse(name) return CString().parse( self.coff.stringTable[vs.value:]).decode("ascii") else: return String(8, padchar=b"\x00").parse(name).decode("ascii")
class Execute(FrontendMessage): key = 'E' struct = Struct("name" / CString("ASCII"), "max_rows_to_return" / Int32ub) def print(message): return "Execute({}, max_rows_to_return={})".format( message.name or "<unnamed>", message.max_rows_to_return)
class NoticeResponse(BackendMessage): key = 'N' struct = Struct("notices" / GreedyRange( Struct( "key" / Enum(Byte, severity=ord('S'), _severity_not_localized=ord('V'), _sql_state=ord('C'), message=ord('M'), detail=ord('D'), hint=ord('H'), _position=ord('P'), _internal_position=ord('p'), _internal_query=ord('q'), _where=ord('W'), schema_name=ord('s'), table_name=ord('t'), column_name=ord('c'), data_type_name=ord('d'), constraint_name=ord('n'), _file_name=ord('F'), _line_no=ord('L'), _routine_name=ord('R')), "value" / CString("ASCII")))) def print(message): return "NoticeResponse({})".format(", ".join( "{}={}".format(response.key, response.value) for response in message.notices if not response.key.startswith('_')))
def getString(self, tableIndex, entry): if (tableIndex, entry) in self._stringCache: return self._stringCache[(tableIndex, entry)] else: name = CString(encoding="ascii").parse( self.sectionHeaders[tableIndex].image[entry:]) return name
def parse(buffer, byteorder = "<"): """ Parameters ---------- buffer: bytes-like byteorder: char "<": Little-endian ">": Big-endian Returns ------- dict key: Vendor name values: list of attributes """ Integer = Int32ul if byteorder == "<" else Int32ub Section = Struct( "len" / Integer, "vendor" / CString(encoding = "ascii"), "_pos" / Tell, "data" / Bytes(this.len - this._pos), ) SubSectionHeader = Struct( "tag" / Byte, "len" / Integer, "_pos" / Tell, "data" / Bytes(this.len - this._pos), ) RawAttribute = Struct( "tag" / ULEB, "parameterType" / Computed(lambda ctx: ATTRIBUTES[ctx.tag].parameterType), "name" / Computed(lambda ctx: ATTRIBUTES[ctx.tag].tag), "_conv" / Computed(lambda ctx: ATTRIBUTES[ctx.tag].conv), "value" / Switch(this.parameterType, { Reader.INT32: Integer, Reader.ULEB: ULEB, Reader.CSTRING: CString(encoding = "ascii") }), "pos" / Tell, ) format_version = buffer[0] i = 1 length = len(buffer) result = {} while True: section = Section.parse(buffer[i : ]) if not section.vendor in result: result[section.vendor] = [] i += section.len res = SubSectionHeader.parse(section.data) j = 0 while j < len(res.data): attr = RawAttribute.parse(res.data[j : ]) r = Attribute(attr.tag, attr.name, attr.value) if attr._conv != Ident: r.description = attr._conv[attr.value] result[section.vendor].append(r) j += attr.pos if i >= length: break return result
def do_mac_info(self): if not '.debug_macinfo' in self.sections: return section = self.sections['.debug_macinfo'] image = io.BytesIO(section.image) length = len(section.image) MacInfo = Struct( "start" / Tell, "macType" / Enum( ULEB, default=ident, DW_MACINFO_define=0x01, DW_MACINFO_undef=0x02, DW_MACINFO_start_file=0x03, DW_MACINFO_end_file=0x04, DW_MACINFO_vendor_ext=0xff, ), "parameters" / Switch( this.macType, { "DW_MACINFO_define": Struct("lineNumber" / ULEB, "value" / CString(encoding="ascii")), "DW_MACINFO_undef": Struct("lineNumber" / ULEB, "value" / CString(encoding="ascii")), "DW_MACINFO_start_file": Struct("lineNumber" / ULEB, "fileNumber" / ULEB), "DW_MACINFO_end_file": Pass, "DW_MACINFO_vendor_ext": Struct("constant" / ULEB, "value" / CString(encoding="ascii")), }, default=Pass, ), "stop" / Tell, ) offset = 0 while True: macInfo = MacInfo.parse_stream(image) offset += macInfo.stop - macInfo.start print(offset, macInfo) if offset >= length - 1: break
def FixedUTF16CString(size_func, ctx_str_name): """At parse time parses a UTF16 string terminated with null byte with a known size, and at build time builds the string with its given size. If the given string is empty at build time, then build nothing instead of a single null character. """ return IfThenElse(lambda ctx: ctx._parsing, PaddedString(size_func, "UTF_16_le"), If(lambda ctx: ctx[ctx_str_name], CString("UTF_16_le")))
def string_list(name, extra = Pass): return PrefixedArray(Struct(name, UNInt32("len"), Anchor("start"), CString(name), Anchor("offset"), pad(), extra), UNInt32("nr"))
class Describe(FrontendMessage): key = 'D' struct = Struct( "type" / Enum(Byte, prepared_statement=ord('S'), portal=ord('P')), "name" / CString("ASCII")) def print(message): return "Describe({}={})".format(message.type, message.name or "<unnamed>")
def build_id(): return Struct("build_id", Anchor("start"), UNInt32("type"), UNInt16("misc"), UNInt16("size"), SNInt32("pid"), HexDumpAdapter(String("build_id", 24)), CString("filename"), Anchor("offset"), pad("size"))
def get_files(data): files = {} fstruct = GreedyRange( Struct( "dsize" / Int32ul, "nsize" / Int32ul, "name" / Bytes(256), "fdata" / Bytes(this.dsize), ) ) fdata = fstruct.parse(data) for file in fdata: if file["nsize"] > 1 and ord(file["name"][1]) == 0: filename = CString("utf16").parse(file["name"]) else: filename = CString("ascii").parse(file["name"]) filename = filename.encode("ascii", "ignore") files[filename] = file["fdata"] return files
def get_form_readers(self, addressSize): return { constants.AttributeForm.DW_FORM_string: CString(encoding="utf8"), constants.AttributeForm.DW_FORM_udata: ULEB, constants.AttributeForm.DW_FORM_sdata: SLEB, constants.AttributeForm.DW_FORM_data1: self.u8, constants.AttributeForm.DW_FORM_data2: self.u16, constants.AttributeForm.DW_FORM_data4: self.u32, constants.AttributeForm.DW_FORM_data8: self.u64, constants.AttributeForm.DW_FORM_addr: Address(addressSize, self.endianess), constants.AttributeForm.DW_FORM_block: BlockUleb, constants.AttributeForm.DW_FORM_block1: Block1, constants.AttributeForm.DW_FORM_block2: 'block2', constants.AttributeForm.DW_FORM_block4: 'block4', constants.AttributeForm.DW_FORM_flag: self.u8, constants.AttributeForm.DW_FORM_ref_addr: self.u32, constants.AttributeForm.DW_FORM_ref1: self.u8, constants.AttributeForm.DW_FORM_ref2: self.u16, constants.AttributeForm.DW_FORM_ref4: self.u32, constants.AttributeForm.DW_FORM_ref8: self.u64, constants.AttributeForm.DW_FORM_ref_udata: ULEB, constants.AttributeForm.DW_FORM_strp: StrP(self.strings, self.endianess), constants.AttributeForm.DW_FORM_indirect: None, # TODO: uleb value, that represents its form! constants.AttributeForm.DW_FORM_sec_offset: self.u32, constants.AttributeForm.DW_FORM_exprloc: BlockUleb, constants.AttributeForm.DW_FORM_flag_present: One, constants.AttributeForm.DW_FORM_ref_sig8: self.u64, }
def mmap2(): return Struct("mmap2", SNInt32("pid"), SNInt32("tid"), UNInt64("addr"), UNInt64("len"), UNInt64("pgoff"), UNInt32("maj"), UNInt32("min"), UNInt64("ino"), UNInt64("ino_generation"), UNInt32("prot"), UNInt32("flags"), CString("filename"), sample_id())
class RowDescription(BackendMessage): key = 'T' struct = Struct( "fieldcount" / Int16ub, "fields" / Array( this.fieldcount, Struct( "_type" / Computed("F"), "name" / CString("ascii"), "tableoid" / Int32ub, "colattrnum" / Int16ub, "typoid" / Int32ub, "typlen" / Int16sb, "typmod" / Int32sb, "format_code" / Int16ub, )))
def mmap(): return Struct("mmap", SNInt32("pid"), SNInt32("tid"), UNInt64("addr"), UNInt64("len"), UNInt64("pgoff"), Anchor("start_of_filename"), CString("filename"), Anchor("end_of_filename"), # hack for now. this shouldn't be needed. If(lambda ctx: True, # XXX Embedded(Pointer(lambda ctx: ctx.size + ctx.start - sample_id_size(ctx), sample_id()))))
def _parse_comment(self, data): Line = Struct("line" / CString("ascii"), "pos" / Tell) if not data: return "" length = len(data) result = [] i = 0 if data.find(b"\x00") == -1: return str(data, "ascii") while i < length: #print("*** LINE", data[i : ]) line = Line.parse(data[i:]) if line.line: result.append(line.line) i += line.pos return '\n'.join(result)
class InstantSoupData(object): # common server = Struct("server", CString("server_id"), PrefixedArray(CString('channels'), UBInt8("num_channels"))) # structures from rfc opt_client_nick = CString('nickname') opt_client_membership = PrefixedArray(server, UBInt8("num_servers")) opt_server = Struct("opt_server", UBInt16("port")) opt_server_channels = Struct( "opt_server_channels", PrefixedArray(CString("channels"), UBInt8("num_channels"))) opt_server_invite = Struct( "opt_server_invite", CString("channel_id"), PrefixedArray(CString("client_id"), UBInt8("num_clients"))) # option fields option = Struct( "option", Enum(UBInt8("option_id"), CLIENT_NICK_OPTION=0x01, CLIENT_MEMBERSHIP_OPTION=0x02, SERVER_OPTION=0x10, SERVER_CHANNELS_OPTION=0x11, SERVER_INVITE_OPTION=0x12), Switch( "option_data", lambda ctx: ctx["option_id"], { "CLIENT_NICK_OPTION": opt_client_nick, "CLIENT_MEMBERSHIP_OPTION": opt_client_membership, "SERVER_OPTION": opt_server, "SERVER_CHANNELS_OPTION": opt_server_channels, "SERVER_INVITE_OPTION": opt_server_invite })) # the peer pdu itself peer_pdu = Struct("peer_pdu", CString('id'), OptionalGreedyRange(option)) command = PascalString("command", length_field=UBInt32("length"), encoding='utf8')
def pubnames(self): if not '.debug_pubnames' in self.sections: return section = self.sections['.debug_pubnames'] image = io.BytesIO(section.image) length = len(section.image) Header = Struct( "start" / Tell, "unit_length" / self.u32, "version" / self.u16, "debug_info_offset" / self.u32, "debug_info_length" / self.u32, "stop" / Tell, ) Entry = Struct( "start" / Tell, "offset" / self.u32, "name" / CString(encoding="ascii"), "stop" / Tell, ) offset = 0 finished = False while True: if finished: break header = Header.parse_stream(image) offset += header.stop - header.start print(offset, header) if offset >= length - 1: break while True: entry = Entry.parse_stream(image) offset += entry.stop - entry.start print("ENTRY", entry) if entry.offset == 0: break if entry.stop >= header.unit_length: finished = True break
def perf_event(): return Struct( "perf_event", Anchor("start"), perf_event_header(), Anchor("header_end"), Switch( "data", lambda ctx: ctx.type, { "MMAP": mmap(), # noqa E121 "MMAP2": mmap2(), "LOST": Struct("lost", UNInt64("id"), UNInt64("lost"), sample_id()), "COMM": Struct("comm", SNInt32("pid"), SNInt32("tid"), CString("comm"), sample_id()), "EXIT": fork_exit("exit"), "THROTTLE": throttle("throttle"), "UNTHROTTLE": throttle("unthrottle"), "FINISHED_ROUND": Pass, "FORK": fork_exit("fork"), "READ": Embedded( Struct("read_event", SNInt32("pid"), SNInt32("tid"), read_format(), sample_id())), "SAMPLE": event() }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start)))
DOUBLE=0x9, DECIMAL=0x0A, STRING=0x12, CSTRING=0x13, PSTRING=0x14, # compound data structure GROUP=0x16, # LIKE (inherited data type) ) TABLE_DEFINITION_FIELD_STRUCT = Struct( 'record_table_definition_field', FIELD_TYPE_STRUCT, # data offset in record ULInt16('offset'), CString('name'), ULInt16('array_element_count'), ULInt16('size'), # 1, if fields overlap (OVER attribute), or 0 ULInt16('overlaps'), # record number ULInt16('number'), If(lambda x: x['type'] == 'STRING', ULInt16('array_element_size')), If(lambda x: x['type'] == 'STRING', ULInt16('template')), If(lambda x: x['type'] == 'CSTRING', ULInt16('array_element_size')), If(lambda x: x['type'] == 'CSTRING', ULInt16('template')), If(lambda x: x['type'] == 'PSTRING', ULInt16('array_element_size')), If(lambda x: x['type'] == 'PSTRING', ULInt16('template')), If(lambda x: x['type'] == 'PICTURE', ULInt16('array_element_size')), If(lambda x: x['type'] == 'PICTURE', ULInt16('template')), If(lambda x: x['type'] == 'DECIMAL', Byte('decimal_count')),
Padding(2), "followed_unit_id"/Int32ul, Array(lambda ctx: ctx.selected, "unit_ids"/Int32ul) ) formation = "formation"/Struct( "selected"/Byte, "player_id"/Int16ul, FormationEnum("formation_type"/Int32ul), Array(lambda ctx: ctx.selected, "unit_ids"/Int32ul) ) save = "save"/Struct( "exited"/Flag, "player_id"/Byte, "filename"/CString(encoding='latin1'), Padding(lambda ctx: ctx._._.length - 23), "checksum"/Int32ul ) chapter = "chapter"/Struct( "player_id"/Byte ) build = "build"/Struct( "selected"/Byte, "player_id"/Int16ul, "x"/Float32l, "y"/Float32l, "building_type"/Int32ul, Padding(4),
""" from construct import SLInt32, SLInt64, CString, LFloat32 from construct import Embed, If from construct import Struct, Array from construct import Container # from construct.debug import Probe from pox.ethanol.ssl_message.msg_core import msg_default from pox.ethanol.ssl_message.msg_core import field_station, field_intf_name, field_mac_addr from pox.ethanol.ssl_message.msg_common import MSG_TYPE, VERSION from pox.ethanol.ssl_message.msg_common import send_and_receive_msg, len_of_string field_time_stamp = Struct('time_stamp', SLInt32('time_stamp_size'), If(lambda ctx: ctx["time_stamp_size"] > 0, CString("time_stamp")), ) stats_field = Struct('stats', Embed(field_mac_addr), Embed(field_intf_name), SLInt32('inactive_time'), # long SLInt64('rx_bytes'), SLInt64('tx_bytes'), SLInt64('rx_packets'), SLInt64('rx_duration'), SLInt64('tx_packets'), SLInt64('tx_retries'), SLInt64('tx_failed'), SLInt64('beacon_loss'), SLInt64('beacon_rx'),
if _construct_version: if (_construct_version[0] < 2) or ((_construct_version[0] == 2) and (_construct_version[1] < 9)): raise Exception( 'Construct version too low, please install version 2.9+') from construct import Struct, Const, Int32ub, Int32sb, RepeatUntil, CString, Pointer, Bytes, Padding, BitStruct, Flag, IfThenElse, Seek, Tell _FArc_format = Struct( "signature" / Const(b'FArc'), "header_size" / Int32ub, # doesn't include signature or header_size "alignment" / Int32sb, "files" / RepeatUntil( lambda obj, lst, ctx: ctx._io.tell() - 7 > ctx.header_size, Struct( "name" / CString("utf8"), "pointer" / Int32ub, "size" / Int32ub, "data" / Pointer(lambda this: this.pointer, Bytes(lambda this: this.size)))), #Padding(lambda this: this.alignment - (this._io.tell() % this.alignment) if this._io.tell() % this.alignment else 0) ) _FArC_format = Struct( "signature" / Const(b'FArC'), "header_size" / Int32ub, # doesn't include signature or header_size "alignment" / Int32sb, "files" / RepeatUntil( lambda obj, lst, ctx: ctx._io.tell() - 7 > ctx.header_size, Struct( "name" / CString("utf8"), "pointer" / Int32ub, "compressed_size" / Int32ub, "uncompressed_size" / Int32ub, "data" / Pointer(lambda this: this.pointer,
from construct import CString, Enum, Int32ul, Struct ServerGuildCommandResult = Struct( 'cmd' / Int32ul, 'str' / CString('ascii'), 'result' / Int32ul, )
def test_parse(self): s = CString("foo") self.assertEqual(s.parse(b"hello\x00"), b"hello")
def test_build(self): s = CString("foo") self.assertEqual(s.build(b"hello"), b"hello\x00")
def test_parse_terminator(self): s = CString("foo", terminators=b"XYZ") self.assertEqual(s.parse(b"helloX"), b"hello") self.assertEqual(s.parse(b"helloY"), b"hello") self.assertEqual(s.parse(b"helloZ"), b"hello")
def test_build_terminator(self): s = CString("foo", terminators=b"XYZ") self.assertEqual(s.build(b"hello"), b"helloX")
self.assertEqual(s.build(six.u("hello")), six.b("hello\x00")) def test_parse_terminator(self): s = CString("foo", terminators=six.b("XYZ"), encoding="utf8") self.assertEqual(s.parse(six.b("helloX")), six.u("hello")) self.assertEqual(s.parse(six.b("helloY")), six.u("hello")) self.assertEqual(s.parse(six.b("helloZ")), six.u("hello")) def test_build_terminator(self): s = CString("foo", terminators=six.b("XYZ"), encoding="utf8") self.assertEqual(s.build(six.u("hello")), six.b("helloX")) class TestGreedyString(unittest.TestCase): def test_parse(self): s = GreedyString("foo", encoding="utf8") self.assertEqual(s.parse(six.b("hello\x00")), six.u("hello\x00")) def test_build(self): s = GreedyString("foo", encoding="utf8") self.assertEqual(s.build(six.u("hello")), six.b("hello")) if __name__ == "__main__": #unittest.main() s = CString("foo", encoding="utf8") s.build(six.u("hello"))
def test_build(self): s = CString("foo", encoding="utf8") self.assertEqual(s.build(six.u("hello")), six.b("hello\x00"))
def test_parse_terminator(self): s = CString("foo", terminators=six.b("XYZ"), encoding="utf8") self.assertEqual(s.parse(six.b("helloX")), six.u("hello")) self.assertEqual(s.parse(six.b("helloY")), six.u("hello")) self.assertEqual(s.parse(six.b("helloZ")), six.u("hello"))
def test_build_terminator(self): s = CString("foo", terminators=six.b("XYZ"), encoding="utf8") self.assertEqual(s.build(six.u("hello")), six.b("helloX"))