brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 1a9b313 Raw
225 lines · python
1#!/usr/bin/env python2 3import string4import struct5import sys6 7 8class FileExtract:9    """Decode binary data from a file"""10 11    def __init__(self, f, b="="):12        """Initialize with an open binary file and optional byte order"""13 14        self.file = f15        self.byte_order = b16        self.offsets = list()17 18    def set_byte_order(self, b):19        '''Set the byte order, valid values are "big", "little", "swap", "native", "<", ">", "@", "="'''20        if b == "big":21            self.byte_order = ">"22        elif b == "little":23            self.byte_order = "<"24        elif b == "swap":25            # swap what ever the current byte order is26            self.byte_order = swap_unpack_char()27        elif b == "native":28            self.byte_order = "="29        elif b == "<" or b == ">" or b == "@" or b == "=":30            self.byte_order = b31        else:32            print("error: invalid byte order specified: '%s'" % b)33 34    def is_in_memory(self):35        return False36 37    def seek(self, offset, whence=0):38        if self.file:39            return self.file.seek(offset, whence)40        raise ValueError41 42    def tell(self):43        if self.file:44            return self.file.tell()45        raise ValueError46 47    def read_size(self, byte_size):48        s = self.file.read(byte_size)49        if len(s) != byte_size:50            return None51        return s52 53    def push_offset_and_seek(self, offset):54        '''Push the current file offset and seek to "offset"'''55        self.offsets.append(self.file.tell())56        self.file.seek(offset, 0)57 58    def pop_offset_and_seek(self):59        """Pop a previously pushed file offset, or do nothing if there were no previously pushed offsets"""60        if len(self.offsets) > 0:61            self.file.seek(self.offsets.pop())62 63    def get_sint8(self, fail_value=0):64        """Extract a single int8_t from the binary file at the current file position, returns a single integer"""65        s = self.read_size(1)66        if s:67            (v,) = struct.unpack(self.byte_order + "b", s)68            return v69        else:70            return fail_value71 72    def get_uint8(self, fail_value=0):73        """Extract a single uint8_t from the binary file at the current file position, returns a single integer"""74        s = self.read_size(1)75        if s:76            (v,) = struct.unpack(self.byte_order + "B", s)77            return v78        else:79            return fail_value80 81    def get_sint16(self, fail_value=0):82        """Extract a single int16_t from the binary file at the current file position, returns a single integer"""83        s = self.read_size(2)84        if s:85            (v,) = struct.unpack(self.byte_order + "h", s)86            return v87        else:88            return fail_value89 90    def get_uint16(self, fail_value=0):91        """Extract a single uint16_t from the binary file at the current file position, returns a single integer"""92        s = self.read_size(2)93        if s:94            (v,) = struct.unpack(self.byte_order + "H", s)95            return v96        else:97            return fail_value98 99    def get_sint32(self, fail_value=0):100        """Extract a single int32_t from the binary file at the current file position, returns a single integer"""101        s = self.read_size(4)102        if s:103            (v,) = struct.unpack(self.byte_order + "i", s)104            return v105        else:106            return fail_value107 108    def get_uint32(self, fail_value=0):109        """Extract a single uint32_t from the binary file at the current file position, returns a single integer"""110        s = self.read_size(4)111        if s:112            (v,) = struct.unpack(self.byte_order + "I", s)113            return v114        else:115            return fail_value116 117    def get_sint64(self, fail_value=0):118        """Extract a single int64_t from the binary file at the current file position, returns a single integer"""119        s = self.read_size(8)120        if s:121            (v,) = struct.unpack(self.byte_order + "q", s)122            return v123        else:124            return fail_value125 126    def get_uint64(self, fail_value=0):127        """Extract a single uint64_t from the binary file at the current file position, returns a single integer"""128        s = self.read_size(8)129        if s:130            (v,) = struct.unpack(self.byte_order + "Q", s)131            return v132        else:133            return fail_value134 135    def get_fixed_length_c_string(136        self, n, fail_value="", isprint_only_with_space_padding=False137    ):138        """Extract a single fixed length C string from the binary file at the current file position, returns a single C string"""139        s = self.read_size(n)140        if s:141            (cstr,) = struct.unpack(self.byte_order + ("%i" % n) + "s", s)142            # Strip trialing NULLs143            cstr = string.strip(cstr, "\0")144            if isprint_only_with_space_padding:145                for c in cstr:146                    if c in string.printable or ord(c) == 0:147                        continue148                    return fail_value149            return cstr150        else:151            return fail_value152 153    def get_c_string(self):154        """Extract a single NULL terminated C string from the binary file at the current file position, returns a single C string"""155        cstr = ""156        byte = self.get_uint8()157        while byte != 0:158            cstr += "%c" % byte159            byte = self.get_uint8()160        return cstr161 162    def get_n_sint8(self, n, fail_value=0):163        """Extract "n" int8_t integers from the binary file at the current file position, returns a list of integers"""164        s = self.read_size(n)165        if s:166            return struct.unpack(self.byte_order + ("%u" % n) + "b", s)167        else:168            return (fail_value,) * n169 170    def get_n_uint8(self, n, fail_value=0):171        """Extract "n" uint8_t integers from the binary file at the current file position, returns a list of integers"""172        s = self.read_size(n)173        if s:174            return struct.unpack(self.byte_order + ("%u" % n) + "B", s)175        else:176            return (fail_value,) * n177 178    def get_n_sint16(self, n, fail_value=0):179        """Extract "n" int16_t integers from the binary file at the current file position, returns a list of integers"""180        s = self.read_size(2 * n)181        if s:182            return struct.unpack(self.byte_order + ("%u" % n) + "h", s)183        else:184            return (fail_value,) * n185 186    def get_n_uint16(self, n, fail_value=0):187        """Extract "n" uint16_t integers from the binary file at the current file position, returns a list of integers"""188        s = self.read_size(2 * n)189        if s:190            return struct.unpack(self.byte_order + ("%u" % n) + "H", s)191        else:192            return (fail_value,) * n193 194    def get_n_sint32(self, n, fail_value=0):195        """Extract "n" int32_t integers from the binary file at the current file position, returns a list of integers"""196        s = self.read_size(4 * n)197        if s:198            return struct.unpack(self.byte_order + ("%u" % n) + "i", s)199        else:200            return (fail_value,) * n201 202    def get_n_uint32(self, n, fail_value=0):203        """Extract "n" uint32_t integers from the binary file at the current file position, returns a list of integers"""204        s = self.read_size(4 * n)205        if s:206            return struct.unpack(self.byte_order + ("%u" % n) + "I", s)207        else:208            return (fail_value,) * n209 210    def get_n_sint64(self, n, fail_value=0):211        """Extract "n" int64_t integers from the binary file at the current file position, returns a list of integers"""212        s = self.read_size(8 * n)213        if s:214            return struct.unpack(self.byte_order + ("%u" % n) + "q", s)215        else:216            return (fail_value,) * n217 218    def get_n_uint64(self, n, fail_value=0):219        """Extract "n" uint64_t integers from the binary file at the current file position, returns a list of integers"""220        s = self.read_size(8 * n)221        if s:222            return struct.unpack(self.byte_order + ("%u" % n) + "Q", s)223        else:224            return (fail_value,) * n225