def parse(code, hdr): if hdr: hdrtext, defines = parse_hdr(hdr) else: hdrtext = None defines = {} bgiop.clear_offsets() inst = {} size = get_code_end(code) pos = 0 while pos < size: addr = pos op, = struct.unpack('<I', code[addr:addr + 4]) if op not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (op, addr)) pos += 4 fmt, pfmt, fcn = bgiop.ops[op] if fmt: n = struct.calcsize(fmt) args = struct.unpack(fmt, code[pos:pos + n]) if fcn: args = fcn(code, addr, defines, *args) inst[addr] = pfmt % args pos += n else: inst[addr] = pfmt offsets = bgiop.offsets.copy() return inst, offsets, hdrtext, defines
def parse(code, hdr): if hdr: hdrtext, defines = parse_hdr(hdr) else: hdrtext = None defines = {} print(hdrtext) print(defines) bgiop.clear_offsets() inst = {} size = get_code_end(code) pos = 0 while pos < size: addr = pos op, = struct.unpack('<I', code[addr:addr+4]) if op not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (op, addr)) pos += 4 fmt, pfmt, fcn = bgiop.ops[op] if fmt: n = struct.calcsize(fmt) args = struct.unpack(fmt, code[pos:pos+n]) if fcn: args = fcn(code, addr, defines, *args) inst[addr] = pfmt % args pos += n else: inst[addr] = pfmt offsets = bgiop.offsets.copy() return inst, offsets, hdrtext, defines
def parse(code): bgiop.clear_offsets() size = get_code_end(code) pos = 0 texts = [] strings = [] while pos < size: addr = pos op, = struct.unpack('<I', code[addr:addr + 4]) if op not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (op, addr)) pos += 4 if op == 0x003: # push_string fmt, _, _ = bgiop.ops[op] n = struct.calcsize(fmt) pos0 = struct.unpack(fmt, code[pos:pos + n])[0] s = get_string(code, addr, pos0) s = asdis.escape(s) strings.append(s) pos += n elif 0x140 <= op <= 0x160: # msg_::f_ if op == 0x140: #or op == 0x143 or op == 0x151 or op == 0x150: if len(strings) == 1: texts.append({ "name": None, "text": strings[0], "opcode": op }) elif len(strings) == 2: texts.append({ "name": strings[0], "text": strings[1], "opcode": op }) else: raise Exception("len(strings) = %d" % len(strings)) # else: # raise Exception("msg_op=0x%x" % op) strings.clear() else: strings.clear() fmt, _, _ = bgiop.ops[op] if fmt: n = struct.calcsize(fmt) pos += n return texts
def parse(code): bgiop.clear_offsets() size = get_code_end(code) pos = 0 texts = [] strings = [] while pos < size: addr = pos op, = struct.unpack('<I', code[addr:addr+4]) if op not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (op, addr)) pos += 4 if op == 0x003: # push_string fmt, _, _ = bgiop.ops[op] n = struct.calcsize(fmt) pos0 = struct.unpack(fmt, code[pos:pos+n])[0] s = get_string(code, addr, pos0) s = asdis.escape(s) strings.append(s) pos += n elif 0x140 <= op <= 0x160: # msg_::f_ if op == 0x140: #or op == 0x143 or op == 0x151 or op == 0x150: if len(strings) == 1: texts.append({ "name":None, "text":strings[0], "opcode":op }) elif len(strings) == 2: texts.append({ "name":strings[0], "text":strings[1], "opcode":op }) else: raise Exception("len(strings) = %d" % len(strings)) # else: # raise Exception("msg_op=0x%x" % op) strings.clear() else: strings.clear() fmt, _, _ = bgiop.ops[op] if fmt: n = struct.calcsize(fmt) pos += n return texts
def parse(code, hdr): """ Parse the code section, with an optional header (0-length bytes otherwise) Returns: tuple(dict, dict, bytes, dict) """ if hdr: hdrtext, defines = parse_hdr(hdr) else: hdrtext = None defines = {} bgiop.clear_offsets() inst = {} size = buriko_common.get_section_boundary(code) pos = 0 idx = 1 while pos < size: addr = pos opcode, = struct.unpack('<I', code[addr:addr + 4]) if opcode not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (opcode, addr)) pos += 4 fmt, pfmt, fcn = bgiop.ops[opcode] if fmt: oplen = struct.calcsize(fmt) args = struct.unpack(fmt, code[pos:pos + oplen]) if fcn: args = fcn(code, addr, defines, *args) if fcn == bgiop.get_string: args = list(args) args.append(idx) idx = idx + 1 inst[addr] = pfmt.format(*args) pos += oplen else: inst[addr] = pfmt offsets = bgiop.offsets.copy() return inst, offsets, hdrtext, defines
def parse(data, texts): hdrsize = 0x1C + struct.unpack('<I', data[0x1C:0x20])[0] hdr = data[:hdrsize] code = data[hdrsize:] bgiop.clear_offsets() size = get_code_end(code) pos = 0 code_out = io.BytesIO() string_out = io.BytesIO() strings = [] stringsTable = {} def getStringOffset(s): if s in stringsTable: return stringsTable[s] o = string_out.tell() + size string_out.write(s.encode('gbk', 'gbk_err') + b'\0') stringsTable[s] = o return o def clearStrings(): for s, o in strings: code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(s))) code_out.seek(0, 2) strings.clear() while pos < size: addr = pos instr = code[addr:addr+4] op, = struct.unpack('<I', instr) if op not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (op, addr)) pos += 4 if op == 0x003: # push_string fmt, _, _ = bgiop.ops[op] n = struct.calcsize(fmt) instr += code[pos:pos+n] pos0 = struct.unpack(fmt, code[pos:pos+n])[0] s = get_string(code, addr, pos0) strings.append((s, code_out.tell()+4)) pos += n elif op == 0x07F: # line fmt, _, _ = bgiop.ops[op] n = struct.calcsize(fmt) pos0, lno = struct.unpack(fmt, code[pos:pos+n]) s = get_string(code, addr, pos0) o = getStringOffset(s) instr += struct.pack(fmt, o, lno) pos += n elif 0x140 <= op <= 0x160: # msg_::f_ if op == 0x140: if len(strings) == 1: t = texts.pop(0) _, o = strings[0] code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(t))) code_out.seek(0, 2) elif len(strings) == 2: t = texts.pop(0) _, o = strings[0] code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(t[0]))) _, o = strings[1] code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(t[1]))) code_out.seek(0, 2) else: raise Exception("len(strings) = %d" % len(strings)) strings.clear() else: clearStrings() else: clearStrings() fmt, _, _ = bgiop.ops[op] if fmt: n = struct.calcsize(fmt) instr += code[pos:pos+n] pos += n code_out.write(instr) return hdr + code_out.getvalue() + string_out.getvalue()
def parse(data, texts): hdrsize = 0x1C + struct.unpack('<I', data[0x1C:0x20])[0] hdr = data[:hdrsize] code = data[hdrsize:] bgiop.clear_offsets() size = get_code_end(code) pos = 0 code_out = io.BytesIO() string_out = io.BytesIO() strings = [] stringsTable = {} def getStringOffset(s): if s in stringsTable: return stringsTable[s] o = string_out.tell() + size string_out.write(s.encode('gbk', 'gbk_err') + b'\0') stringsTable[s] = o return o def clearStrings(): for s, o in strings: code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(s))) code_out.seek(0, 2) strings.clear() while pos < size: addr = pos instr = code[addr:addr + 4] op, = struct.unpack('<I', instr) if op not in bgiop.ops: raise Exception('size unknown for op %02x @ offset %05x' % (op, addr)) pos += 4 if op == 0x003: # push_string fmt, _, _ = bgiop.ops[op] n = struct.calcsize(fmt) instr += code[pos:pos + n] pos0 = struct.unpack(fmt, code[pos:pos + n])[0] s = get_string(code, addr, pos0) strings.append((s, code_out.tell() + 4)) pos += n elif op == 0x07F: # line fmt, _, _ = bgiop.ops[op] n = struct.calcsize(fmt) pos0, lno = struct.unpack(fmt, code[pos:pos + n]) s = get_string(code, addr, pos0) o = getStringOffset(s) instr += struct.pack(fmt, o, lno) pos += n elif 0x140 <= op <= 0x160: # msg_::f_ if op == 0x140: if len(strings) == 1: t = texts.pop(0) _, o = strings[0] code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(t))) code_out.seek(0, 2) elif len(strings) == 2: t = texts.pop(0) _, o = strings[0] code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(t[0]))) _, o = strings[1] code_out.seek(o, 0) code_out.write(struct.pack('<I', getStringOffset(t[1]))) code_out.seek(0, 2) else: raise Exception("len(strings) = %d" % len(strings)) strings.clear() else: clearStrings() else: clearStrings() fmt, _, _ = bgiop.ops[op] if fmt: n = struct.calcsize(fmt) instr += code[pos:pos + n] pos += n code_out.write(instr) return hdr + code_out.getvalue() + string_out.getvalue()