def read(parser, prototype): parser = _State(parser) size = parser.stream.read_uleb128() if size == 0: return False if not parser.stream.check_data_available(size): errprint("File truncated") return False start = parser.stream.pos r = True r = r and _read_flags(parser, prototype) r = r and _read_counts_and_sizes(parser, prototype) r = r and _read_instructions(parser, prototype) r = r and _read_constants(parser, prototype) r = r and _read_debuginfo(parser, prototype) end = parser.stream.pos if r: assert end - start == size, "Incorrectly read: from {0} to {1} ({2}) instead of {3}".format( start, end, end - start, size ) return r
def read(parser, prototype): parser = _State(parser) size = parser.stream.read_uleb128() if size == 0: return False if not parser.stream.check_data_available(size): errprint("File truncated") return False start = parser.stream.pos r = True r = r and _read_flags(parser, prototype) r = r and _read_counts_and_sizes(parser, prototype) r = r and _read_instructions(parser, prototype) r = r and _read_constants(parser, prototype) r = r and _read_debuginfo(parser, prototype) end = parser.stream.pos if r: assert end - start == size, \ "Incorrectly read: from {0} to {1} ({2}) instead of {3}"\ .format(start, end, end - start, size) return r
def _read_version(state, header): header.version = state.stream.read_byte() if header.version > _MAX_VERSION: errprint("Version {0}: propritary modifications", header.version) return False return True
def _read_flags(parser, prototype): flags = parser.stream.read_byte() bits = flags prototype.flags.has_ffi = bool(flags & FLAG_HAS_FFI) bits &= ~FLAG_HAS_FFI prototype.flags.has_iloop = bool(flags & FLAG_HAS_ILOOP) bits &= ~FLAG_HAS_ILOOP prototype.flags.has_jit = not (flags & FLAG_JIT_DISABLED) bits &= ~FLAG_JIT_DISABLED prototype.flags.has_sub_prototypes = bool(flags & FLAG_HAS_CHILD) bits &= ~FLAG_HAS_CHILD prototype.flags.is_variadic = bool(flags & FLAG_IS_VARIADIC) bits &= ~FLAG_IS_VARIADIC # errprint ("prototype.flags.has_ffi %d" % prototype.flags.has_ffi) # errprint ("prototype.flags.has_iloop %d" % prototype.flags.has_iloop) # errprint ("prototype.flags.has_jit %d" % prototype.flags.has_jit) # errprint ("prototype.flags.has_sub_prototypes %d" % prototype.flags.has_sub_prototypes) # errprint ("prototype.flags.is_variadic %d" % prototype.flags.is_variadic) if bits != 0: errprint("Unknown prototype flags: {0:08b}", bits) return False return True
def _read_header(parser, header): if not ljd.rawdump.header.read(parser, header): errprint("Failed to read raw-dump header") return False if header.flags.is_big_endian: parser.stream.data_byteorder = 'big' else: parser.stream.data_byteorder = 'little' return True
def _read_prototypes(state, prototypes): while not state.stream.eof(): prototype = ljd.bytecode.prototype.Prototype() if not ljd.rawdump.prototype.read(state, prototype): if state.stream.eof(): break else: errprint("Failed to read prototype") return False prototypes.append(prototype) return True
def _read_prototypes(state, prototypes): while not state.stream.eof(): prototype = ljd.bytecode.prototype.Prototype() #print ("good rwsdump->parser->read_prototypes") if not ljd.rawdump.prototype.read(state, prototype): if state.stream.eof(): break else: errprint("Failed to read prototype") return False # dump("prototype",prototype,0) prototypes.append(prototype) return True
def _read_flags(parser, header): bits = parser.stream.read_uleb128() header.flags.is_big_endian = bits & _FLAG_IS_BIG_ENDIAN bits &= ~_FLAG_IS_BIG_ENDIAN header.flags.is_stripped = bits & _FLAG_IS_STRIPPED bits &= ~_FLAG_IS_STRIPPED header.flags.has_ffi = bits & _FLAG_HAS_FFI bits &= ~_FLAG_HAS_FFI if bits != 0: errprint("Unknown flags set: {0:08b}", bits) return False return True
def read(parser): global _MAP codeword = parser.stream.read_uint(4) opcode = codeword & 0xFF instruction_class = _MAP[opcode] if instruction_class is None: errprint("Warning: unknown opcode {0:08x}", opcode) instruction_class = instructions.UNKNW # @UndefinedVariable instruction = instruction_class() if instruction_class.opcode != opcode: instruction.opcode = opcode _set_instruction_operands(parser, codeword, instruction) return instruction
def parse(filename): parser = _State() parser.stream.open(filename) header = ljd.rawdump.header.Header() r = True try: r = r and _read_header(parser, header) r = r and _read_prototypes(parser, parser.prototypes) except IOError as e: errprint("I/O error while reading dump: {0}", str(e)) r = False if r and not parser.stream.eof(): errprint("Stopped before whole file was read, something wrong") r = False if r and len(parser.prototypes) != 1: errprint("Invalid prototypes stack order") r = False parser.stream.close() if r: return header, parser.prototypes[0] else: return None, None
def _read_flags(parser, header): bits = parser.stream.read_uleb128() header.flags.is_big_endian = bits & _FLAG_IS_BIG_ENDIAN bits &= ~_FLAG_IS_BIG_ENDIAN header.flags.is_stripped = bits & _FLAG_IS_STRIPPED bits &= ~_FLAG_IS_STRIPPED header.flags.has_ffi = bits & _FLAG_HAS_FFI bits &= ~_FLAG_HAS_FFI # zzw.20180714 pitch: flag value is according to parser.flag when parse proto, not by header.flags parser.flags.is_big_endian = header.flags.is_big_endian parser.flags.is_stripped = header.flags.is_stripped parser.flags.is_big_endian = header.flags.has_ffi if bits != 0: errprint("Unknown flags set: {0:08b}", bits) return False return True
def read(parser): global _MAP codeword = parser.stream.read_uint(4) # errprint ("codeword %08x" % codeword, file=sys.stderr) opcode = codeword & 0xFF # errprint ("opcode %x" % opcode) instruction_class = _MAP[opcode] if instruction_class is None: errprint("Warning: unknown opcode {0:08x}", opcode) instruction_class = instructions.UNKNW # @UndefinedVariable #zzw.20180714 instruction = instruction_class() if instruction_class.opcode != opcode: instruction.opcode = opcode # errprint ("instruction.opcode %x name %s" % (instruction.opcode,instruction.name)) _set_instruction_operands(parser, codeword, instruction) return instruction
def _read_flags(parser, prototype): bits = parser.stream.read_byte() prototype.flags.has_ffi = bool(bits & FLAG_HAS_FFI) bits &= ~FLAG_HAS_FFI prototype.flags.has_iloop = bool(bits & FLAG_HAS_ILOOP) bits &= ~FLAG_HAS_ILOOP prototype.flags.has_jit = not (bits & FLAG_JIT_DISABLED) bits &= ~FLAG_JIT_DISABLED prototype.flags.has_sub_prototypes = bool(bits & FLAG_HAS_CHILD) bits &= ~FLAG_HAS_CHILD prototype.flags.is_variadic = bool(bits & FLAG_IS_VARIADIC) bits &= ~FLAG_IS_VARIADIC if bits != 0: errprint("Unknown prototype flags: {0:08b}", bits) return False return True
def _read_version(state, header): header.version = state.stream.read_byte() if header.version != gconfig.gBCVersion: errprint("header.version {0} is not equals to gconfig.gBCVersion {1}", header.version, gconfig.gBCVersion) errprint("please modify gBCVersion in gconfig.py to make sure gconfig.gBCVersion == header.version") return False if header.version > _MAX_VERSION: errprint("Version {0}: propritary modifications", header.version) return False return True
def _check_magic(state): if state.stream.read_bytes(3) != _MAGIC: errprint("Invalid magic, not a LuaJIT format") return False return True