]> Chaos Git - corbenik/corbenik.git/commitdiff
All of the basic patches now use the interpreter.
authorchaoskagami <chaos.kagami@gmail.com>
Thu, 2 Jun 2016 12:33:09 +0000 (08:33 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Thu, 2 Jun 2016 12:33:09 +0000 (08:33 -0400)
host/bytecode_asm.py
patch/memexec.pco
source/interp.c
source/patch/memexec.c
source/patch/unitinfo.c

index f82e0dffd57254129bc1e61ce153086b31aab19f..30aed0e28696ce6df5fa8de3a5ac0c5b425de6f1 100755 (executable)
@@ -57,7 +57,7 @@ def cat_list(list):
                retstr += str + " "
        return retstr
 
-def parse_op(token_list):
+def parse_op(token_list, instr_offs):
        global title
        global desc
        global name
@@ -134,10 +134,12 @@ def parse_op(token_list):
                if s != 2:
                        syn_err("invalid number of arguments")
 
-               if len(token_list[1] == 2):
-                       token_list[1] = "00" + token_list[1]
-
-               return bytearray.fromhex("07" + token_list[1])
+               if instr_offs == None:
+                       return bytearray.fromhex("070000")
+               else:
+                       tok = bytearray.fromhex(token_list[1])
+                       num = struct.unpack(">H", tok)[0]
+                       return bytearray.fromhex("07") + struct.pack(">H", instr_offs[num])
        elif token_list[0] == "rewind":
                return bytearray.fromhex("08")
        elif token_list[0] == "and":
@@ -184,16 +186,33 @@ except:
 
 size = 0
 
+offsets = []
+
 with open(in_file, "r") as ins:
        with open(out_file, "wb") as writ:
                bytecode = bytearray()
 
+               # We have to do two passes because of JMP.
+               # One to figure out the opcode offsets, one
+               # to actually parse everything.
+
                for line in ins:
                        lines += 1
                        tokens = re.split("\s+", line.strip("\n")) # Split by whitespace.
-                       bytes = parse_op(tokens) # Parse.
+                       bytes = parse_op(tokens, None) # Parse.
                        if bytes:
+                               offsets += [size]
                                size += len(bytes)
+
+               print(offsets)
+
+               ins.seek(0)
+
+               for line in ins:
+                       lines += 1
+                       tokens = re.split("\s+", line.strip("\n")) # Split by whitespace.
+                       bytes = parse_op(tokens, offsets) # Parse.
+                       if bytes:
                                bytecode += bytes
 
                data  = bytearray("AIDA")
index 6226e98b29b14cf3b25127b36c818f4d6205af92..8b209315fe515bf67123434967e625953680bd13 100644 (file)
@@ -13,11 +13,11 @@ rel native_s1
 find 9705000015E40000
 
 # Move backwards until we find what we want.
-# LOOP: (3)
-       back 01
-       test 00016416
-       jmp  0007
-       jmp  0003
+# LOOP: (2)
+back 04
+test 16640100
+jmp  0006
+jmp  0002
 
-# END LOOP: (7)
-       and efff
+# END LOOP: (6)
+and  efff
index 8031d423ea958ff192622f27ae19ff1b662ed072..4d529516f4c4edaebdfb00f1f74a07112511a1d0 100644 (file)
@@ -185,18 +185,23 @@ int exec_bytecode(uint8_t* bytecode, uint32_t len, int debug) {
                                code += 2;
                                if(memcmp(current_mode->memory+offset, code, *(code-1))) {
                                        test_was_false = 1;
+                                       fprintf(stderr, "false\n");
+                               } else {
+                                       fprintf(stderr, "true\n");
                                }
-                               offset += *(code-1);
                                code   += *(code-1);
                                break;
                        case OP_JMP: // Jump to offset.
                                if (debug)
                                        fprintf(stderr, "jmp\n");
                                code++;
-                               if (!test_was_false)
-                                       code = bytecode + *((uint16_t*)code);
-                               else
+                               if (!test_was_false) {
+                                       fprintf(stderr, "jmp to %hu,%hu\n", code[0], code[1]);
+                                       code = bytecode + code[1] + ( code[0] * 0x100 );
+                               } else {
+                                       code += 2;
                                        test_was_false = 0;
+                               }
                                break;
                        case OP_REWIND:
                                if (debug)
index 7f8888c4c5e6093522b4f3894bb1514283cb3a66..4fc0b339c9e2375f5554e2f8f43b0ce5858db358 100644 (file)
@@ -6,48 +6,9 @@
 // behavioral change that can be used maliciously and/or to
 // detect CFW use rather easily.
 
-/*
-  rel native_s1
-  find 8, 0x97, 0x05, 0x00, 0x00, 0x15, 0xE4, 0x00, 0x00
-  back 1
-  test 4, 0x00016416
-  jmp 7
-  jmp 3
-  and ~(1<<4)
- */
-
 PATCH(memexec)
 {
-       firm_section_h* arm11_section = & firm_loc->section[1]; // Section 1, please.
-
-    uint8_t* firm_mem = (uint8_t*)firm_loc + arm11_section->offset;
-    uint32_t size = arm11_section->size;
-
-       const uint8_t pattern[] = {0x97, 0x05, 0x00, 0x00, 0x15, 0xE4, 0x00, 0x00};
-
-    // We look for 'exe:' first; this string is close to what we patch
-    uint32_t* off = (uint32_t*)memfind(firm_mem, size, pattern, 8);
-
-    if (off == NULL) {
-        fprintf(stderr, "memexec: couldn't find pattern.\n");
-        return 1;
-    }
-
-       // NOTE - Luma3DS' check here was incoherent.
-       // It read as 'decrement until 0x00000000, which means on
-       // failure it would cause lockup due to read of unreadable mapped areas.
-       // Even worse, it could end up patching something that isn't in FCRAM.
-       while(off > (uint32_t*)firm_mem && *off != 0x16416)
-               off--;
-
-       if(off == (uint32_t*)firm_mem) {
-        fprintf(stderr, "memexec: beginning missing.\n");
-        return 1;
-       }
-
-       *off &= ~(1 << 4); //Clear XN bit
-
-    fprintf(stderr, "memexec: Cleared XN bit.\n");
+       execb(PATH_PATCHES "/memexec.vco");
 
     return 0;
 }
index e143e731f25585f1646a7ae34e5ecaa9c5f81ea6..9649449fa92d75c5dec94cf6e02080f72b3947a7 100644 (file)
@@ -5,47 +5,9 @@
 // usually the ErrDisp patch in loader should be good enough for
 // debugging crashes.
 
-/*
-  rel native_arm9
-  find 4, 0x01, 0x10, 0xA0, 0x13
-  fwd 3
-  set 1, 0xE3
- */
-
 PATCH(unitinfo)
 {
-       firm_section_h* arm9_section;
-       int found_sect = 0;
-
-       for (arm9_section = firm_loc->section;
-         arm9_section < firm_loc->section + 4; arm9_section++) {
-        if (arm9_section->type == FIRM_TYPE_ARM9) {
-                       found_sect = 1;
-                       break;
-               }
-       }
-
-       if (!found_sect) {
-               fprintf(stderr, "unitinfo: no arm9 section?\n");
-               return 1;
-       }
-
-    uint8_t* firm_mem = (uint8_t*)firm_loc + arm9_section->offset;
-    uint32_t size = arm9_section->size;
-
-       const uint8_t pattern[] = {0x01, 0x10, 0xA0, 0x13};
-
-    // We look for 'exe:' first; this string is close to what we patch
-    uint8_t* off = memfind(firm_mem, size, pattern, 4);
-
-    if (off == NULL) {
-        fprintf(stderr, "unitinfo: Couldn't find UNITINFO.\n");
-        return 1;
-    }
-
-       off[3] = 0xE3;
-
-    fprintf(stderr, "unitinfo: Applied\n");
+       execb(PATH_PATCHES "/unitinfo.vco");
 
     return 0;
 }