#-------------------------------------------------------------------------------# elftools: common/utils.py## Miscellaneous utilities for elftools## Eli Bendersky (eliben@gmail.com)# This code is in the public domain#-------------------------------------------------------------------------------from contextlib import contextmanagerfrom .exceptions import ELFParseError, ELFError, DWARFErrorfrom .py3compat import int2bytefrom ..construct import ConstructError, ULInt8def merge_dicts(*dicts):"Given any number of dicts, merges them into a new one."""result = {}for d in dicts:result.update(d)return resultdef bytelist2string(bytelist):""" Convert a list of byte values (e.g. [0x10 0x20 0x00]) to a bytes object(e.g. b'\x10\x20\x00')."""return b''.join(int2byte(b) for b in bytelist)def struct_parse(struct, stream, stream_pos=None):""" Convenience function for using the given struct to parse a stream.If stream_pos is provided, the stream is seeked to this position beforethe parsing is done. Otherwise, the current position of the stream isused.Wraps the error thrown by construct with ELFParseError."""try:if stream_pos is not None:stream.seek(stream_pos)return struct.parse_stream(stream)except ConstructError as e:raise ELFParseError(str(e))def parse_cstring_from_stream(stream, stream_pos=None):""" Parse a C-string from the given stream. The string is returned withoutthe terminating \x00 byte. If the terminating byte wasn't found, Noneis returned (the stream is exhausted).If stream_pos is provided, the stream is seeked to this position beforethe parsing is done. Otherwise, the current position of the stream isused.Note: a bytes object is returned here, because this is what's read fromthe binary file."""if stream_pos is not None:stream.seek(stream_pos)CHUNKSIZE = 64chunks = []found = Falsewhile True:chunk = stream.read(CHUNKSIZE)end_index = chunk.find(b'\x00')if end_index >= 0:chunks.append(chunk[:end_index])found = Truebreakelse:chunks.append(chunk)if len(chunk) < CHUNKSIZE:breakreturn b''.join(chunks) if found else Nonedef elf_assert(cond, msg=''):""" Assert that cond is True, otherwise raise ELFError(msg)"""_assert_with_exception(cond, msg, ELFError)def dwarf_assert(cond, msg=''):""" Assert that cond is True, otherwise raise DWARFError(msg)"""_assert_with_exception(cond, msg, DWARFError)@contextmanagerdef preserve_stream_pos(stream):""" Usage:# stream has some position FOO (return value of stream.tell())with preserve_stream_pos(stream):# do stuff that manipulates the stream# stream still has position FOO"""saved_pos = stream.tell()yieldstream.seek(saved_pos)def roundup(num, bits):""" Round up a number to nearest multiple of 2^bits. The result is a numberwhere the least significant bits passed in bits are 0."""return (num - 1 | (1 << bits) - 1) + 1def read_blob(stream, length):"""Read length bytes from stream, return a list of ints"""return [struct_parse(ULInt8(''), stream) for i in range(length)]#------------------------- PRIVATE -------------------------def _assert_with_exception(cond, msg, exception_type):if not cond:raise exception_type(msg)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。