]> Chaos Git - corbenik/corbenik.git/commitdiff
Remove hackish jmp syntax, add labels
authorchaoskagami <chaos.kagami@gmail.com>
Sat, 11 Jun 2016 22:57:42 +0000 (18:57 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Sat, 11 Jun 2016 22:57:42 +0000 (18:57 -0400)
20 files changed:
host/bytecode_asm.py
patch/aadowngrade.pco
patch/agb_biosscreen.pco
patch/agb_sig.pco
patch/block_cart_update.pco
patch/block_eshop_update.pco
patch/block_nim_update.pco
patch/errdisp.pco
patch/friends_ver.pco
patch/memexec.pco
patch/mset_str.pco
patch/ns_force_menu.pco
patch/prot.pco
patch/regionfree.pco
patch/ro_sigs.pco
patch/secinfo_sigs.pco
patch/sig.pco
patch/twl_fix.pco
patch/unitinfo.pco
source/interp.c

index 0dd38dc31ae2e550e92314195abfca5165149979..6e81c1e75987e4a89a6068bcc59903ba65175a07 100755 (executable)
@@ -61,6 +61,19 @@ ver = "01"
 flags = []
 uuid = ""
 deps = []
+size = 0
+offsets = {}
+
+def pad_zero_r(x, c):
+       while len(x) < c:
+               x = x + bytearray([0])
+       return x
+
+
+def pad_zero_l(x, c):
+       while len(x) < c:
+               x = bytearray([0]) + x
+       return x
 
 def cat_list(list):
        retstr = ""
@@ -80,7 +93,12 @@ def parse_op(token_list, instr_offs):
        if s == 0:
                return bytearray() # Empty.
 
-       if token_list[0] == "#": # Comment.
+       elif token_list[0][-1:] == ":":
+               if instr_offs == None: # Label.
+                       offsets[token_list[0][:-1]] = size
+               return bytearray()
+
+       elif token_list[0] == "#": # Comment.
                if s < 3:
                        return bytearray() # Nope.
                elif token_list[1] == "$name": # Meta: name
@@ -147,10 +165,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("07") + val
+                       return bytearray.fromhex("07") + pad_zero_r(val, 2)
        elif token_list[0] == "rewind":
                return bytearray.fromhex("08")
        elif token_list[0] == "and":
@@ -197,10 +214,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("17") + val
+                       return bytearray.fromhex("17") + pad_zero_r(val, 2)
        elif token_list[0] == "jmpne":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -208,10 +224,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("27") + val
+                       return bytearray.fromhex("27") + pad_zero_r(val, 2)
        elif token_list[0] == "jmplt":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -219,10 +234,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("37") + val
+                       return bytearray.fromhex("37") + pad_zero_r(val, 2)
        elif token_list[0] == "jmpgt":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -230,10 +244,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("47") + val
+                       return bytearray.fromhex("47") + pad_zero_r(val, 2)
        elif token_list[0] == "jmple":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -241,10 +254,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("57") + val
+                       return bytearray.fromhex("57") + pad_zero_r(val, 2)
        elif token_list[0] == "jmpge":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -252,10 +264,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("67") + val
+                       return bytearray.fromhex("67") + pad_zero_r(val, 2)
        elif token_list[0] == "jmpf":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -263,10 +274,9 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("77") + val
+                       return bytearray.fromhex("77") + pad_zero_r(val, 2)
        elif token_list[0] == "jmpnf":
                if s != 2:
                        syn_err("invalid number of arguments")
@@ -274,23 +284,26 @@ def parse_op(token_list, instr_offs):
                if instr_offs == None:
                        return bytearray.fromhex("070000")
                else:
-                       num = int(token_list[1])
-                       val = bytearray(struct.pack(">H", instr_offs[num]))
+                       val = bytearray(struct.pack(">H", offsets[token_list[1]]))
                        val.reverse()
-                       return bytearray.fromhex("87") + val
+                       return bytearray.fromhex("87") + pad_zero_r(val, 2)
        elif token_list[0] == "n3ds": # Sets the eq flag if this is an n3ds.
                return bytearray.fromhex("10")
 
-def pad_zero_r(x, c):
-       while len(x) < c:
-               x = x + bytearray([0])
-       return x
-
-
-def pad_zero_l(x, c):
-       while len(x) < c:
-               x = bytearray([0]) + x
-       return x
+       elif token_list[0] == "abort":
+               return bytearray.fromhex("18")
+       elif token_list[0] == "aborteq":
+               return bytearray.fromhex("28")
+       elif token_list[0] == "abortne":
+               return bytearray.fromhex("38")
+       elif token_list[0] == "abortlt":
+               return bytearray.fromhex("48")
+       elif token_list[0] == "abortgt":
+               return bytearray.fromhex("58")
+       elif token_list[0] == "abortf":
+               return bytearray.fromhex("68")
+       elif token_list[0] == "abortnf":
+               return bytearray.fromhex("78")
 
 def flag_convert(x):
        flags = 0
@@ -311,10 +324,6 @@ except:
        usage()
        exit(1)
 
-size = 0
-offsets = []
-labels = []
-
 with open(in_file, "r") as ins:
        with open(out_file, "wb") as writ:
                bytecode = bytearray()
@@ -330,12 +339,8 @@ with open(in_file, "r") as ins:
                        tokens = re.split("\s+", line.strip("\n")) # Split by whitespace.
                        bytes = parse_op(tokens, None) # Parse.
                        if bytes:
-                               offsets += [size]
                                size += len(bytes)
 
-               offsets += [size] # So we can jump past the last instruction for 'exit' type behavior
-               lines = 0
-
                ins.seek(0)
 
                for line in ins:
@@ -343,6 +348,7 @@ with open(in_file, "r") as ins:
                        tokens = re.split("\s+", line.strip("\n")) # Split by whitespace.
                        bytes = parse_op(tokens, offsets) # Parse.
                        if bytes:
+                               print([bytes])
                                bytecode += bytes
 
                data  = bytearray("AIDA")
index 5c163fe247a22cf5cf1454ad91a9b4b3497f89d4..ce774b8e14528d46dd148221059f8a5d49117fb0 100644 (file)
@@ -13,5 +13,6 @@ rel  native_p9
 
 # We want to patch the fifth byte of this pattern.
 find 890a814202D2
+abortnf
 fwd  05
 set  E0
index a15b35452e812e9f5c5791de1d3c84fddb46b0fb..99db7760d65fa55d927e855494ff374e1fe7d060 100644 (file)
@@ -15,5 +15,6 @@ rel agb
 
 # Bootscreen (1)
 find  000001ef
+abortnf
 fwd   02
 set   26
index 1646020cd8908ca4676ed5363d07484dbdd08ad7..761abee70cd6841a38b1c388e242395fb0bb8611 100644 (file)
@@ -10,4 +10,5 @@ rel agb
 # #############################
 
 find  C117491C31D0
+abortnf
 set   00204EB070BD
index 210f3f0b82b4eaa43e2877ec964bd0a2f1900a68..b07acf63869833e962b30d14693d370516ec99f2 100644 (file)
@@ -9,7 +9,9 @@ rel exe_text
 # Status: needs loader
 
 find 0C18E1D8
+abortnf
 set  0B1821C8
 
 find 0C18E1D8
+abortnf
 set  0B1821C8
index b02f03fa68a5740321f9ca4babb977fa502e34f5..6486cb976228258919755223a85bf01a63e62d97 100644 (file)
@@ -9,4 +9,5 @@ rel exe_text
 # Status: needs loader
 
 find 30B5F1B0
+abortnf
 set  002008607047
index c162ccf2de7c4fe95f0c1256b0eba7dce60265e8..ae4dfb45782e5ced550bdc094ac387c29b3acabd 100644 (file)
@@ -9,4 +9,5 @@ rel exe_text
 # Status: needs loader
 
 find 25790B99
+abortnf
 set  E3A0
index 07748b0cd6f707d06166421c63e09aa0a88588d3..0ab46fa76766df84848732a9c197f4fde28036e3 100644 (file)
@@ -10,11 +10,17 @@ rel exe_text
 # Status: needs loader
 
 find 1400D0E5DB9A9FED
+abortnf
 set  0000A0E3
 
 find 1400D0E5010010E3
+abortnf
 set  0000A0E3
+
 find 1400D0E5010010E3
+abortnf
 set  0000A0E3
+
 find 1400D0E5010010E3
+abortnf
 set  0000A0E3
index a8e16b9888a2499bf22658b611e3d46bdc2bd7b2..df74913aa83180079ae827ae50834b9e5b758902 100644 (file)
@@ -10,5 +10,6 @@ rel exe_text
 # Status: needs loader
 
 find E01EFF2FE1010101
+abortnf
 fwd  09
 set  06
index 566fd72e1e380a365a8228c94e96274719abd347..e1ed3afddc0a146d92f85e9cd005742a5a119c56 100644 (file)
@@ -9,11 +9,13 @@ rel    native_s1
 
 # 1: Find this byte string.
 find   9705000015E40000
+abortnf
 
 # Move backwards until we find what we want.
-# LOOP (2):
+loop_back:
+
 back   04
 test   16640100
-jmpne  2
+jmpne  loop_back
 
 and    ef
index 6ee3b4461db798582cf0b2f5d1c30c5fc88a39ce..c001f5d25f37075900ea7320a94a8537ce8ae7e4 100644 (file)
@@ -11,5 +11,7 @@ rel exe_text
 # u"Ver."
 find 5600650072002e00
 
+abortnf
+
 # u".hax"
 set  2e006800610078
index f2aec0531fbad177a16324deaa3f50e2d2341cc5..8c8188a1b829ceeb5e44561f1cc288b4c560b498 100644 (file)
@@ -12,6 +12,7 @@ rel exe_text
 # Searching for a relative bl is error prone,
 # so find the code before the bl and seek forward instead
 find 1b00000abc009fe5
+abortnf
 fwd  04
 
 # mov r0, r9 (== 0x00008102)
index 80e45a9552b46dffb6fa31627e86789bb1107cb7..a7dd6d404ad68ee6ba4e628fa5662fe86768cc7b 100644 (file)
@@ -9,7 +9,11 @@
 rel native_p9
 # String: 'exe:'
 find 6578653a
+abortnf
+
 back 01
 back ff
+
 find 002801DA
+abortnf
 set  0020C046
index d3614306af75478b13fb8f91c83c8a7e68fae651..e94b4d37c70f4c7e7df4436a07d632a3677f9f8d 100644 (file)
@@ -9,6 +9,7 @@ rel exe_text
 # Status: needs loader
 
 find 000055E30110A0E3
+abortnf
 
 # 16
 back 10
index 8f00b748103faf21c0ad729e1b0e49578e4203e1..c9e2d437292df25f9722712fea9e44ce98987011 100644 (file)
@@ -9,10 +9,13 @@ rel exe_text
 # Status: needs loader
 
 find 30402DE90250A0E1
+abortnf
 set  0000A0E31EFF2FE1
 
 find 30402DE924D04DE2
+abortnf
 set  0000A0E31EFF2FE1
 
 find F84F2DE90170A0E1
+abortnf
 set  0000A0E31EFF2FE1
index ae439ae3ca98eaf87dfc42693a871c4958a0af95..4d666a8e73341e8e07c6b72d569da3250b375ad7 100644 (file)
@@ -9,4 +9,5 @@ rel exe_text
 # Status: needs loader
 
 find 06461048FC
+abortnf
 set  0026
index 47747156d2ecbf7aa15e4ad4341dcfdc8c786885..a8a63aabde38f0586341cbd3c9bec17fe9cc8e69 100644 (file)
@@ -13,6 +13,7 @@ rel  native_p9
 
 # Pattern one.
 find c01c76e7
+abortnf
 set  0020
 
 # Rewind to beginning.
@@ -20,5 +21,6 @@ rewind
 
 # Pattern 2.
 find b5224d0c
+abortnf
 back 01
 set  00207047
index a6f18a5b54d03621fc705f848e0d76627c339448..24cfb8a8f4600b478ba0264ebf8e38ddc710a59b 100644 (file)
@@ -10,12 +10,14 @@ rel  twl
 
 # Disable main signature checks (1)
 find C117491C31D0
+abortnf
 set  00204EB070BD
 rewind
 
 # Patch RSA function to not report invalid signatures (4)
 # TODO - Check O3DS
 find 18ee0020
+abortnf
 fwd  02
 set  0120
 rewind
@@ -23,60 +25,67 @@ rewind
 # Disable header Nintendo logo check (not generally needed) (8)
 # TODO - Check O3DS
 find c03006f0
+abortnf
 fwd  02
 set  00200000
 rewind
 
 # Disable whitelist check (12)
 find FFF7B6FB
+abortnf
 set  00200000
 rewind
 
 # Disable cartridge blacklist check (mostly, if not entirely, demo carts) (15)
 # TODO - Check O3DS
 find 012520000ef0
+abortnf
 fwd  04
 set  01200000
 rewind
 
 # Stub function commonly used to compare SHA hashes to always succeed (19)
 find 10B51422
+abortnf
 set  01207047
 rewind
 
-##################################### (22)
+##################################### (28)
 
 # There's not enough context for the patterns below to patch both o3ds and n3ds, so
 # we have to split them up.
 
 n3ds
-jmpeq 25
-jmp   32
+jmpne o3ds
 
-# new: (25)
+# new: (31)
 
 # Disable save type check
 find FCF745FE
+abortnf
 set  01200000
 rewind
 
-# Disable DSi cartridge save exploit check (28)
+# Disable DSi cartridge save exploit check (35)
 find FCF765FD
+abortnf
 set  01200000
 rewind
 
-jmp 38
+jmp end
 
-# old: (32)
+o3ds:
 
 # Disable save type check
 find FCF771FE
+abortnf
 set  01200000
 rewind
 
 # Disable DSi cartridge save exploit check (35)
 find FCF791FD
+abortnf
 set  01200000
 rewind
 
-# end (38)
+end:
index f25807a0fb5d24228720133e4d4ed7590b1f9e7e..ec239ac7aa5ed1d311871e859cbc291c92d15a61 100644 (file)
@@ -9,5 +9,6 @@
 rel  native_s2
 
 find 0110A013
+abortnf
 fwd  03
 set  E3
index 6971c12c34d87191f6b54ba0d46ef578751ad3e5..248daa8a4c7b10a0ea967e89351b8673ac6cd335 100644 (file)
 #define OP_SEEK 0x0F
 #define OP_N3DS 0x10
 
+#define OP_ABORT   0x18
+#define OP_ABORTEQ 0x28
+#define OP_ABORTNE 0x38
+#define OP_ABORTLT 0x48
+#define OP_ABORTGT 0x58
+#define OP_ABORTF  0x68
+#define OP_ABORTNF 0x78
+
 #define OP_JMPEQ 0x17
 #define OP_JMPNE 0x27
 #define OP_JMPLT 0x37
@@ -436,6 +444,55 @@ exec_bytecode(uint8_t *bytecode, uint16_t ver, uint32_t len, int debug)
                 }
                 code += 4;
                 break;
+            case OP_ABORT:
+                code++;
+                if (debug)
+                    log("abort\n");
+
+                abort("abort triggered, halting VM!\n")
+                break;
+            case OP_ABORTEQ:
+                code++;
+                if (debug)
+                    log("aborteq\n");
+                if (eq)
+                    abort("eq flag not set, halting VM!\n")
+                break;
+            case OP_ABORTNE:
+                code++;
+                if (debug)
+                    log("abortlt\n");
+                if (!eq)
+                    abort("eq flag not set, halting VM!\n")
+                break;
+            case OP_ABORTLT:
+                code++;
+                if (debug)
+                    log("abortlt\n");
+                if (lt)
+                    abort("lt flag set, halting VM!\n")
+                break;
+            case OP_ABORTGT:
+                code++;
+                if (debug)
+                    log("abortgt\n");
+                if (gt)
+                    abort("gt flag set, halting VM!\n")
+                break;
+            case OP_ABORTF:
+                code++;
+                if (debug)
+                    log("abortf\n");
+                if (found)
+                    abort("f flag set, halting VM!\n")
+                break;
+            case OP_ABORTNF:
+                code++;
+                if (debug)
+                    log("abortnf\n");
+                if (!found)
+                    abort("f flag is not set, halting VM!\n")
+                break;
             case OP_NEXT:
                 if (debug) {
                     log("next\n");