From: chaoskagami Date: Sat, 11 Jun 2016 22:57:42 +0000 (-0400) Subject: Remove hackish jmp syntax, add labels X-Git-Tag: v0.0.9~4 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=78b0459289c4db86b201d06ea89c5fdd533c0f46;p=corbenik%2Fcorbenik.git Remove hackish jmp syntax, add labels --- diff --git a/host/bytecode_asm.py b/host/bytecode_asm.py index 0dd38dc..6e81c1e 100755 --- a/host/bytecode_asm.py +++ b/host/bytecode_asm.py @@ -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") diff --git a/patch/aadowngrade.pco b/patch/aadowngrade.pco index 5c163fe..ce774b8 100644 --- a/patch/aadowngrade.pco +++ b/patch/aadowngrade.pco @@ -13,5 +13,6 @@ rel native_p9 # We want to patch the fifth byte of this pattern. find 890a814202D2 +abortnf fwd 05 set E0 diff --git a/patch/agb_biosscreen.pco b/patch/agb_biosscreen.pco index a15b354..99db776 100644 --- a/patch/agb_biosscreen.pco +++ b/patch/agb_biosscreen.pco @@ -15,5 +15,6 @@ rel agb # Bootscreen (1) find 000001ef +abortnf fwd 02 set 26 diff --git a/patch/agb_sig.pco b/patch/agb_sig.pco index 1646020..761abee 100644 --- a/patch/agb_sig.pco +++ b/patch/agb_sig.pco @@ -10,4 +10,5 @@ rel agb # ############################# find C117491C31D0 +abortnf set 00204EB070BD diff --git a/patch/block_cart_update.pco b/patch/block_cart_update.pco index 210f3f0..b07acf6 100644 --- a/patch/block_cart_update.pco +++ b/patch/block_cart_update.pco @@ -9,7 +9,9 @@ rel exe_text # Status: needs loader find 0C18E1D8 +abortnf set 0B1821C8 find 0C18E1D8 +abortnf set 0B1821C8 diff --git a/patch/block_eshop_update.pco b/patch/block_eshop_update.pco index b02f03f..6486cb9 100644 --- a/patch/block_eshop_update.pco +++ b/patch/block_eshop_update.pco @@ -9,4 +9,5 @@ rel exe_text # Status: needs loader find 30B5F1B0 +abortnf set 002008607047 diff --git a/patch/block_nim_update.pco b/patch/block_nim_update.pco index c162ccf..ae4dfb4 100644 --- a/patch/block_nim_update.pco +++ b/patch/block_nim_update.pco @@ -9,4 +9,5 @@ rel exe_text # Status: needs loader find 25790B99 +abortnf set E3A0 diff --git a/patch/errdisp.pco b/patch/errdisp.pco index 07748b0..0ab46fa 100644 --- a/patch/errdisp.pco +++ b/patch/errdisp.pco @@ -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 diff --git a/patch/friends_ver.pco b/patch/friends_ver.pco index a8e16b9..df74913 100644 --- a/patch/friends_ver.pco +++ b/patch/friends_ver.pco @@ -10,5 +10,6 @@ rel exe_text # Status: needs loader find E01EFF2FE1010101 +abortnf fwd 09 set 06 diff --git a/patch/memexec.pco b/patch/memexec.pco index 566fd72..e1ed3af 100644 --- a/patch/memexec.pco +++ b/patch/memexec.pco @@ -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 diff --git a/patch/mset_str.pco b/patch/mset_str.pco index 6ee3b44..c001f5d 100644 --- a/patch/mset_str.pco +++ b/patch/mset_str.pco @@ -11,5 +11,7 @@ rel exe_text # u"Ver." find 5600650072002e00 +abortnf + # u".hax" set 2e006800610078 diff --git a/patch/ns_force_menu.pco b/patch/ns_force_menu.pco index f2aec05..8c8188a 100644 --- a/patch/ns_force_menu.pco +++ b/patch/ns_force_menu.pco @@ -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) diff --git a/patch/prot.pco b/patch/prot.pco index 80e45a9..a7dd6d4 100644 --- a/patch/prot.pco +++ b/patch/prot.pco @@ -9,7 +9,11 @@ rel native_p9 # String: 'exe:' find 6578653a +abortnf + back 01 back ff + find 002801DA +abortnf set 0020C046 diff --git a/patch/regionfree.pco b/patch/regionfree.pco index d361430..e94b4d3 100644 --- a/patch/regionfree.pco +++ b/patch/regionfree.pco @@ -9,6 +9,7 @@ rel exe_text # Status: needs loader find 000055E30110A0E3 +abortnf # 16 back 10 diff --git a/patch/ro_sigs.pco b/patch/ro_sigs.pco index 8f00b74..c9e2d43 100644 --- a/patch/ro_sigs.pco +++ b/patch/ro_sigs.pco @@ -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 diff --git a/patch/secinfo_sigs.pco b/patch/secinfo_sigs.pco index ae439ae..4d666a8 100644 --- a/patch/secinfo_sigs.pco +++ b/patch/secinfo_sigs.pco @@ -9,4 +9,5 @@ rel exe_text # Status: needs loader find 06461048FC +abortnf set 0026 diff --git a/patch/sig.pco b/patch/sig.pco index 4774715..a8a63aa 100644 --- a/patch/sig.pco +++ b/patch/sig.pco @@ -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 diff --git a/patch/twl_fix.pco b/patch/twl_fix.pco index a6f18a5..24cfb8a 100644 --- a/patch/twl_fix.pco +++ b/patch/twl_fix.pco @@ -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: diff --git a/patch/unitinfo.pco b/patch/unitinfo.pco index f25807a..ec239ac 100644 --- a/patch/unitinfo.pco +++ b/patch/unitinfo.pco @@ -9,5 +9,6 @@ rel native_s2 find 0110A013 +abortnf fwd 03 set E3 diff --git a/source/interp.c b/source/interp.c index 6971c12..248daa8 100644 --- a/source/interp.c +++ b/source/interp.c @@ -26,6 +26,14 @@ #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");