ROM Hack Cheat Codes AMS and Sx Os, Add and Request

  • Thread starter Thread starter matias3ds
  • Start date Start date
  • Views Views 24,030,141
  • Replies Replies 73,114
  • Likes Likes 249
hello i am just curiouse if you have had chance to look at the dof no blur cheat for EOW its ok if you havent yet i know your busy and i really appreciate your work so thank you again for everything you have done
i did and its the instruction didnt change internally. i have no issue with it showing up 100% of the time. idk what to say :/ sorry.
 
Arcade Archives FANTASTIC NIGHT DREAMS COTTOn 1.0.2
TID: 0100DDA020B80000
BID: 4F652D055516D008

[Breeze beta98a Arcade Archives FANTASTIC NIGHT DREAMS COTTOn 1.0.1 TID: 0100DDA020B80000 BID: 74E7766E6234AB77]

[Inf.Credits]
580F0000 012F2C88
780F0000 000000FC
610F0000 00000000 00000009

[Inf.Lives]
580F0000 012F2C88
780F0000 00003E2C
610F0000 00000000 00000009

[Invincibility]
580F0000 012F2C88
780F0000 0000299D
610F0000 00000000 000000FF

[Inf.Magic]
580F0000 012F2C88
780F0000 00003E46
610F0000 00000000 00000006

[Select Magic(1=Fire,2=Thunder)]
580F0000 012F2C88
780F0000 00003E4C
610F0000 00000000 00000001

[Always Max Exp]
580F0000 012F2C88
780F0000 00003E40
620F0000 00000000 00000168

[Always All Faries]
580F0000 012F2C88
780F0000 00003E2B
610F0000 00000000 00000006

[Breeze beta99 Arcade Archives FANTASTIC NIGHT DREAMS COTTOn 1.0.2 TID: 0100DDA020B80000 BID: 4F652D055516D008]

[Inf.Credits]
580F0000 012F2C88
780F0000 000000FC
610F0000 00000000 00000009

[Inf.Lives]
580F0000 012F2C88
780F0000 00003E2C
610F0000 00000000 00000009

[Invincibility]
580F0000 012F2C88
780F0000 0000299D
610F0000 00000000 000000FF

[Inf.Magic]
580F0000 012F2C88
780F0000 00003E46
610F0000 00000000 00000006

[Select Magic(1=Fire,2=Thunder)]
580F0000 012F2C88
780F0000 00003E4C
610F0000 00000000 00000001

[Always Max Exp]
580F0000 012F2C88
780F0000 00003E40
620F0000 00000000 00000168

[Always All Faries]
580F0000 012F2C88
780F0000 00003E2B
610F0000 00000000 00000006

Original Code by ネオ•グランゾン

Note: i also inserted the previous version for those who don't have it.
 

Attachments

Hello! I'm kinda stuck on a possible code for Fire Emblem Warriors USA Tid: 0100F15003E64000. Bid: 1953770037acc52a. The code is for the Musou gauge (special attack). The value for 1 bar is 100 exact. But even when using Edizon to find the value,
it just resets itself mid battle. Could someone make a pointer for this? And possibly a cheat for infinite awakening gauge to?
Thanks everyone!!
 
  • Like
Reactions: 100time
can it be used with emulator? i want to make the code but since i have no console only emu
so full credit to Tom on his script https://github.com/tomvita/Breeze-Beta/blob/master/disassemble_cheats.py

I am just waiting on him to approve more of my bug fix pull request but you can grab from his link.

I do also have one with the pending bug fixes here

This fixes 8 byte write instructions to actually convert rather than leave empty. (you can copy this code then paste into a notepad and save as a .py file to make the script

Python:
import sys
from enum import Enum

try:
    from capstone import Cs, CS_ARCH_ARM64, CS_MODE_ARM
    CAPSTONE_AVAILABLE = True
except ImportError:
    CAPSTONE_AVAILABLE = False

# Based on source/opcode.hpp

class CheatVmOpcodeType(Enum):
    StoreStatic = 0
    BeginConditionalBlock = 1
    EndConditionalBlock = 2
    ControlLoop = 3
    LoadRegisterStatic = 4
    LoadRegisterMemory = 5
    StoreStaticToAddress = 6
    PerformArithmeticStatic = 7
    BeginKeypressConditionalBlock = 8
    PerformArithmeticRegister = 9
    StoreRegisterToAddress = 10
    Reserved11 = 11
    ExtendedWidth = 12
    BeginRegisterConditionalBlock = 0xC0
    SaveRestoreRegister = 0xC1
    SaveRestoreRegisterMask = 0xC2
    ReadWriteStaticRegister = 0xC3
    BeginExtendedKeypressConditionalBlock = 0xC4
    DoubleExtendedWidth = 0xF0
    PauseProcess = 0xFF0
    ResumeProcess = 0xFF1
    DebugLog = 0xFFF

class MemoryAccessType(Enum):
    MainNso = 0
    Heap = 1
    Alias = 2
    Aslr = 3
    Blank = 4

class ConditionalComparisonType(Enum):
    GT = 1
    GE = 2
    LT = 3
    LE = 4
    EQ = 5
    NE = 6

class RegisterArithmeticType(Enum):
    Addition = 0
    Subtraction = 1
    Multiplication = 2
    LeftShift = 3
    RightShift = 4
    LogicalAnd = 5
    LogicalOr = 6
    LogicalNot = 7
    LogicalXor = 8
    None_ = 9
    FloatAddition = 10
    FloatMultiplication = 11
    DoubleAddition = 12
    DoubleMultiplication = 13

class StoreRegisterOffsetType(Enum):
    None_ = 0
    Reg = 1
    Imm = 2
    MemReg = 3
    MemImm = 4
    MemImmReg = 5

class CompareRegisterValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    StaticValue = 4
    OtherRegister = 5
    OffsetValue = 6
   
class SaveRestoreRegisterOpType(Enum):
    Restore = 0
    Save = 1
    ClearSaved = 2
    ClearRegs = 3

class DebugLogValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    RegisterValue = 4

CONDITION_STR = {
    ConditionalComparisonType.GT: ">",
    ConditionalComparisonType.GE: ">=",
    ConditionalComparisonType.LT: "<",
    ConditionalComparisonType.LE: "<=",
    ConditionalComparisonType.EQ: "==",
    ConditionalComparisonType.NE: "!=",
}

MATH_STR = {
    RegisterArithmeticType.Addition: "+",
    RegisterArithmeticType.Subtraction: "-",
    RegisterArithmeticType.Multiplication: "*",
    RegisterArithmeticType.LeftShift: "<<",
    RegisterArithmeticType.RightShift: ">>",
    RegisterArithmeticType.LogicalAnd: "&",
    RegisterArithmeticType.LogicalOr: "|",
    RegisterArithmeticType.LogicalNot: "!",
    RegisterArithmeticType.LogicalXor: "^",
    RegisterArithmeticType.None_: "",
    RegisterArithmeticType.FloatAddition: "+f",
    RegisterArithmeticType.FloatMultiplication: "*f",
    RegisterArithmeticType.DoubleAddition: "+d",
    RegisterArithmeticType.DoubleMultiplication: "*d",
}

OPERAND_STR = {
    SaveRestoreRegisterOpType.Restore: "Restore",
    SaveRestoreRegisterOpType.Save: "Save",
    SaveRestoreRegisterOpType.ClearSaved: "ClearSaved",
    SaveRestoreRegisterOpType.ClearRegs: "ClearRegs",
}


class VmInt:
    def __init__(self, value=0):
        self.value = value

class CheatVmOpcode:
    def __init__(self):
        self.opcode = None
        self.size = 0
        self.str = ""

def get_next_dword(opcodes, instruction_ptr):
    if instruction_ptr >= len(opcodes):
        return None, instruction_ptr + 1
    return opcodes[instruction_ptr], instruction_ptr + 1

def get_next_vm_int(opcodes, instruction_ptr, bit_width):
    val = VmInt()
   
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None, instruction_ptr

    if bit_width == 1:
        val.value = first_dword & 0xFF
    elif bit_width == 2:
        val.value = first_dword & 0xFFFF
    elif bit_width == 4:
        val.value = first_dword
    elif bit_width == 8:
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        if second_dword is None:
            return None, instruction_ptr
        val.value = (first_dword << 32) | second_dword
    else:
        # Invalid bit_width, but I'll assign the dword to avoid crashing.
        val.value = first_dword
       
    return val, instruction_ptr


def mem_type_str(mem_type):
    if mem_type == MemoryAccessType.MainNso: return "Main"
    if mem_type == MemoryAccessType.Heap: return "Heap"
    if mem_type == MemoryAccessType.Alias: return "Alias"
    if mem_type == MemoryAccessType.Aslr: return "Aslr"
    return ""

def arm64_disassemble(value, bit_width, address):
    if not CAPSTONE_AVAILABLE:
        return ""
   
    md = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
    code = value.to_bytes(bit_width, byteorder='little')
   
    disassembled = []
    try:
        for i in md.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        return "; ".join(disassembled).strip()
    except Exception:
        return "" # Return empty string if Capstone fails


def decode_next_opcode(opcodes, index):
    instruction_ptr = index
   
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None

    out = CheatVmOpcode()
   
    opcode_val = (first_dword >> 28) & 0xF
    if opcode_val >= CheatVmOpcodeType.ExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 24) & 0xF)
    if opcode_val >= CheatVmOpcodeType.DoubleExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 20) & 0xF)

    try:
        out.opcode = CheatVmOpcodeType(opcode_val)
    except ValueError:
        out.str = f"Unknown opcode: {hex(opcode_val)}"
        out.size = 1
        return out

    if out.opcode == CheatVmOpcodeType.StoreStatic:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        offset_register = (first_dword >> 16) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFF) << 32) | second_dword
       
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
       
        out.str = f"[{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] = 0x{value.value:X}"
       
        value_for_disasm = value.value
        if bit_width == 8:
            # The 64-bit value is read as (high_dword << 32 | low_dword).
            # For little-endian disassembly, the byte stream needs to be
            # ordered by the dwords as they appear in the file (high then low).
            # value.to_bytes(..., 'little') would produce bytes(low) then bytes(high).
            # To fix this, swap the dwords before converting to bytes.
            high_dw = value.value >> 32
            low_dw = value.value & 0xFFFFFFFF
            value_for_disasm = (low_dw << 32) | high_dw

        if CAPSTONE_AVAILABLE and (bit_width == 4 or bit_width == 8):
            asm = arm64_disassemble(value_for_disasm, bit_width, rel_address)
            if asm:
                out.str += f"  {asm}"
        else:
            out.str += " (Disassembly skipped - Capstone not available or invalid bit_width)"
   
    elif out.opcode == CheatVmOpcodeType.BeginConditionalBlock:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        include_ofs_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_reg_index = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFF) << 32) | second_dword
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
        ofs_reg_str = f"R{ofs_reg_index}+" if include_ofs_reg else ""
        out.str = f"If [{mem_type_str(mem_type)}+{ofs_reg_str}0x{rel_address:010X}] {CONDITION_STR.get(cond_type, '?')} 0x{value.value:X}"

    elif out.opcode == CheatVmOpcodeType.EndConditionalBlock:
        end_type = (first_dword >> 24) & 0xF
        out.str = "Else" if end_type == 1 else "Endif"

    elif out.opcode == CheatVmOpcodeType.ControlLoop:
        start_loop = ((first_dword >> 24) & 0xF) == 0
        reg_index = (first_dword >> 16) & 0xF
        if start_loop:
            num_iters, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
            out.str = f"Loop Start R{reg_index} = {num_iters}"
        else:
            out.str = "Loop stop"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterStatic:
        reg_index = (first_dword >> 16) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit value
        out.str = f"R{reg_index} = 0x{value.value:016X}"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterMemory:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        reg_index = (first_dword >> 16) & 0xF
        load_from_reg = (first_dword >> 12) & 0xF
        offset_register = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFF) << 32) | second_dword
        if load_from_reg == 3:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] W={bit_width}"
        elif load_from_reg:
            src_reg = reg_index if load_from_reg == 1 else offset_register
            out.str = f"R{reg_index} = [R{src_reg}+0x{rel_address:010X}] W={bit_width}"
        else:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+0x{rel_address:010X}] W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.StoreStaticToAddress:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        add_offset_reg = ((first_dword >> 8) & 0xF) != 0
        offset_reg_index = (first_dword >> 4) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit
        if add_offset_reg:
            out.str = f"[R{reg_index}+R{offset_reg_index}] = 0x{value.value:016X} W={bit_width}"
        else:
            out.str = f"[R{reg_index}] = 0x{value.value:016X} W={bit_width}"
        if increment_reg:
            out.str += f" R{reg_index} += {bit_width}"

    elif out.opcode == CheatVmOpcodeType.PerformArithmeticStatic:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 12) & 0xF)
        value, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        out.str = f"R{reg_index} = R{reg_index} {MATH_STR.get(math_type, '?')} 0x{value:X} W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.BeginKeypressConditionalBlock:
        key_mask = first_dword & 0x0FFFFFFF
        out.str = f"If keyheld 0x{key_mask:X}"
       
    elif out.opcode == CheatVmOpcodeType.PerformArithmeticRegister:
        bit_width = (first_dword >> 24) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 20) & 0xF)
        dst_reg_index = (first_dword >> 16) & 0xF
        src_reg_1_index = (first_dword >> 12) & 0xF
        has_immediate = ((first_dword >> 8) & 0xF) != 0
        if has_immediate:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} 0x{value.value:X} W={bit_width}"
        else:
            src_reg_2_index = (first_dword >> 4) & 0xF
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} R{src_reg_2_index} W={bit_width}"
   
    elif out.opcode == CheatVmOpcodeType.StoreRegisterToAddress:
        bit_width = (first_dword >> 24) & 0xF
        str_reg_index = (first_dword >> 20) & 0xF
        addr_reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_type = StoreRegisterOffsetType((first_dword >> 8) & 0xF)
        ofs_reg_index = (first_dword >> 4) & 0xF
       
        addr_str = ""
        if ofs_type == StoreRegisterOffsetType.None_:
            addr_str = f"[R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Reg:
            addr_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Imm:
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.MemImm:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemImmReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}+0x{rel_address.value:X}]"
       
        out.str = f"{addr_str} = R{str_reg_index} W={bit_width}"
        if increment_reg:
            out.str += f" R{addr_reg_index} += {bit_width}"
           
    elif out.opcode == CheatVmOpcodeType.BeginRegisterConditionalBlock:
        bit_width = (first_dword >> 20) & 0xF
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        val_reg_index = (first_dword >> 12) & 0xF
        comp_type = CompareRegisterValueType((first_dword >> 8) & 0xF)
       
        comp_str = ""
        if comp_type == CompareRegisterValueType.StaticValue:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            comp_str = f"0x{value.value:X}"
        elif comp_type == CompareRegisterValueType.OtherRegister:
            other_reg_index = (first_dword >> 4) & 0xF
            comp_str = f"R{other_reg_index}"
        else: # Memory access
            mem_type = MemoryAccessType((first_dword >> 4) & 0xF)
            if comp_type in [CompareRegisterValueType.MemoryRelAddr, CompareRegisterValueType.RegisterRelAddr]:
                rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4)
                if comp_type == CompareRegisterValueType.MemoryRelAddr:
                    comp_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
                else: # RegisterRelAddr
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
            else: # MemoryOfsReg, RegisterOfsReg
                ofs_reg_index = first_dword & 0xF
                if comp_type == CompareRegisterValueType.MemoryOfsReg:
                    comp_str = f"[{mem_type_str(mem_type)}+R{ofs_reg_index}]"
                else: # RegisterOfsReg
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        out.str = f"If R{val_reg_index} {CONDITION_STR.get(cond_type, '?')} {comp_str}"
       
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegister:
        dst_index = (first_dword >> 16) & 0xF
        src_index = (first_dword >> 8) & 0xF
        op_type = SaveRestoreRegisterOpType((first_dword >> 4) & 0xF)
        out.str = f"SaveRestoreRegister dst={dst_index} src={src_index} {OPERAND_STR.get(op_type, '?')}"
       
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegisterMask:
        op_type = SaveRestoreRegisterOpType((first_dword >> 20) & 0xF)
        mask = first_dword & 0xFFFF
        out.str = f"SaveRestoreRegisterMask {OPERAND_STR.get(op_type, '?')} mask=0x{mask:04X}"
       
    elif out.opcode == CheatVmOpcodeType.ReadWriteStaticRegister:
        static_idx = (first_dword >> 4) & 0xFF
        idx = first_dword & 0xF
        out.str = f"ReadWriteStaticRegister static_idx=0x{static_idx:X} idx={idx}"
       
    elif out.opcode == CheatVmOpcodeType.BeginExtendedKeypressConditionalBlock:
        auto_repeat = ((first_dword >> 20) & 0xF) != 0
        key_mask, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8)
        out.str = f"If {'keyheld' if auto_repeat else 'keydown'} 0x{key_mask.value:X}"
       
    elif out.opcode == CheatVmOpcodeType.PauseProcess:
        out.str = "PauseProcess"
       
    elif out.opcode == CheatVmOpcodeType.ResumeProcess:
        out.str = "ResumeProcess"
       
    elif out.opcode == CheatVmOpcodeType.DebugLog:
        out.str = "DebugLog" # Simplified

    else:
        out.str = f"Opcode {out.opcode.name} not implemented in this script."

    out.size = instruction_ptr - index
    return out

def disassemble_cheat(opcodes):
    """Disassembles a list of opcodes for a single cheat."""
    index = 0
    while index < len(opcodes):
        opcode_info = decode_next_opcode(opcodes, index)
        if not opcode_info:
            break
       
        raw_opcodes_list = opcodes[index : index + opcode_info.size]
        raw_opcodes_str = " ".join([f"{opc:08X}" for opc in raw_opcodes_list])

        print(f"{raw_opcodes_str:<40} {opcode_info.str}")
       
        index += opcode_info.size

def disassemble_opcodes_from_file(file_path):
    try:
        with open(file_path, 'r') as f:
            cheat_opcodes = []
            for line in f:
                stripped_line = line.strip()
                if not stripped_line:
                    continue

                if (stripped_line.startswith('[') and stripped_line.endswith(']')) or \
                   (stripped_line.startswith('{') and stripped_line.endswith('}')):
                    if cheat_opcodes:
                        disassemble_cheat(cheat_opcodes)
                        cheat_opcodes = []
                    print(f"\n{stripped_line}")
                else:
                    parts = stripped_line.split()
                    for part in parts:
                        if part:
                            try:
                                cheat_opcodes.append(int(part, 16))
                            except ValueError:
                                # Ignore non-hex parts, could be comments
                                pass
            # After the loop, process any remaining opcodes
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)

    except FileNotFoundError:
        print(f"Error: The file '{file_path}' was not found.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def disassemble_opcodes_from_string(opcodes_str):
    cheat_opcodes = []
    for line in opcodes_str.splitlines():
        line = line.strip()
        if not line:
            continue
        if line.startswith('[') and line.endswith(']'):
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)
                cheat_opcodes = []
            print(f"\n{line}")
        else:
            parts = line.split()
            for part in parts:
                try:
                    cheat_opcodes.append(int(part, 16))
                except ValueError:
                    pass  # Ignore non-hex parts
    if cheat_opcodes:
        disassemble_cheat(cheat_opcodes)

def main():
    """Main function to handle command-line arguments or interactive mode."""
    if not CAPSTONE_AVAILABLE:
        print("Capstone library not found. Please install it with 'pip install capstone'")
        sys.exit(1)

    # If a command-line argument is provided, treat it as a file path
    if len(sys.argv) > 1:
        file_path = sys.argv[1]
        print(f"--- Disassembling from file: {file_path} ---")
        disassemble_opcodes_from_file(file_path)
        input("\nPress Enter to exit...")
    else:
   
     if len(sys.argv) != 2:
        print("Usage: python disassemble_cheats.py <path_to_opcode_file>")
        example_file = 'asm.txt'
        print(f"\nNo file provided. Trying with example file: '{example_file}'")
        try:
            with open(example_file, 'r'):
                disassemble_opcodes_from_file(example_file)
        except FileNotFoundError:
            print(f"Example file '{example_file}' not found.")
           
        print("--- Interactive Mode ---")
        while True:
            print("\nPaste your opcodes (type 'done' on a new line to finish):")
            opcodes_str = ""
            while True:
                try:
                    line = input()
                    if line.strip().lower() == 'done':
                        break
                    opcodes_str += line + "\n"
                except EOFError:
                    break
           
            if opcodes_str.strip():
                disassemble_opcodes_from_string(opcodes_str)
           
            choice = input("\nDisassemble more? (yes/no): ")
            if choice.strip().lower() != 'yes':
                break
               


if __name__ == "__main__":
    main()


Then this version here i did up is just a test im doing up for him.. this has arm32 support for games that use that like Ty the tasmanian tiger HD, Mario kart 8 D pre 3.0.4, etc. so if you know the codes are arm32 instructions choose that as your architecture...


Python:
import sys
from enum import Enum

try:
    from capstone import Cs, CS_ARCH_ARM64, CS_ARCH_ARM, CS_MODE_ARM, CS_MODE_THUMB
    CAPSTONE_AVAILABLE = True
except ImportError:
    CAPSTONE_AVAILABLE = False

# Global variable to store the target architecture chosen by the user
TARGET_ARCH = None

# Based on source/opcode.hpp

class CheatVmOpcodeType(Enum):
    StoreStatic = 0
    BeginConditionalBlock = 1
    EndConditionalBlock = 2
    ControlLoop = 3
    LoadRegisterStatic = 4
    LoadRegisterMemory = 5
    StoreStaticToAddress = 6
    PerformArithmeticStatic = 7
    BeginKeypressConditionalBlock = 8
    PerformArithmeticRegister = 9
    StoreRegisterToAddress = 10
    Reserved11 = 11
    ExtendedWidth = 12
    BeginRegisterConditionalBlock = 0xC0
    SaveRestoreRegister = 0xC1
    SaveRestoreRegisterMask = 0xC2
    ReadWriteStaticRegister = 0xC3
    BeginExtendedKeypressConditionalBlock = 0xC4
    DoubleExtendedWidth = 0xF0
    PauseProcess = 0xFF0
    ResumeProcess = 0xFF1
    DebugLog = 0xFFF

class MemoryAccessType(Enum):
    MainNso = 0
    Heap = 1
    Alias = 2
    Aslr = 3
    Blank = 4

class ConditionalComparisonType(Enum):
    GT = 1
    GE = 2
    LT = 3
    LE = 4
    EQ = 5
    NE = 6

class RegisterArithmeticType(Enum):
    Addition = 0
    Subtraction = 1
    Multiplication = 2
    LeftShift = 3
    RightShift = 4
    LogicalAnd = 5
    LogicalOr = 6
    LogicalNot = 7
    LogicalXor = 8
    None_ = 9
    FloatAddition = 10
    FloatMultiplication = 11
    DoubleAddition = 12
    DoubleMultiplication = 13

class StoreRegisterOffsetType(Enum):
    None_ = 0
    Reg = 1
    Imm = 2
    MemReg = 3
    MemImm = 4
    MemImmReg = 5

class CompareRegisterValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    StaticValue = 4
    OtherRegister = 5
    OffsetValue = 6
   
class SaveRestoreRegisterOpType(Enum):
    Restore = 0
    Save = 1
    ClearSaved = 2
    ClearRegs = 3

class DebugLogValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    RegisterValue = 4

CONDITION_STR = {
    ConditionalComparisonType.GT: ">",
    ConditionalComparisonType.GE: ">=",
    ConditionalComparisonType.LT: "<",
    ConditionalComparisonType.LE: "<=",
    ConditionalComparisonType.EQ: "==",
    ConditionalComparisonType.NE: "!=",
}

MATH_STR = {
    RegisterArithmeticType.Addition: "+",
    RegisterArithmeticType.Subtraction: "-",
    RegisterArithmeticType.Multiplication: "*",
    RegisterArithmeticType.LeftShift: "<<",
    RegisterArithmeticType.RightShift: ">>",
    RegisterArithmeticType.LogicalAnd: "&",
    RegisterArithmeticType.LogicalOr: "|",
    RegisterArithmeticType.LogicalNot: "!",
    RegisterArithmeticType.LogicalXor: "^",
    RegisterArithmeticType.None_: "",
    RegisterArithmeticType.FloatAddition: "+f",
    RegisterArithmeticType.FloatMultiplication: "*f",
    RegisterArithmeticType.DoubleAddition: "+d",
    RegisterArithmeticType.DoubleMultiplication: "*d",
}

OPERAND_STR = {
    SaveRestoreRegisterOpType.Restore: "Restore",
    SaveRestoreRegisterOpType.Save: "Save",
    SaveRestoreRegisterOpType.ClearSaved: "ClearSaved",
    SaveRestoreRegisterOpType.ClearRegs: "ClearRegs",
}


class VmInt:
    def __init__(self, value=0):
        self.value = value

class CheatVmOpcode:
    def __init__(self):
        self.opcode = None
        self.size = 0
        self.str = ""

def get_next_dword(opcodes, instruction_ptr):
    if instruction_ptr >= len(opcodes):
        return None, instruction_ptr + 1
    return opcodes[instruction_ptr], instruction_ptr + 1

def get_next_vm_int(opcodes, instruction_ptr, bit_width):
    val = VmInt()
   
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None, instruction_ptr

    if bit_width == 1:
        val.value = first_dword & 0xFF
    elif bit_width == 2:
        val.value = first_dword & 0xFFFF
    elif bit_width == 4:
        val.value = first_dword
    elif bit_width == 8:
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        if second_dword is None:
            return None, instruction_ptr
        val.value = (first_dword << 32) | second_dword
    else:
        # Invalid bit_width, but we'll assign the dword to avoid crashing.
        val.value = first_dword
       
    return val, instruction_ptr


def mem_type_str(mem_type):
    if mem_type == MemoryAccessType.MainNso: return "Main"
    if mem_type == MemoryAccessType.Heap: return "Heap"
    if mem_type == MemoryAccessType.Alias: return "Alias"
    if mem_type == MemoryAccessType.Aslr: return "Aslr"
    return ""

def arm64_disassemble(value, address):
    """
    Disassembles a 4-byte value as an ARM64 instruction.
    ARM64 instructions are always 4 bytes.
    """
    if not CAPSTONE_AVAILABLE:
        return ""
   
    md = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
    # Ensure we always convert to 4 bytes for ARM64 instruction disassembly
    code = (value & 0xFFFFFFFF).to_bytes(4, byteorder='little')
   
    disassembled = []
    try:
        for i in md.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        return "; ".join(disassembled).strip()
    except Exception:
        return "" # Return empty string if Capstone fails

def arm32_disassemble(value, address):
    """
    Disassembles a 4-byte value as an ARM32 instruction (trying ARM then Thumb).
    ARM32/Thumb instructions are 2 or 4 bytes. I provide 4 bytes and let Capstone handle it.
    """
    if not CAPSTONE_AVAILABLE:
        return ""
   
    code = value.to_bytes(4, byteorder='little') # ARM32 instructions are 4 bytes (or 2 for Thumb, but provide 4)
   
    # Try ARM mode first
    md_arm = Cs(CS_ARCH_ARM, CS_MODE_ARM)
    disassembled = []
    try:
        for i in md_arm.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        if disassembled:
            return "; ".join(disassembled).strip()
    except Exception:
        pass # Fall through to Thumb mode if ARM disassembly fails or produces nothing

    # If ARM mode didn't work or produced no output, try Thumb mode
    md_thumb = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
    disassembled = []
    try:
        for i in md_thumb.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        if disassembled:
            return "; ".join(disassembled).strip()
    except Exception:
        pass

    return "" # Return empty string if neither ARM nor Thumb can disassemble


def decode_next_opcode(opcodes, index):
    instruction_ptr = index
   
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None

    out = CheatVmOpcode()
   
    opcode_val = (first_dword >> 28) & 0xF
    if opcode_val >= CheatVmOpcodeType.ExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 24) & 0xF)
    if opcode_val >= CheatVmOpcodeType.DoubleExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 20) & 0xF)

    try:
        out.opcode = CheatVmOpcodeType(opcode_val)
    except ValueError:
        out.str = f"Unknown opcode: {hex(opcode_val)}"
        out.size = 1
        return out

    if out.opcode == CheatVmOpcodeType.StoreStatic:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        offset_register = (first_dword >> 16) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        # Assuming rel_address high 24 bits are from first_dword & 0xFFFFFF
        # and low 32 bits from second_dword.
        rel_address = ((first_dword & 0xFFFFFF) << 32) | second_dword
       
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
       
        out.str = f"[{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] = 0x{value.value:X}"
       
        # Determine disassembly based on bit_width and global TARGET_ARCH
        if CAPSTONE_AVAILABLE:
            if bit_width == 8: # 8-byte value: Disassemble both halves based on TARGET_ARCH
                high_32_bits = (value.value >> 32) & 0xFFFFFFFF
                low_32_bits = value.value & 0xFFFFFFFF

                combined_asm = []
                if TARGET_ARCH == "ARM64":
                    asm_low = arm64_disassemble(low_32_bits, rel_address)
                    asm_high = arm64_disassemble(high_32_bits, rel_address + 4)
                    arch_label = "ARM64"
                elif TARGET_ARCH == "ARM32":
                    asm_low = arm32_disassemble(low_32_bits, rel_address)
                    asm_high = arm32_disassemble(high_32_bits, rel_address + 4)
                    arch_label = "ARM32"
                else: # Should not happen if TARGET_ARCH is set correctly
                    asm_low = ""
                    asm_high = ""
                    arch_label = "UNKNOWN ARCH"

                if asm_low:
                    combined_asm.append(f"[{hex(rel_address)}] {asm_low}")
                if asm_high:
                    combined_asm.append(f"[{hex(rel_address + 4)}] {asm_high}")
               
                if combined_asm:
                    out.str += f"  ({arch_label}: {'; '.join(combined_asm)})"
                else:
                    out.str += f"  ({arch_label}: No disassembly)"

            elif bit_width == 4: # 4-byte value: Use TARGET_ARCH to decide
                if TARGET_ARCH == "ARM64":
                    asm = arm64_disassemble(value.value, rel_address)
                    if asm:
                        out.str += f"  (ARM64: {asm})"
                elif TARGET_ARCH == "ARM32":
                    asm = arm32_disassemble(value.value, rel_address)
                    if asm:
                        out.str += f"  (ARM32: {asm})"
                else: # Should not happen if TARGET_ARCH is set correctly
                    out.str += " (Disassembly type not determined)"
        else:
            out.str += " (Disassembly skipped - Capstone not available)"
   
    elif out.opcode == CheatVmOpcodeType.BeginConditionalBlock:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        include_ofs_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_reg_index = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFFFFFF) << 32) | second_dword # Adjusted to mask 24 bits
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
        ofs_reg_str = f"R{ofs_reg_index}+" if include_ofs_reg else ""
        out.str = f"If [{mem_type_str(mem_type)}+{ofs_reg_str}0x{rel_address:010X}] {CONDITION_STR.get(cond_type, '?')} 0x{value.value:X}"

    elif out.opcode == CheatVmOpcodeType.EndConditionalBlock:
        end_type = (first_dword >> 24) & 0xF
        out.str = "Else" if end_type == 1 else "Endif"

    elif out.opcode == CheatVmOpcodeType.ControlLoop:
        start_loop = ((first_dword >> 24) & 0xF) == 0
        reg_index = (first_dword >> 16) & 0xF
        if start_loop:
            num_iters, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
            out.str = f"Loop Start R{reg_index} = {num_iters}"
        else:
            out.str = "Loop stop"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterStatic:
        reg_index = (first_dword >> 16) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit value
        out.str = f"R{reg_index} = 0x{value.value:016X}"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterMemory:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        reg_index = (first_dword >> 16) & 0xF
        load_from_reg = (first_dword >> 12) & 0xF
        offset_register = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFFFFFF) << 32) | second_dword # Adjusted to mask 24 bits
        if load_from_reg == 3:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] W={bit_width}"
        elif load_from_reg:
            src_reg = reg_index if load_from_reg == 1 else offset_register
            out.str = f"R{reg_index} = [R{src_reg}+0x{rel_address:010X}] W={bit_width}"
        else:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+0x{rel_address:010X}] W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.StoreStaticToAddress:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        add_offset_reg = ((first_dword >> 8) & 0xF) != 0
        offset_reg_index = (first_dword >> 4) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit
        if add_offset_reg:
            out.str = f"[R{reg_index}+R{offset_reg_index}] = 0x{value.value:016X} W={bit_width}"
        else:
            out.str = f"[R{reg_index}] = 0x{value.value:016X} W={bit_width}"
        if increment_reg:
            out.str += f" R{reg_index} += {bit_width}"

    elif out.opcode == CheatVmOpcodeType.PerformArithmeticStatic:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 12) & 0xF)
        value, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        out.str = f"R{reg_index} = R{reg_index} {MATH_STR.get(math_type, '?')} 0x{value:X} W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.BeginKeypressConditionalBlock:
        key_mask = first_dword & 0x0FFFFFFF
        out.str = f"If keyheld 0x{key_mask:X}"
       
    elif out.opcode == CheatVmOpcodeType.PerformArithmeticRegister:
        bit_width = (first_dword >> 24) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 20) & 0xF)
        dst_reg_index = (first_dword >> 16) & 0xF
        src_reg_1_index = (first_dword >> 12) & 0xF
        has_immediate = ((first_dword >> 8) & 0xF) != 0
        if has_immediate:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} 0x{value.value:X} W={bit_width}"
        else:
            src_reg_2_index = (first_dword >> 4) & 0xF
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} R{src_reg_2_index} W={bit_width}"
   
    elif out.opcode == CheatVmOpcodeType.StoreRegisterToAddress:
        bit_width = (first_dword >> 24) & 0xF
        str_reg_index = (first_dword >> 20) & 0xF
        addr_reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_type = StoreRegisterOffsetType((first_dword >> 8) & 0xF)
        ofs_reg_index = (first_dword >> 4) & 0xF
       
        addr_str = ""
        if ofs_type == StoreRegisterOffsetType.None_:
            addr_str = f"[R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Reg:
            addr_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Imm:
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.MemImm:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemImmReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}+0x{rel_address.value:X}]"
       
        out.str = f"{addr_str} = R{str_reg_index} W={bit_width}"
        if increment_reg:
            out.str += f" R{addr_reg_index} += {bit_width}"
           
    elif out.opcode == CheatVmOpcodeType.BeginRegisterConditionalBlock:
        bit_width = (first_dword >> 20) & 0xF
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        val_reg_index = (first_dword >> 12) & 0xF
        comp_type = CompareRegisterValueType((first_dword >> 8) & 0xF)
       
        comp_str = ""
        if comp_type == CompareRegisterValueType.StaticValue:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            comp_str = f"0x{value.value:X}"
        elif comp_type == CompareRegisterValueType.OtherRegister:
            other_reg_index = (first_dword >> 4) & 0xF
            comp_str = f"R{other_reg_index}"
        else: # Memory access
            mem_type = MemoryAccessType((first_dword >> 4) & 0xF)
            if comp_type in [CompareRegisterValueType.MemoryRelAddr, CompareRegisterValueType.RegisterRelAddr]:
                rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4)
                if comp_type == CompareRegisterValueType.MemoryRelAddr:
                    comp_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
                else: # RegisterRelAddr
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
            else: # MemoryOfsReg, RegisterOfsReg
                ofs_reg_index = first_dword & 0xF
                if comp_type == CompareRegisterValueType.MemoryOfsReg:
                    comp_str = f"[{mem_type_str(mem_type)}+R{ofs_reg_index}]"
                else: # RegisterOfsReg
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        out.str = f"If R{val_reg_index} {CONDITION_STR.get(cond_type, '?')} {comp_str}"
       
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegister:
        dst_index = (first_dword >> 16) & 0xF
        src_index = (first_dword >> 8) & 0xF
        op_type = SaveRestoreRegisterOpType((first_dword >> 4) & 0xF)
        out.str = f"SaveRestoreRegister dst={dst_index} src={src_index} {OPERAND_STR.get(op_type, '?')}"
       
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegisterMask:
        op_type = SaveRestoreRegisterOpType((first_dword >> 20) & 0xF)
        mask = first_dword & 0xFFFF
        out.str = f"SaveRestoreRegisterMask {OPERAND_STR.get(op_type, '?')} mask=0x{mask:04X}"
       
    elif out.opcode == CheatVmOpcodeType.ReadWriteStaticRegister:
        static_idx = (first_dword >> 4) & 0xFF
        idx = first_dword & 0xF
        out.str = f"ReadWriteStaticRegister static_idx=0x{static_idx:X} idx={idx}"
       
    elif out.opcode == CheatVmOpcodeType.BeginExtendedKeypressConditionalBlock:
        auto_repeat = ((first_dword >> 20) & 0xF) != 0
        key_mask, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8)
        out.str = f"If {'keyheld' if auto_repeat else 'keydown'} 0x{key_mask.value:X}"
       
    elif out.opcode == CheatVmOpcodeType.PauseProcess:
        out.str = "PauseProcess"
       
    elif out.opcode == CheatVmOpcodeType.ResumeProcess:
        out.str = "ResumeProcess"
       
    elif out.opcode == CheatVmOpcodeType.DebugLog:
        out.str = "DebugLog" # Simplified

    else:
        out.str = f"Opcode {out.opcode.name} not implemented in this script."

    out.size = instruction_ptr - index
    return out

def disassemble_cheat(opcodes):
    """Disassembles a list of opcodes for a single cheat."""
    index = 0
    while index < len(opcodes):
        opcode_info = decode_next_opcode(opcodes, index)
        if not opcode_info:
            break
       
        raw_opcodes_list = opcodes[index : index + opcode_info.size]
        raw_opcodes_str = " ".join([f"{opc:08X}" for opc in raw_opcodes_list])

        print(f"{raw_opcodes_str:<40} {opcode_info.str}")
       
        index += opcode_info.size

def disassemble_opcodes_from_file(file_path):
    global TARGET_ARCH # Declare intent to modify global variable
    if TARGET_ARCH is None: # If not set by command line, prompt
        TARGET_ARCH = get_target_arch_from_user()

    try:
        with open(file_path, 'r') as f:
            cheat_opcodes = []
            for line in f:
                stripped_line = line.strip()
                if not stripped_line:
                    continue

                if (stripped_line.startswith('[') and stripped_line.endswith(']')) or \
                   (stripped_line.startswith('{') and stripped_line.endswith('}')):
                    if cheat_opcodes:
                        disassemble_cheat(cheat_opcodes)
                        cheat_opcodes = []
                    print(f"\n{stripped_line}")
                else:
                    parts = stripped_line.split()
                    for part in parts:
                        if part:
                            try:
                                cheat_opcodes.append(int(part, 16))
                            except ValueError:
                                # Ignore non-hex parts, could be comments
                                pass
            # After the loop, process any remaining opcodes
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)

    except FileNotFoundError:
        print(f"Error: The file '{file_path}' was not found.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def disassemble_opcodes_from_string(opcodes_str):
    cheat_opcodes = []
    for line in opcodes_str.splitlines():
        line = line.strip()
        if not line:
            continue
        if line.startswith('[') and line.endswith(']'):
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)
                cheat_opcodes = []
            print(f"\n{line}")
        else:
            parts = line.split()
            for part in parts:
                try:
                    cheat_opcodes.append(int(part, 16))
                except ValueError:
                    pass  # Ignore non-hex parts
    if cheat_opcodes:
        disassemble_cheat(cheat_opcodes)

def get_target_arch_from_user():
    while True:
        choice = input("Enter target architecture (ARM32/ARM64): ").strip().upper()
        if choice in ["ARM32", "ARM64"]:
            return choice
        else:
            print("Invalid choice. Please enter 'ARM32' or 'ARM64'.")

def main():
    """Main function to handle command-line arguments or interactive mode."""
    global TARGET_ARCH

    if not CAPSTONE_AVAILABLE:
        print("Capstone library not found. Please install it with 'pip install capstone'")
        sys.exit(1)

    file_path_arg = None
    for i, arg in enumerate(sys.argv[1:]):
        if arg.lower() == "--arch" and i + 1 < len(sys.argv[1:]):
            arch_arg = sys.argv[i+2].strip().upper()
            if arch_arg in ["ARM32", "ARM64"]:
                TARGET_ARCH = arch_arg
                print(f"Target architecture set to: {TARGET_ARCH} (from command line)")
            else:
                print(f"Warning: Invalid architecture '{arch_arg}' provided via --arch. Will prompt.")
            sys.argv.pop(i+1)
            sys.argv.pop(i+1)
            break

    if len(sys.argv) > 1:
        file_path_arg = sys.argv[1]

    if TARGET_ARCH is None:
        TARGET_ARCH = get_target_arch_from_user()
    print(f"\nDisassembly will target: {TARGET_ARCH}")

    if file_path_arg:
        print(f"--- Disassembling from file: {file_path_arg} ---")
        disassemble_opcodes_from_file(file_path_arg)
        input("\nPress Enter to exit...")
       
    else:
     if len(sys.argv) != 2:
        print("Usage: python ASMdisassemble_cheats.py <path_to_opcode_file>")
        example_file = 'asm.txt'
        print(f"\nNo file provided. Trying with example file: '{example_file}'")
        try:
            with open(example_file, 'r'):
                disassemble_opcodes_from_file(example_file)
        except FileNotFoundError:
            print(f"Example file '{example_file}' not found.")

        print("--- Interactive Mode ---")
        while True:
            print("\nPaste your opcodes (type 'done' on a new line to finish):")
            opcodes_str = ""
            while True:
                try:
                    line = input()
                    if line.strip().lower() == 'done':
                        break
                    opcodes_str += line + "\n"
                except EOFError:
                    break
           
            if opcodes_str.strip():
                disassemble_opcodes_from_string(opcodes_str)
           
            choice = input("\nDisassemble more? (yes/no): ")
            if choice.strip().lower() != 'yes':
                break

if __name__ == "__main__":
    main()
Screenshot 2025-07-22 225506.png

Screenshot 2025-07-22 225522.png

Screenshot 2025-07-22 225549.png
 
The last days/weeks I tried out to achieve some more cheats for Mario Kart but wasn't easy at least for me :)
A few were possible

You can add these cheats to the existing ones you already have or find here in the forum.

It is a little bit dirty how I achieved the cheats to work but hadn't much success in finding the player number in the data structure of the items or vice versa.
And the fact that it is ARM32 didn't make it better.

So Feedback is much appreciated also on the solving side of life ;) or with the naming, because my two code caves I am not pulling in a master code right now but have to be activated that it works ([Activator Set Item Place 1] and [Activator Set Item Place 2])
Dirty because wasn't able to store the base address of the player into the stack or memory (missing ARM32 knowledge and know how to deal with relative memory addresses) so I did another trick.
With the item buttons combination I save in the next free item slot for a certain player a custom number (50 for 3 Red Shells, 51 for Lightning etc.) and when it comes to storing the item after touching a question mark/item box - this custom number leads to the individual item...
That is the magic... This in done in the first code cave and the second code cave is to avoid a irrelevant store in the item slot in between my custom number is set and the real item is placed into the item slot.
I am not sure if I can also save these global constants for my cheats to work (e.g. 50 for 3 Red Shells) elsewhere. Because now the code caves and the item combination have to be in sync with each other.

So enjoy :)

[Mario Kart 8 Deluxe 3.0.3 TID: 0100152000022000 BID: 6A85262F21B90364]

[Item]
20000000

[Activator Set Item Place 1]
04000000 000482E0 E5840058
04000000 000482E0 EA2F531E
04000000 00C1CF60 E52D1004
04000000 00C1CF64 E5941058
04000000 00C1CF68 E3510050
04000000 00C1CF6C 1A000000
04000000 00C1CF70 E3A00013
04000000 00C1CF74 E3510051
04000000 00C1CF78 1A000000
04000000 00C1CF7C E3A0000A
04000000 00C1CF80 E3510052
04000000 00C1CF84 1A000000
04000000 00C1CF88 E3A0000B
04000000 00C1CF8C E3510053
04000000 00C1CF90 1A000000
04000000 00C1CF94 E3A00009
04000000 00C1CF98 E5840058
04000000 00C1CF9C E49D1004
04000000 00C1CFA0 EAD0ACCF

[Activator Set Item Place 1 off]
04000000 000482E0 E5840058

[Activator Set Item Place 2]
04000000 00047F7C E5801058
04000000 00047F7C EA2F540B
04000000 00C1CFB0 E52D2004
04000000 00C1CFB4 E5902058
04000000 00C1CFB8 E3520032
04000000 00C1CFBC 3A000000
04000000 00C1CFC0 EA000000
04000000 00C1CFC4 E5801058
04000000 00C1CFC8 E49D2004
04000000 00C1CFCC EAD0ABEB

[Activator Set Item Place 2 off]
04000000 00047F7C E5801058

[P1 Set Next Item 3 Red Shells L+A+DPad Up]
80002041
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000000
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000050
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P1 Set Next Item Lightning L+A+DPad Right]
80004041
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000000
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000051
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P1 Set Next Item Golden Mushroom L+A+DPad Down]
80008041
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000000
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000052
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P1 Set Next Item Bullet Bill L+A+DPad Left]
80001041
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000000
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000053
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P2 Set Next Item 3 Red Shells L+Y+DPad Up]
80002048
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000004
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000050
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P2 Set Next Item Lightning L+Y+DPad Right]
80004048
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000004
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000051
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P2 Set Next Item Golden Mushroom L+Y+DPad Down]
80008048
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000004
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000052
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[P2 Set Next Item Bullet Bill L+Y+DPad Left]
80001048
540F0000 00F4F9DC
540F1000 00000014
540F1000 00000064
540F1000 0000007C
540F1000 00000004
30000000 00000002
9891F000
54011000 00000030
74010000 00000058
98921000
54011000 00000000
C0411400 00000030
64020000 00000000 00000053
40000000 00000000 00000001
20010000
780F0000 00000004
31000000
20010000

[Item Instant Without wait time]
04000000 00047C00 E3A000C8

[Item Instant off]
04000000 00047C00 E2800001

[Item end]
20000001

[Lakitu Stop Pickup Wrong Direction]
04000000 0090C79C E320F000

[Lakitu Stop Pickup Wrong Direction off]
04000000 0090C79C E1C406B4
Hi bro, I tried to add them on MK8 3.0.3 but It doesn't detect them for me on mod folder and atmosphere too :(
 
Hi bro, I tried to add them on MK8 3.0.3 but It doesn't detect them for me on mod folder and atmosphere too :(
Your BID of the game is matching? Sounds like a cheat file or recognition problem. Because of course in the mod folder it is not working because it is a cheat but in atmosphere under contents and a folder with the TID of the game and a cheat text file with the correct BID it should work
 
Arcade Archives City Bomber 1.0.0
TID: 0100BAE0209E8000
BID: F57B6A0A0B490950

[Breeze beta98b Arcade Archives City Bomber 1.0.0 TID: 0100BAE0209E8000 BID: F57B6A0A0B490950]

[Inf.Credits]
580F0000 006B71F8
580F1000 00000188
780F0000 0000003D
610F0000 00000000 00000099

[Inf.Time]
80000100
580F0000 006B71F8
580F1000 00000188
780F0000 0000049A
620F0000 00000000 00930999
20000000

Original Code by ネオ•グランゾン
 

Attachments

Last edited by herowang,
so full credit to Tom on his script https://github.com/tomvita/Breeze-Beta/blob/master/disassemble_cheats.py

I am just waiting on him to approve more of my bug fix pull request but you can grab from his link.

I do also have one with the pending bug fixes here

This fixes 8 byte write instructions to actually convert rather than leave empty. (you can copy this code then paste into a notepad and save as a .py file to make the script

Python:
import sys
from enum import Enum

try:
    from capstone import Cs, CS_ARCH_ARM64, CS_MODE_ARM
    CAPSTONE_AVAILABLE = True
except ImportError:
    CAPSTONE_AVAILABLE = False

# Based on source/opcode.hpp

class CheatVmOpcodeType(Enum):
    StoreStatic = 0
    BeginConditionalBlock = 1
    EndConditionalBlock = 2
    ControlLoop = 3
    LoadRegisterStatic = 4
    LoadRegisterMemory = 5
    StoreStaticToAddress = 6
    PerformArithmeticStatic = 7
    BeginKeypressConditionalBlock = 8
    PerformArithmeticRegister = 9
    StoreRegisterToAddress = 10
    Reserved11 = 11
    ExtendedWidth = 12
    BeginRegisterConditionalBlock = 0xC0
    SaveRestoreRegister = 0xC1
    SaveRestoreRegisterMask = 0xC2
    ReadWriteStaticRegister = 0xC3
    BeginExtendedKeypressConditionalBlock = 0xC4
    DoubleExtendedWidth = 0xF0
    PauseProcess = 0xFF0
    ResumeProcess = 0xFF1
    DebugLog = 0xFFF

class MemoryAccessType(Enum):
    MainNso = 0
    Heap = 1
    Alias = 2
    Aslr = 3
    Blank = 4

class ConditionalComparisonType(Enum):
    GT = 1
    GE = 2
    LT = 3
    LE = 4
    EQ = 5
    NE = 6

class RegisterArithmeticType(Enum):
    Addition = 0
    Subtraction = 1
    Multiplication = 2
    LeftShift = 3
    RightShift = 4
    LogicalAnd = 5
    LogicalOr = 6
    LogicalNot = 7
    LogicalXor = 8
    None_ = 9
    FloatAddition = 10
    FloatMultiplication = 11
    DoubleAddition = 12
    DoubleMultiplication = 13

class StoreRegisterOffsetType(Enum):
    None_ = 0
    Reg = 1
    Imm = 2
    MemReg = 3
    MemImm = 4
    MemImmReg = 5

class CompareRegisterValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    StaticValue = 4
    OtherRegister = 5
    OffsetValue = 6
  
class SaveRestoreRegisterOpType(Enum):
    Restore = 0
    Save = 1
    ClearSaved = 2
    ClearRegs = 3

class DebugLogValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    RegisterValue = 4

CONDITION_STR = {
    ConditionalComparisonType.GT: ">",
    ConditionalComparisonType.GE: ">=",
    ConditionalComparisonType.LT: "<",
    ConditionalComparisonType.LE: "<=",
    ConditionalComparisonType.EQ: "==",
    ConditionalComparisonType.NE: "!=",
}

MATH_STR = {
    RegisterArithmeticType.Addition: "+",
    RegisterArithmeticType.Subtraction: "-",
    RegisterArithmeticType.Multiplication: "*",
    RegisterArithmeticType.LeftShift: "<<",
    RegisterArithmeticType.RightShift: ">>",
    RegisterArithmeticType.LogicalAnd: "&",
    RegisterArithmeticType.LogicalOr: "|",
    RegisterArithmeticType.LogicalNot: "!",
    RegisterArithmeticType.LogicalXor: "^",
    RegisterArithmeticType.None_: "",
    RegisterArithmeticType.FloatAddition: "+f",
    RegisterArithmeticType.FloatMultiplication: "*f",
    RegisterArithmeticType.DoubleAddition: "+d",
    RegisterArithmeticType.DoubleMultiplication: "*d",
}

OPERAND_STR = {
    SaveRestoreRegisterOpType.Restore: "Restore",
    SaveRestoreRegisterOpType.Save: "Save",
    SaveRestoreRegisterOpType.ClearSaved: "ClearSaved",
    SaveRestoreRegisterOpType.ClearRegs: "ClearRegs",
}


class VmInt:
    def __init__(self, value=0):
        self.value = value

class CheatVmOpcode:
    def __init__(self):
        self.opcode = None
        self.size = 0
        self.str = ""

def get_next_dword(opcodes, instruction_ptr):
    if instruction_ptr >= len(opcodes):
        return None, instruction_ptr + 1
    return opcodes[instruction_ptr], instruction_ptr + 1

def get_next_vm_int(opcodes, instruction_ptr, bit_width):
    val = VmInt()
  
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None, instruction_ptr

    if bit_width == 1:
        val.value = first_dword & 0xFF
    elif bit_width == 2:
        val.value = first_dword & 0xFFFF
    elif bit_width == 4:
        val.value = first_dword
    elif bit_width == 8:
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        if second_dword is None:
            return None, instruction_ptr
        val.value = (first_dword << 32) | second_dword
    else:
        # Invalid bit_width, but I'll assign the dword to avoid crashing.
        val.value = first_dword
      
    return val, instruction_ptr


def mem_type_str(mem_type):
    if mem_type == MemoryAccessType.MainNso: return "Main"
    if mem_type == MemoryAccessType.Heap: return "Heap"
    if mem_type == MemoryAccessType.Alias: return "Alias"
    if mem_type == MemoryAccessType.Aslr: return "Aslr"
    return ""

def arm64_disassemble(value, bit_width, address):
    if not CAPSTONE_AVAILABLE:
        return ""
  
    md = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
    code = value.to_bytes(bit_width, byteorder='little')
  
    disassembled = []
    try:
        for i in md.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        return "; ".join(disassembled).strip()
    except Exception:
        return "" # Return empty string if Capstone fails


def decode_next_opcode(opcodes, index):
    instruction_ptr = index
  
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None

    out = CheatVmOpcode()
  
    opcode_val = (first_dword >> 28) & 0xF
    if opcode_val >= CheatVmOpcodeType.ExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 24) & 0xF)
    if opcode_val >= CheatVmOpcodeType.DoubleExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 20) & 0xF)

    try:
        out.opcode = CheatVmOpcodeType(opcode_val)
    except ValueError:
        out.str = f"Unknown opcode: {hex(opcode_val)}"
        out.size = 1
        return out

    if out.opcode == CheatVmOpcodeType.StoreStatic:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        offset_register = (first_dword >> 16) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFF) << 32) | second_dword
      
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
      
        out.str = f"[{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] = 0x{value.value:X}"
      
        value_for_disasm = value.value
        if bit_width == 8:
            # The 64-bit value is read as (high_dword << 32 | low_dword).
            # For little-endian disassembly, the byte stream needs to be
            # ordered by the dwords as they appear in the file (high then low).
            # value.to_bytes(..., 'little') would produce bytes(low) then bytes(high).
            # To fix this, swap the dwords before converting to bytes.
            high_dw = value.value >> 32
            low_dw = value.value & 0xFFFFFFFF
            value_for_disasm = (low_dw << 32) | high_dw

        if CAPSTONE_AVAILABLE and (bit_width == 4 or bit_width == 8):
            asm = arm64_disassemble(value_for_disasm, bit_width, rel_address)
            if asm:
                out.str += f"  {asm}"
        else:
            out.str += " (Disassembly skipped - Capstone not available or invalid bit_width)"
  
    elif out.opcode == CheatVmOpcodeType.BeginConditionalBlock:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        include_ofs_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_reg_index = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFF) << 32) | second_dword
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
        ofs_reg_str = f"R{ofs_reg_index}+" if include_ofs_reg else ""
        out.str = f"If [{mem_type_str(mem_type)}+{ofs_reg_str}0x{rel_address:010X}] {CONDITION_STR.get(cond_type, '?')} 0x{value.value:X}"

    elif out.opcode == CheatVmOpcodeType.EndConditionalBlock:
        end_type = (first_dword >> 24) & 0xF
        out.str = "Else" if end_type == 1 else "Endif"

    elif out.opcode == CheatVmOpcodeType.ControlLoop:
        start_loop = ((first_dword >> 24) & 0xF) == 0
        reg_index = (first_dword >> 16) & 0xF
        if start_loop:
            num_iters, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
            out.str = f"Loop Start R{reg_index} = {num_iters}"
        else:
            out.str = "Loop stop"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterStatic:
        reg_index = (first_dword >> 16) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit value
        out.str = f"R{reg_index} = 0x{value.value:016X}"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterMemory:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        reg_index = (first_dword >> 16) & 0xF
        load_from_reg = (first_dword >> 12) & 0xF
        offset_register = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFF) << 32) | second_dword
        if load_from_reg == 3:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] W={bit_width}"
        elif load_from_reg:
            src_reg = reg_index if load_from_reg == 1 else offset_register
            out.str = f"R{reg_index} = [R{src_reg}+0x{rel_address:010X}] W={bit_width}"
        else:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+0x{rel_address:010X}] W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.StoreStaticToAddress:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        add_offset_reg = ((first_dword >> 8) & 0xF) != 0
        offset_reg_index = (first_dword >> 4) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit
        if add_offset_reg:
            out.str = f"[R{reg_index}+R{offset_reg_index}] = 0x{value.value:016X} W={bit_width}"
        else:
            out.str = f"[R{reg_index}] = 0x{value.value:016X} W={bit_width}"
        if increment_reg:
            out.str += f" R{reg_index} += {bit_width}"

    elif out.opcode == CheatVmOpcodeType.PerformArithmeticStatic:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 12) & 0xF)
        value, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        out.str = f"R{reg_index} = R{reg_index} {MATH_STR.get(math_type, '?')} 0x{value:X} W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.BeginKeypressConditionalBlock:
        key_mask = first_dword & 0x0FFFFFFF
        out.str = f"If keyheld 0x{key_mask:X}"
      
    elif out.opcode == CheatVmOpcodeType.PerformArithmeticRegister:
        bit_width = (first_dword >> 24) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 20) & 0xF)
        dst_reg_index = (first_dword >> 16) & 0xF
        src_reg_1_index = (first_dword >> 12) & 0xF
        has_immediate = ((first_dword >> 8) & 0xF) != 0
        if has_immediate:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} 0x{value.value:X} W={bit_width}"
        else:
            src_reg_2_index = (first_dword >> 4) & 0xF
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} R{src_reg_2_index} W={bit_width}"
  
    elif out.opcode == CheatVmOpcodeType.StoreRegisterToAddress:
        bit_width = (first_dword >> 24) & 0xF
        str_reg_index = (first_dword >> 20) & 0xF
        addr_reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_type = StoreRegisterOffsetType((first_dword >> 8) & 0xF)
        ofs_reg_index = (first_dword >> 4) & 0xF
      
        addr_str = ""
        if ofs_type == StoreRegisterOffsetType.None_:
            addr_str = f"[R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Reg:
            addr_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Imm:
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.MemImm:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemImmReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}+0x{rel_address.value:X}]"
      
        out.str = f"{addr_str} = R{str_reg_index} W={bit_width}"
        if increment_reg:
            out.str += f" R{addr_reg_index} += {bit_width}"
          
    elif out.opcode == CheatVmOpcodeType.BeginRegisterConditionalBlock:
        bit_width = (first_dword >> 20) & 0xF
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        val_reg_index = (first_dword >> 12) & 0xF
        comp_type = CompareRegisterValueType((first_dword >> 8) & 0xF)
      
        comp_str = ""
        if comp_type == CompareRegisterValueType.StaticValue:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            comp_str = f"0x{value.value:X}"
        elif comp_type == CompareRegisterValueType.OtherRegister:
            other_reg_index = (first_dword >> 4) & 0xF
            comp_str = f"R{other_reg_index}"
        else: # Memory access
            mem_type = MemoryAccessType((first_dword >> 4) & 0xF)
            if comp_type in [CompareRegisterValueType.MemoryRelAddr, CompareRegisterValueType.RegisterRelAddr]:
                rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4)
                if comp_type == CompareRegisterValueType.MemoryRelAddr:
                    comp_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
                else: # RegisterRelAddr
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
            else: # MemoryOfsReg, RegisterOfsReg
                ofs_reg_index = first_dword & 0xF
                if comp_type == CompareRegisterValueType.MemoryOfsReg:
                    comp_str = f"[{mem_type_str(mem_type)}+R{ofs_reg_index}]"
                else: # RegisterOfsReg
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        out.str = f"If R{val_reg_index} {CONDITION_STR.get(cond_type, '?')} {comp_str}"
      
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegister:
        dst_index = (first_dword >> 16) & 0xF
        src_index = (first_dword >> 8) & 0xF
        op_type = SaveRestoreRegisterOpType((first_dword >> 4) & 0xF)
        out.str = f"SaveRestoreRegister dst={dst_index} src={src_index} {OPERAND_STR.get(op_type, '?')}"
      
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegisterMask:
        op_type = SaveRestoreRegisterOpType((first_dword >> 20) & 0xF)
        mask = first_dword & 0xFFFF
        out.str = f"SaveRestoreRegisterMask {OPERAND_STR.get(op_type, '?')} mask=0x{mask:04X}"
      
    elif out.opcode == CheatVmOpcodeType.ReadWriteStaticRegister:
        static_idx = (first_dword >> 4) & 0xFF
        idx = first_dword & 0xF
        out.str = f"ReadWriteStaticRegister static_idx=0x{static_idx:X} idx={idx}"
      
    elif out.opcode == CheatVmOpcodeType.BeginExtendedKeypressConditionalBlock:
        auto_repeat = ((first_dword >> 20) & 0xF) != 0
        key_mask, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8)
        out.str = f"If {'keyheld' if auto_repeat else 'keydown'} 0x{key_mask.value:X}"
      
    elif out.opcode == CheatVmOpcodeType.PauseProcess:
        out.str = "PauseProcess"
      
    elif out.opcode == CheatVmOpcodeType.ResumeProcess:
        out.str = "ResumeProcess"
      
    elif out.opcode == CheatVmOpcodeType.DebugLog:
        out.str = "DebugLog" # Simplified

    else:
        out.str = f"Opcode {out.opcode.name} not implemented in this script."

    out.size = instruction_ptr - index
    return out

def disassemble_cheat(opcodes):
    """Disassembles a list of opcodes for a single cheat."""
    index = 0
    while index < len(opcodes):
        opcode_info = decode_next_opcode(opcodes, index)
        if not opcode_info:
            break
      
        raw_opcodes_list = opcodes[index : index + opcode_info.size]
        raw_opcodes_str = " ".join([f"{opc:08X}" for opc in raw_opcodes_list])

        print(f"{raw_opcodes_str:<40} {opcode_info.str}")
      
        index += opcode_info.size

def disassemble_opcodes_from_file(file_path):
    try:
        with open(file_path, 'r') as f:
            cheat_opcodes = []
            for line in f:
                stripped_line = line.strip()
                if not stripped_line:
                    continue

                if (stripped_line.startswith('[') and stripped_line.endswith(']')) or \
                   (stripped_line.startswith('{') and stripped_line.endswith('}')):
                    if cheat_opcodes:
                        disassemble_cheat(cheat_opcodes)
                        cheat_opcodes = []
                    print(f"\n{stripped_line}")
                else:
                    parts = stripped_line.split()
                    for part in parts:
                        if part:
                            try:
                                cheat_opcodes.append(int(part, 16))
                            except ValueError:
                                # Ignore non-hex parts, could be comments
                                pass
            # After the loop, process any remaining opcodes
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)

    except FileNotFoundError:
        print(f"Error: The file '{file_path}' was not found.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def disassemble_opcodes_from_string(opcodes_str):
    cheat_opcodes = []
    for line in opcodes_str.splitlines():
        line = line.strip()
        if not line:
            continue
        if line.startswith('[') and line.endswith(']'):
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)
                cheat_opcodes = []
            print(f"\n{line}")
        else:
            parts = line.split()
            for part in parts:
                try:
                    cheat_opcodes.append(int(part, 16))
                except ValueError:
                    pass  # Ignore non-hex parts
    if cheat_opcodes:
        disassemble_cheat(cheat_opcodes)

def main():
    """Main function to handle command-line arguments or interactive mode."""
    if not CAPSTONE_AVAILABLE:
        print("Capstone library not found. Please install it with 'pip install capstone'")
        sys.exit(1)

    # If a command-line argument is provided, treat it as a file path
    if len(sys.argv) > 1:
        file_path = sys.argv[1]
        print(f"--- Disassembling from file: {file_path} ---")
        disassemble_opcodes_from_file(file_path)
        input("\nPress Enter to exit...")
    else:
  
     if len(sys.argv) != 2:
        print("Usage: python disassemble_cheats.py <path_to_opcode_file>")
        example_file = 'asm.txt'
        print(f"\nNo file provided. Trying with example file: '{example_file}'")
        try:
            with open(example_file, 'r'):
                disassemble_opcodes_from_file(example_file)
        except FileNotFoundError:
            print(f"Example file '{example_file}' not found.")
          
        print("--- Interactive Mode ---")
        while True:
            print("\nPaste your opcodes (type 'done' on a new line to finish):")
            opcodes_str = ""
            while True:
                try:
                    line = input()
                    if line.strip().lower() == 'done':
                        break
                    opcodes_str += line + "\n"
                except EOFError:
                    break
          
            if opcodes_str.strip():
                disassemble_opcodes_from_string(opcodes_str)
          
            choice = input("\nDisassemble more? (yes/no): ")
            if choice.strip().lower() != 'yes':
                break
              


if __name__ == "__main__":
    main()


Then this version here i did up is just a test im doing up for him.. this has arm32 support for games that use that like Ty the tasmanian tiger HD, Mario kart 8 D pre 3.0.4, etc. so if you know the codes are arm32 instructions choose that as your architecture...


Python:
import sys
from enum import Enum

try:
    from capstone import Cs, CS_ARCH_ARM64, CS_ARCH_ARM, CS_MODE_ARM, CS_MODE_THUMB
    CAPSTONE_AVAILABLE = True
except ImportError:
    CAPSTONE_AVAILABLE = False

# Global variable to store the target architecture chosen by the user
TARGET_ARCH = None

# Based on source/opcode.hpp

class CheatVmOpcodeType(Enum):
    StoreStatic = 0
    BeginConditionalBlock = 1
    EndConditionalBlock = 2
    ControlLoop = 3
    LoadRegisterStatic = 4
    LoadRegisterMemory = 5
    StoreStaticToAddress = 6
    PerformArithmeticStatic = 7
    BeginKeypressConditionalBlock = 8
    PerformArithmeticRegister = 9
    StoreRegisterToAddress = 10
    Reserved11 = 11
    ExtendedWidth = 12
    BeginRegisterConditionalBlock = 0xC0
    SaveRestoreRegister = 0xC1
    SaveRestoreRegisterMask = 0xC2
    ReadWriteStaticRegister = 0xC3
    BeginExtendedKeypressConditionalBlock = 0xC4
    DoubleExtendedWidth = 0xF0
    PauseProcess = 0xFF0
    ResumeProcess = 0xFF1
    DebugLog = 0xFFF

class MemoryAccessType(Enum):
    MainNso = 0
    Heap = 1
    Alias = 2
    Aslr = 3
    Blank = 4

class ConditionalComparisonType(Enum):
    GT = 1
    GE = 2
    LT = 3
    LE = 4
    EQ = 5
    NE = 6

class RegisterArithmeticType(Enum):
    Addition = 0
    Subtraction = 1
    Multiplication = 2
    LeftShift = 3
    RightShift = 4
    LogicalAnd = 5
    LogicalOr = 6
    LogicalNot = 7
    LogicalXor = 8
    None_ = 9
    FloatAddition = 10
    FloatMultiplication = 11
    DoubleAddition = 12
    DoubleMultiplication = 13

class StoreRegisterOffsetType(Enum):
    None_ = 0
    Reg = 1
    Imm = 2
    MemReg = 3
    MemImm = 4
    MemImmReg = 5

class CompareRegisterValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    StaticValue = 4
    OtherRegister = 5
    OffsetValue = 6
  
class SaveRestoreRegisterOpType(Enum):
    Restore = 0
    Save = 1
    ClearSaved = 2
    ClearRegs = 3

class DebugLogValueType(Enum):
    MemoryRelAddr = 0
    MemoryOfsReg = 1
    RegisterRelAddr = 2
    RegisterOfsReg = 3
    RegisterValue = 4

CONDITION_STR = {
    ConditionalComparisonType.GT: ">",
    ConditionalComparisonType.GE: ">=",
    ConditionalComparisonType.LT: "<",
    ConditionalComparisonType.LE: "<=",
    ConditionalComparisonType.EQ: "==",
    ConditionalComparisonType.NE: "!=",
}

MATH_STR = {
    RegisterArithmeticType.Addition: "+",
    RegisterArithmeticType.Subtraction: "-",
    RegisterArithmeticType.Multiplication: "*",
    RegisterArithmeticType.LeftShift: "<<",
    RegisterArithmeticType.RightShift: ">>",
    RegisterArithmeticType.LogicalAnd: "&",
    RegisterArithmeticType.LogicalOr: "|",
    RegisterArithmeticType.LogicalNot: "!",
    RegisterArithmeticType.LogicalXor: "^",
    RegisterArithmeticType.None_: "",
    RegisterArithmeticType.FloatAddition: "+f",
    RegisterArithmeticType.FloatMultiplication: "*f",
    RegisterArithmeticType.DoubleAddition: "+d",
    RegisterArithmeticType.DoubleMultiplication: "*d",
}

OPERAND_STR = {
    SaveRestoreRegisterOpType.Restore: "Restore",
    SaveRestoreRegisterOpType.Save: "Save",
    SaveRestoreRegisterOpType.ClearSaved: "ClearSaved",
    SaveRestoreRegisterOpType.ClearRegs: "ClearRegs",
}


class VmInt:
    def __init__(self, value=0):
        self.value = value

class CheatVmOpcode:
    def __init__(self):
        self.opcode = None
        self.size = 0
        self.str = ""

def get_next_dword(opcodes, instruction_ptr):
    if instruction_ptr >= len(opcodes):
        return None, instruction_ptr + 1
    return opcodes[instruction_ptr], instruction_ptr + 1

def get_next_vm_int(opcodes, instruction_ptr, bit_width):
    val = VmInt()
  
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None, instruction_ptr

    if bit_width == 1:
        val.value = first_dword & 0xFF
    elif bit_width == 2:
        val.value = first_dword & 0xFFFF
    elif bit_width == 4:
        val.value = first_dword
    elif bit_width == 8:
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        if second_dword is None:
            return None, instruction_ptr
        val.value = (first_dword << 32) | second_dword
    else:
        # Invalid bit_width, but we'll assign the dword to avoid crashing.
        val.value = first_dword
      
    return val, instruction_ptr


def mem_type_str(mem_type):
    if mem_type == MemoryAccessType.MainNso: return "Main"
    if mem_type == MemoryAccessType.Heap: return "Heap"
    if mem_type == MemoryAccessType.Alias: return "Alias"
    if mem_type == MemoryAccessType.Aslr: return "Aslr"
    return ""

def arm64_disassemble(value, address):
    """
    Disassembles a 4-byte value as an ARM64 instruction.
    ARM64 instructions are always 4 bytes.
    """
    if not CAPSTONE_AVAILABLE:
        return ""
  
    md = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
    # Ensure we always convert to 4 bytes for ARM64 instruction disassembly
    code = (value & 0xFFFFFFFF).to_bytes(4, byteorder='little')
  
    disassembled = []
    try:
        for i in md.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        return "; ".join(disassembled).strip()
    except Exception:
        return "" # Return empty string if Capstone fails

def arm32_disassemble(value, address):
    """
    Disassembles a 4-byte value as an ARM32 instruction (trying ARM then Thumb).
    ARM32/Thumb instructions are 2 or 4 bytes. I provide 4 bytes and let Capstone handle it.
    """
    if not CAPSTONE_AVAILABLE:
        return ""
  
    code = value.to_bytes(4, byteorder='little') # ARM32 instructions are 4 bytes (or 2 for Thumb, but provide 4)
  
    # Try ARM mode first
    md_arm = Cs(CS_ARCH_ARM, CS_MODE_ARM)
    disassembled = []
    try:
        for i in md_arm.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        if disassembled:
            return "; ".join(disassembled).strip()
    except Exception:
        pass # Fall through to Thumb mode if ARM disassembly fails or produces nothing

    # If ARM mode didn't work or produced no output, try Thumb mode
    md_thumb = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
    disassembled = []
    try:
        for i in md_thumb.disasm(code, address):
            disassembled.append(f"{i.mnemonic} {i.op_str}")
        if disassembled:
            return "; ".join(disassembled).strip()
    except Exception:
        pass

    return "" # Return empty string if neither ARM nor Thumb can disassemble


def decode_next_opcode(opcodes, index):
    instruction_ptr = index
  
    first_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
    if first_dword is None:
        return None

    out = CheatVmOpcode()
  
    opcode_val = (first_dword >> 28) & 0xF
    if opcode_val >= CheatVmOpcodeType.ExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 24) & 0xF)
    if opcode_val >= CheatVmOpcodeType.DoubleExtendedWidth.value:
        opcode_val = (opcode_val << 4) | ((first_dword >> 20) & 0xF)

    try:
        out.opcode = CheatVmOpcodeType(opcode_val)
    except ValueError:
        out.str = f"Unknown opcode: {hex(opcode_val)}"
        out.size = 1
        return out

    if out.opcode == CheatVmOpcodeType.StoreStatic:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        offset_register = (first_dword >> 16) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        # Assuming rel_address high 24 bits are from first_dword & 0xFFFFFF
        # and low 32 bits from second_dword.
        rel_address = ((first_dword & 0xFFFFFF) << 32) | second_dword
      
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
      
        out.str = f"[{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] = 0x{value.value:X}"
      
        # Determine disassembly based on bit_width and global TARGET_ARCH
        if CAPSTONE_AVAILABLE:
            if bit_width == 8: # 8-byte value: Disassemble both halves based on TARGET_ARCH
                high_32_bits = (value.value >> 32) & 0xFFFFFFFF
                low_32_bits = value.value & 0xFFFFFFFF

                combined_asm = []
                if TARGET_ARCH == "ARM64":
                    asm_low = arm64_disassemble(low_32_bits, rel_address)
                    asm_high = arm64_disassemble(high_32_bits, rel_address + 4)
                    arch_label = "ARM64"
                elif TARGET_ARCH == "ARM32":
                    asm_low = arm32_disassemble(low_32_bits, rel_address)
                    asm_high = arm32_disassemble(high_32_bits, rel_address + 4)
                    arch_label = "ARM32"
                else: # Should not happen if TARGET_ARCH is set correctly
                    asm_low = ""
                    asm_high = ""
                    arch_label = "UNKNOWN ARCH"

                if asm_low:
                    combined_asm.append(f"[{hex(rel_address)}] {asm_low}")
                if asm_high:
                    combined_asm.append(f"[{hex(rel_address + 4)}] {asm_high}")
              
                if combined_asm:
                    out.str += f"  ({arch_label}: {'; '.join(combined_asm)})"
                else:
                    out.str += f"  ({arch_label}: No disassembly)"

            elif bit_width == 4: # 4-byte value: Use TARGET_ARCH to decide
                if TARGET_ARCH == "ARM64":
                    asm = arm64_disassemble(value.value, rel_address)
                    if asm:
                        out.str += f"  (ARM64: {asm})"
                elif TARGET_ARCH == "ARM32":
                    asm = arm32_disassemble(value.value, rel_address)
                    if asm:
                        out.str += f"  (ARM32: {asm})"
                else: # Should not happen if TARGET_ARCH is set correctly
                    out.str += " (Disassembly type not determined)"
        else:
            out.str += " (Disassembly skipped - Capstone not available)"
  
    elif out.opcode == CheatVmOpcodeType.BeginConditionalBlock:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        include_ofs_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_reg_index = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFFFFFF) << 32) | second_dword # Adjusted to mask 24 bits
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
        ofs_reg_str = f"R{ofs_reg_index}+" if include_ofs_reg else ""
        out.str = f"If [{mem_type_str(mem_type)}+{ofs_reg_str}0x{rel_address:010X}] {CONDITION_STR.get(cond_type, '?')} 0x{value.value:X}"

    elif out.opcode == CheatVmOpcodeType.EndConditionalBlock:
        end_type = (first_dword >> 24) & 0xF
        out.str = "Else" if end_type == 1 else "Endif"

    elif out.opcode == CheatVmOpcodeType.ControlLoop:
        start_loop = ((first_dword >> 24) & 0xF) == 0
        reg_index = (first_dword >> 16) & 0xF
        if start_loop:
            num_iters, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
            out.str = f"Loop Start R{reg_index} = {num_iters}"
        else:
            out.str = "Loop stop"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterStatic:
        reg_index = (first_dword >> 16) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit value
        out.str = f"R{reg_index} = 0x{value.value:016X}"

    elif out.opcode == CheatVmOpcodeType.LoadRegisterMemory:
        bit_width = (first_dword >> 24) & 0xF
        mem_type = MemoryAccessType((first_dword >> 20) & 0xF)
        reg_index = (first_dword >> 16) & 0xF
        load_from_reg = (first_dword >> 12) & 0xF
        offset_register = (first_dword >> 8) & 0xF
        second_dword, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        rel_address = ((first_dword & 0xFFFFFF) << 32) | second_dword # Adjusted to mask 24 bits
        if load_from_reg == 3:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+R{offset_register}+0x{rel_address:010X}] W={bit_width}"
        elif load_from_reg:
            src_reg = reg_index if load_from_reg == 1 else offset_register
            out.str = f"R{reg_index} = [R{src_reg}+0x{rel_address:010X}] W={bit_width}"
        else:
            out.str = f"R{reg_index} = [{mem_type_str(mem_type)}+0x{rel_address:010X}] W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.StoreStaticToAddress:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        add_offset_reg = ((first_dword >> 8) & 0xF) != 0
        offset_reg_index = (first_dword >> 4) & 0xF
        value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8) # 64-bit
        if add_offset_reg:
            out.str = f"[R{reg_index}+R{offset_reg_index}] = 0x{value.value:016X} W={bit_width}"
        else:
            out.str = f"[R{reg_index}] = 0x{value.value:016X} W={bit_width}"
        if increment_reg:
            out.str += f" R{reg_index} += {bit_width}"

    elif out.opcode == CheatVmOpcodeType.PerformArithmeticStatic:
        bit_width = (first_dword >> 24) & 0xF
        reg_index = (first_dword >> 16) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 12) & 0xF)
        value, instruction_ptr = get_next_dword(opcodes, instruction_ptr)
        out.str = f"R{reg_index} = R{reg_index} {MATH_STR.get(math_type, '?')} 0x{value:X} W={bit_width}"

    elif out.opcode == CheatVmOpcodeType.BeginKeypressConditionalBlock:
        key_mask = first_dword & 0x0FFFFFFF
        out.str = f"If keyheld 0x{key_mask:X}"
      
    elif out.opcode == CheatVmOpcodeType.PerformArithmeticRegister:
        bit_width = (first_dword >> 24) & 0xF
        math_type = RegisterArithmeticType((first_dword >> 20) & 0xF)
        dst_reg_index = (first_dword >> 16) & 0xF
        src_reg_1_index = (first_dword >> 12) & 0xF
        has_immediate = ((first_dword >> 8) & 0xF) != 0
        if has_immediate:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} 0x{value.value:X} W={bit_width}"
        else:
            src_reg_2_index = (first_dword >> 4) & 0xF
            out.str = f"R{dst_reg_index} = R{src_reg_1_index} {MATH_STR.get(math_type, '?')} R{src_reg_2_index} W={bit_width}"
  
    elif out.opcode == CheatVmOpcodeType.StoreRegisterToAddress:
        bit_width = (first_dword >> 24) & 0xF
        str_reg_index = (first_dword >> 20) & 0xF
        addr_reg_index = (first_dword >> 16) & 0xF
        increment_reg = ((first_dword >> 12) & 0xF) != 0
        ofs_type = StoreRegisterOffsetType((first_dword >> 8) & 0xF)
        ofs_reg_index = (first_dword >> 4) & 0xF
      
        addr_str = ""
        if ofs_type == StoreRegisterOffsetType.None_:
            addr_str = f"[R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Reg:
            addr_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.Imm:
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}]"
        elif ofs_type == StoreRegisterOffsetType.MemImm:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
        elif ofs_type == StoreRegisterOffsetType.MemImmReg:
            mem_type = MemoryAccessType(ofs_reg_index)
            rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4) # 32-bit
            addr_str = f"[{mem_type_str(mem_type)}+R{addr_reg_index}+0x{rel_address.value:X}]"
      
        out.str = f"{addr_str} = R{str_reg_index} W={bit_width}"
        if increment_reg:
            out.str += f" R{addr_reg_index} += {bit_width}"
          
    elif out.opcode == CheatVmOpcodeType.BeginRegisterConditionalBlock:
        bit_width = (first_dword >> 20) & 0xF
        cond_type = ConditionalComparisonType((first_dword >> 16) & 0xF)
        val_reg_index = (first_dword >> 12) & 0xF
        comp_type = CompareRegisterValueType((first_dword >> 8) & 0xF)
      
        comp_str = ""
        if comp_type == CompareRegisterValueType.StaticValue:
            value, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, bit_width)
            comp_str = f"0x{value.value:X}"
        elif comp_type == CompareRegisterValueType.OtherRegister:
            other_reg_index = (first_dword >> 4) & 0xF
            comp_str = f"R{other_reg_index}"
        else: # Memory access
            mem_type = MemoryAccessType((first_dword >> 4) & 0xF)
            if comp_type in [CompareRegisterValueType.MemoryRelAddr, CompareRegisterValueType.RegisterRelAddr]:
                rel_address, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 4)
                if comp_type == CompareRegisterValueType.MemoryRelAddr:
                    comp_str = f"[{mem_type_str(mem_type)}+0x{rel_address.value:X}]"
                else: # RegisterRelAddr
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+0x{rel_address.value:X}]"
            else: # MemoryOfsReg, RegisterOfsReg
                ofs_reg_index = first_dword & 0xF
                if comp_type == CompareRegisterValueType.MemoryOfsReg:
                    comp_str = f"[{mem_type_str(mem_type)}+R{ofs_reg_index}]"
                else: # RegisterOfsReg
                    addr_reg_index = (first_dword >> 4) & 0xF
                    comp_str = f"[R{addr_reg_index}+R{ofs_reg_index}]"
        out.str = f"If R{val_reg_index} {CONDITION_STR.get(cond_type, '?')} {comp_str}"
      
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegister:
        dst_index = (first_dword >> 16) & 0xF
        src_index = (first_dword >> 8) & 0xF
        op_type = SaveRestoreRegisterOpType((first_dword >> 4) & 0xF)
        out.str = f"SaveRestoreRegister dst={dst_index} src={src_index} {OPERAND_STR.get(op_type, '?')}"
      
    elif out.opcode == CheatVmOpcodeType.SaveRestoreRegisterMask:
        op_type = SaveRestoreRegisterOpType((first_dword >> 20) & 0xF)
        mask = first_dword & 0xFFFF
        out.str = f"SaveRestoreRegisterMask {OPERAND_STR.get(op_type, '?')} mask=0x{mask:04X}"
      
    elif out.opcode == CheatVmOpcodeType.ReadWriteStaticRegister:
        static_idx = (first_dword >> 4) & 0xFF
        idx = first_dword & 0xF
        out.str = f"ReadWriteStaticRegister static_idx=0x{static_idx:X} idx={idx}"
      
    elif out.opcode == CheatVmOpcodeType.BeginExtendedKeypressConditionalBlock:
        auto_repeat = ((first_dword >> 20) & 0xF) != 0
        key_mask, instruction_ptr = get_next_vm_int(opcodes, instruction_ptr, 8)
        out.str = f"If {'keyheld' if auto_repeat else 'keydown'} 0x{key_mask.value:X}"
      
    elif out.opcode == CheatVmOpcodeType.PauseProcess:
        out.str = "PauseProcess"
      
    elif out.opcode == CheatVmOpcodeType.ResumeProcess:
        out.str = "ResumeProcess"
      
    elif out.opcode == CheatVmOpcodeType.DebugLog:
        out.str = "DebugLog" # Simplified

    else:
        out.str = f"Opcode {out.opcode.name} not implemented in this script."

    out.size = instruction_ptr - index
    return out

def disassemble_cheat(opcodes):
    """Disassembles a list of opcodes for a single cheat."""
    index = 0
    while index < len(opcodes):
        opcode_info = decode_next_opcode(opcodes, index)
        if not opcode_info:
            break
      
        raw_opcodes_list = opcodes[index : index + opcode_info.size]
        raw_opcodes_str = " ".join([f"{opc:08X}" for opc in raw_opcodes_list])

        print(f"{raw_opcodes_str:<40} {opcode_info.str}")
      
        index += opcode_info.size

def disassemble_opcodes_from_file(file_path):
    global TARGET_ARCH # Declare intent to modify global variable
    if TARGET_ARCH is None: # If not set by command line, prompt
        TARGET_ARCH = get_target_arch_from_user()

    try:
        with open(file_path, 'r') as f:
            cheat_opcodes = []
            for line in f:
                stripped_line = line.strip()
                if not stripped_line:
                    continue

                if (stripped_line.startswith('[') and stripped_line.endswith(']')) or \
                   (stripped_line.startswith('{') and stripped_line.endswith('}')):
                    if cheat_opcodes:
                        disassemble_cheat(cheat_opcodes)
                        cheat_opcodes = []
                    print(f"\n{stripped_line}")
                else:
                    parts = stripped_line.split()
                    for part in parts:
                        if part:
                            try:
                                cheat_opcodes.append(int(part, 16))
                            except ValueError:
                                # Ignore non-hex parts, could be comments
                                pass
            # After the loop, process any remaining opcodes
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)

    except FileNotFoundError:
        print(f"Error: The file '{file_path}' was not found.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

def disassemble_opcodes_from_string(opcodes_str):
    cheat_opcodes = []
    for line in opcodes_str.splitlines():
        line = line.strip()
        if not line:
            continue
        if line.startswith('[') and line.endswith(']'):
            if cheat_opcodes:
                disassemble_cheat(cheat_opcodes)
                cheat_opcodes = []
            print(f"\n{line}")
        else:
            parts = line.split()
            for part in parts:
                try:
                    cheat_opcodes.append(int(part, 16))
                except ValueError:
                    pass  # Ignore non-hex parts
    if cheat_opcodes:
        disassemble_cheat(cheat_opcodes)

def get_target_arch_from_user():
    while True:
        choice = input("Enter target architecture (ARM32/ARM64): ").strip().upper()
        if choice in ["ARM32", "ARM64"]:
            return choice
        else:
            print("Invalid choice. Please enter 'ARM32' or 'ARM64'.")

def main():
    """Main function to handle command-line arguments or interactive mode."""
    global TARGET_ARCH

    if not CAPSTONE_AVAILABLE:
        print("Capstone library not found. Please install it with 'pip install capstone'")
        sys.exit(1)

    file_path_arg = None
    for i, arg in enumerate(sys.argv[1:]):
        if arg.lower() == "--arch" and i + 1 < len(sys.argv[1:]):
            arch_arg = sys.argv[i+2].strip().upper()
            if arch_arg in ["ARM32", "ARM64"]:
                TARGET_ARCH = arch_arg
                print(f"Target architecture set to: {TARGET_ARCH} (from command line)")
            else:
                print(f"Warning: Invalid architecture '{arch_arg}' provided via --arch. Will prompt.")
            sys.argv.pop(i+1)
            sys.argv.pop(i+1)
            break

    if len(sys.argv) > 1:
        file_path_arg = sys.argv[1]

    if TARGET_ARCH is None:
        TARGET_ARCH = get_target_arch_from_user()
    print(f"\nDisassembly will target: {TARGET_ARCH}")

    if file_path_arg:
        print(f"--- Disassembling from file: {file_path_arg} ---")
        disassemble_opcodes_from_file(file_path_arg)
        input("\nPress Enter to exit...")
      
    else:
     if len(sys.argv) != 2:
        print("Usage: python ASMdisassemble_cheats.py <path_to_opcode_file>")
        example_file = 'asm.txt'
        print(f"\nNo file provided. Trying with example file: '{example_file}'")
        try:
            with open(example_file, 'r'):
                disassemble_opcodes_from_file(example_file)
        except FileNotFoundError:
            print(f"Example file '{example_file}' not found.")

        print("--- Interactive Mode ---")
        while True:
            print("\nPaste your opcodes (type 'done' on a new line to finish):")
            opcodes_str = ""
            while True:
                try:
                    line = input()
                    if line.strip().lower() == 'done':
                        break
                    opcodes_str += line + "\n"
                except EOFError:
                    break
          
            if opcodes_str.strip():
                disassemble_opcodes_from_string(opcodes_str)
          
            choice = input("\nDisassemble more? (yes/no): ")
            if choice.strip().lower() != 'yes':
                break

if __name__ == "__main__":
    main()
View attachment 518092
View attachment 518093
View attachment 518094
Here is a script to assemble codes to type 0.. a mix of both Tom and I only arm 64. I havent even tried arm32 for this.


Python:
import sys
import re
import struct
from enum import Enum


try:
    from keystone import Ks, KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN
    KEYSTONE_AVAILABLE = True
except ImportError:
    KEYSTONE_AVAILABLE = False
    print("FATAL ERROR: Keystone library not found. Please install it with 'pip install keystone-engine'", file=sys.stderr)
    sys.exit(1)

class CheatVmOpcodeType(Enum):
    StoreStatic = 0
    BeginConditionalBlock = 1
    EndConditionalBlock = 2
    ControlLoop = 3
    LoadRegisterStatic = 4
    LoadRegisterMemory = 5
    StoreStaticToAddress = 6
    PerformArithmeticStatic = 7
    BeginKeypressConditionalBlock = 8
    PerformArithmeticRegister = 9
    StoreRegisterToAddress = 10
    Reserved11 = 11
    ExtendedWidth = 12
    BeginRegisterConditionalBlock = 0xC0
    SaveRestoreRegister = 0xC1
    SaveRestoreRegisterMask = 0xC2
    ReadWriteStaticRegister = 0xC3
    BeginExtendedKeypressConditionalBlock = 0xC4
    DoubleExtendedWidth = 0xF0
    PauseProcess = 0xFF0
    ResumeProcess = 0xFF1
    DebugLog = 0xFFF

class MemoryAccessType(Enum):
    MainNso = 0
    Heap = 1
    Alias = 2
    Aslr = 3

def mem_type_from_str(s):
    s_lower = s.lower() if s else ""
    if s_lower == "main": return MemoryAccessType.MainNso
    if s_lower == "heap": return MemoryAccessType.Heap
    if s_lower == "alias": return MemoryAccessType.Alias
    if s_lower == "aslr": return MemoryAccessType.Aslr
    
    if not s:
        print(f"Warning: No memory type specified in input. Defaulting to MainNso.", file=sys.stderr)
    else:
        print(f"Warning: Unrecognized memory type string '{s}'. Defaulting to MainNso.", file=sys.stderr)
    return MemoryAccessType.MainNso

def assemble_instruction(instruction, addr=0):
    try:
        ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
        encoding_raw, count = ks.asm(instruction, addr)
        
        if isinstance(encoding_raw, list):
            encoding_bytes = bytes(encoding_raw)
        elif isinstance(encoding_raw, bytes):
            encoding_bytes = encoding_raw
        else:
            print(f"Error: Unexpected type for Keystone encoding: {type(encoding_raw)}", file=sys.stderr)
            return None, "Keystone returned unexpected type."

        if not encoding_bytes and count == 0:
            print(f"Warning: Keystone assembled '{instruction}' but returned no bytes (empty encoding list/bytes).", file=sys.stderr)
            return None, "Empty encoding returned by Keystone."

        return encoding_bytes, None
    except Exception as e:
        print(f"Error: Exception during Keystone assembly of '{instruction}' at 0x{addr:X}: {e}", file=sys.stderr)
        return None, str(e)

def assemble_from_string(input_str):
    output_lines = []
    current_cheat_name = ""
    processed_lines_count = 0


    for line_num, line in enumerate(input_str.splitlines(), 1):
        line_stripped = line.strip()
        if not line_stripped:
            continue
        

        if line_stripped.startswith('[') and line_stripped.endswith(']') and not '=' in line_stripped:
            if current_cheat_name:
                output_lines.append("")
            current_cheat_name = line_stripped
            output_lines.append(current_cheat_name)
            continue

        match = re.match(r'\[(?:(\w+)\+)?R(\d+)\+0x([0-9A-Fa-f]+)\]=(.*)', line_stripped)
        if not match:
            print(f"Warning (Line {line_num}): Line format not recognized, skipping: '{line_stripped}'", file=sys.stderr)
            continue
            
        mem_type_str_raw, reg_str, addr_str, value_str_raw = match.groups()
        
        mem_type = mem_type_from_str(mem_type_str_raw)
        register_index = int(reg_str)
        absolute_address = int(addr_str, 16)
        value_to_encode = value_str_raw.strip()

        relative_address = absolute_address

        val = None
        bit_width = 4


        if value_to_encode.lower().startswith('flt:'):
            float_str = value_to_encode[4:]
            try:
                float_val = float(float_str)
                packed_float_bytes = struct.pack('<f', float_val)
                val = int.from_bytes(packed_float_bytes, 'little')
                bit_width = 4
            except (ValueError, struct.error) as e:
                print(f"Error (Line {line_num}): Could not parse float value '{float_str}'. Error: {e}. Skipping line: '{line_stripped}'", file=sys.stderr)
                continue
        else:
            instructions = [i.strip() for i in value_to_encode.split(';') if i.strip()]
            
            if not instructions:
                print(f"Warning (Line {line_num}): No instruction found to assemble in line: '{line_stripped}'. Skipping.", file=sys.stderr)
                continue
            
            if len(instructions) > 2:
                print(f"Warning (Line {line_num}): More than two instructions on a line are not supported for Type 0: '{line_stripped}'. Skipping.", file=sys.stderr)
                continue

            bit_width = 4 * len(instructions)
            
            assembled_bytes_list = []
            current_instr_addr = relative_address
            
            assembly_failed = False
            for instr_idx, instr in enumerate(instructions):
                encoding_bytes, error = assemble_instruction(instr, current_instr_addr)
                
                if encoding_bytes is None:
                    assembly_failed = True
                    break
                
                if len(encoding_bytes) != 4:
                    print(f"Error (Line {line_num}): Assembled instruction '{instr}' is not 4 bytes ({len(encoding_bytes)} bytes). Keystone might be misbehaving. Skipping line: '{line_stripped}'", file=sys.stderr)
                    assembly_failed = True
                    break
                
                assembled_bytes_list.append(encoding_bytes)
                current_instr_addr += 4

            if assembly_failed:
                continue

            if len(instructions) == 1:
                val = int.from_bytes(assembled_bytes_list[0], 'little')
            else:
                val1 = int.from_bytes(assembled_bytes_list[0], 'little')
                val2 = int.from_bytes(assembled_bytes_list[1], 'little')
                val = (val2 << 32) | val1

        if val is not None:
            if not (bit_width == 4 or bit_width == 8):
                 print(f"Error (Line {line_num}): Invalid bit_width {bit_width}. Must be 4 or 8. Skipping line: '{line_stripped}'", file=sys.stderr)
                 continue

            if not (0 <= register_index <= 15):
                 print(f"Error (Line {line_num}): Invalid register index {register_index}. Must be 0-15. Skipping line: '{line_stripped}'", file=sys.stderr)
                 continue
            
            first_dword_val = 0x00000000
            first_dword_val |= (bit_width & 0xF) << 24
            first_dword_val |= (mem_type.value & 0xF) << 20
            first_dword_val |= (register_index & 0xF) << 16
            first_dword_val |= ((relative_address >> 32) & 0xFF)

            addr_lower_32 = relative_address & 0xFFFFFFFF
            
            if bit_width == 8:
                val_lower_32 = val & 0xFFFFFFFF
                val_upper_32 = (val >> 32) & 0xFFFFFFFF
                output_lines.append(f"{first_dword_val:08X} {addr_lower_32:08X} {val_upper_32:08X} {val_lower_32:08X}")
            else:
                output_lines.append(f"{first_dword_val:08X} {addr_lower_32:08X} {val:08X}")
            
            processed_lines_count += 1

    if processed_lines_count == 0 and not output_lines:
        print("\n--- No valid cheat lines were processed. Check your input format and any errors above. ---", file=sys.stderr)
    elif processed_lines_count > 0:
        print(f"\n--- Successfully processed {processed_lines_count} lines. ---", file=sys.stderr)
    
    return "\n".join(output_lines)

def main():
    try:
        ks_test = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
        test_instr = "mov x0, #1"
        test_encoding_raw, test_count = ks_test.asm(test_instr)
        
        if isinstance(test_encoding_raw, list):
            test_encoding_bytes = bytes(test_encoding_raw)
        elif isinstance(test_encoding_raw, bytes):
            test_encoding_bytes = test_encoding_raw
        else:
            print(f"FATAL ERROR: Keystone basic test returned unexpected type: {type(test_encoding_raw)}", file=sys.stderr)
            sys.exit(1)

        if not test_encoding_bytes or test_count == 0:
            print(f"FATAL ERROR: Keystone failed basic assembly test for '{test_instr}'. Encoding: {test_encoding_bytes}, Count: {test_count}", file=sys.stderr)
            sys.exit(1)
        
    except Exception as e:
        print(f"FATAL ERROR: Keystone library initialized but failed basic test with exception: {e}", file=sys.stderr)
        sys.exit(1)

    if len(sys.argv) > 1:
        file_path = sys.argv[1]
        try:
            with open(file_path, 'r') as f:
                input_str = f.read()
            output_str = assemble_from_string(input_str)
            print(output_str)
        except FileNotFoundError:
            print(f"Error: File not found '{file_path}'", file=sys.stderr)
            sys.exit(1)
        except Exception as e:
            print(f"FATAL ERROR: An unexpected error occurred during file processing: {e}", file=sys.stderr)
            sys.exit(1)
    else:
        print("--- Interactive Mode (ARM64 to Type 0 Converter) ---", file=sys.stderr)
        print("Enter ARM64 assembly-like cheat lines (e.g., [Main+R0+0x100000000]= mov x0, #0):", file=sys.stderr)
        print("Type 'done' on a new line to finish.", file=sys.stderr)
        input_lines = []
        while True:
            try:
                line = input()
                if line.strip().lower() == 'done':
                    break
                input_lines.append(line)
            except EOFError:
                break
        
        input_str = "\n".join(input_lines)
        if input_str.strip():
            output_str = assemble_from_string(input_str)
            print("\n--- Converted Type 0 Opcodes ---")
            print(output_str)
        else:
            print("No input provided. Exiting interactive mode.", file=sys.stderr)

if __name__ == "__main__":
    main()
    input("\nPress Enter to exit...")
Screenshot 2025-07-23 105559.png

I am going to goto bed now :')

you can open and paste in the asm or command line feed it your own txt file with everything in place.
 
Snow Bros. Special 1.1.1
TID: 0100BFA01787C000
BID: 31FDB371D67EB84D

[Breeze beta99j Snow Bros. Special 1.1.1 TID: 0100BFA01787C000 BID: 31FDB371D67EB84D]

[Original]
20000000

[Inf.Credits]
580F0000 05A4C780
580F1000 00000190
580F1000 00000008
780F0000 00000195
610F0000 00000000 00000009

[Always Secret Bonus]
80000100
580F0000 05A4C780
580F1000 00000190
580F1000 00000008
780F0000 0000165D
610F0000 00000000 00000001
20000000

[1P Inf.Lives]
580F0000 05A4C780
580F1000 00000190
580F1000 00000008
780F0000 00001591
610F0000 00000000 0000000A

[2P Inf.Lives]
580F0000 05A4C780
580F1000 00000190
580F1000 00000008
780F0000 000015A7
610F0000 00000000 0000000A

[1P Always All Powers]
580F0000 05A4C780
580F1000 00000190
580F1000 00000008
780F0000 000015A8
610F0000 00000000 00000070

[2P Always All Powers]
580F0000 05A4C780
580F1000 00000190
580F1000 00000008
780F0000 000015A9
610F0000 00000000 00000070
[/SPOILER[

Original Code by ネオ•グランゾン
 

Attachments

Site & Scene News

Popular threads in this forum