Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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()
Exemple #7
0
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()