Jump to content

Twili

Member
  • Posts

    273
  • Joined

  • Last visited

  • Days Won

    45

Posts posted by Twili

  1. How does one calculate or find the PC? I could really get some use out of this with Quest 64. 

    1. Find a display list in the ROM with some vertex data.

    2. Identify which command is loading that vertex data and get the last 3 bytes of the pointer from it.

    3. Subtract the ROM offset of the data from that.

    4. ???

    5. PC.

     

    Also once you get the PC, subtract it from that pointer.

    Then subtract the result from the ROM offset of the data to get the start of the file and you can use it with the decompiler.

     

    This only works if the file has machine code in it and the pointer starts with 0x80.

     

    That doesn't work, actually. I'd have to show how to do it if you paste data.

  2. Version 2 can be downloaded here: https://www.the-gcn.com/files/file/76-n64-function-decompiler/

     

    Improvements:

    +More MIPS opcodes supported.

    +NOW DETECTS LOOPS AND PRINTS THEM AS WHILE-LOOPS.

    +Now detects every RDP GBI command. *The hardwired ones and programmable ones exclusive to F3DEX_GBI_2. DMA GBI commands unsupported because their low range is too ambiguous with other values.*

     

    I've completely mapped out the source code file strings left in OoT debug's "code" file now: (as function offsets for the decompiler, as before)

     

    09a4  z_en_a_keep.c
    20d0  z_en_item00.c
    4100  z_eff_blure.c
    775c  z_eff_shield_particle.c
    81a0  z_eff_spark.c
    93d0  z_eff_ss_dead.c
    a450  z_effect_soft_sprite.c
    b120  z_effect_soft_sprite_old_init.c
    dc50  flg_set.c
    e248  z_DLF.c
    e3a0  z_actor.c
    18400 z_cheap_proc.c
    1b920 z_bgcheck.c
    3ad38 z_camera.c
    3e44c z_collision_check.c
    46860 z_debug.c
    471d0 z_debug_display.c
    4bddc z_demo.c
    4c684 z_draw.c
    4ed60 z_elf_message.c
    4f918 z_fcurve_data_skelanime.c
    5028c z_horse.c
    515b8 z_jpeg.c
    52000 z_kanfont.c
    52e28 z_kankyo.c
    5c0bc z_lifemeter.c
    5d09c z_lights.c
    5e430 z_map_mark.c
    5eb44 z_moji.c
    5f9f0 z_onepointdemo.c
    63c54 z_map_exp.c
    67c0c z_parameter.c
    72610 z_player_lib.c
    754d0 z_prenmi.c
    76510 z_rcp.c
    78c54 z_room.c
    7a7a4 z_sample.c
    7ada0 z_scene.c
    7c6f0 z_scene_table.c
    83a40 z_skelanime.c
    88b2c z_skin.c
    897dc z_skin_awb.c
    8ce74 z_sram.c
    8d398 z_view.c
    8f1d0 z_vimode.c
    901f4 z_vismono.c
    923b8 z_vr_box.c
    941d0 z_vr_box_draw.c
    94a50 z_fbdemo.c
    9b978 db_camera.c
    9ee30 z_kaleido_manager.c
    9f1f0 z_kaleido_scope_call.c
    9f630 z_play.c
    a40c8 PreRender.c
    a788c game.c
    a8850 gamealloc.c
    a8dcc graph.c
    a9fc0 main.c
    aa5ac padmgr.c
    ab440 sched.c
    acae0 speed_meter.c
    ad540 sys_cfb.c
    b39b0 sys_matrix.c
    b63c0 irqmgr.c
    df1b0 loadfragment2.c
    df260 mtxuty-cvt.c
    ecb08 z_message_PAL.c
    ef53c z_message.c
    f3b50 z_construct.c
     
    Here's how z_lights.c looks now:
     
    Program counter? 0x1ce60
    Function offset? 0x5d09c
    0005d09c: $sp=0xFFFFFF98;
    0005d0a0: stack[(-104)+24]=$s1;
    0005d0a4: $s1=0x00000000;                      /* $a0|$r0 */
    0005d0a8: stack[(-104)+28]=$ra;
    0005d0ac: stack[(-104)+20]=$s0;
    0005d0b0:                                      /* ^_^ */
    0005d0b4: $s0=0x00000000;                      /* $a1|$r0 */
    0005d0b8: $a2=0x8013C8A0;                      /* 0011FA40 in your file */
    0005d0bc: $a0=0xFFFFFFE4;
    0005d0c0:
    0005d0c4: $a3=0x00000153;
    0005d0c0: function_0c6ac4();                   /* 000A9C64 in your file */
    0005d0c8: $v1=mem[$s0+0x02c0];
    0005d0cc: $a0=0xDB020000;                      /* G_MOVEWORD        */
    0005d0d0: $a1=0x00000018;
    0005d0d4: $t6=0x00000008;
    0005d0d8: mem[$s0+0x02c0]=$t6;
    0005d0dc: mem[$v1+0x0000]=$a0;
    0005d0e0: (unsigned char)$t7=mem[$s1+0x0000];
    0005d0e4: $a3=0x00000000;                      /* $r0|$r0 */
    0005d0e8: $t0=0xDC080000;                      /* G_MOVEMEM         */
    0005d0ec: $lo = $t7 * $a1;
    0005d0f0: $t8=$lo;
    0005d0f4: mem[$v1+0x0004]=$t8;
    0005d0f8: $v1=mem[$s0+0x02d0];
    0005d0fc: $t9=0x00000008;
    0005d100: mem[$s0+0x02d0]=$t9;
    0005d104: mem[$v1+0x0000]=$a0;
    0005d108: (unsigned char)$t1=mem[$s1+0x0000];
    0005d10c: $a0=0x00000010;
    0005d110: $lo = $t1 * $a1;
    0005d114: $a1=0x00000018;
    0005d118: $t2=$lo;
    0005d11c: mem[$v1+0x0004]=$t2;
    0005d120: (unsigned char)$t3=mem[$s1+0x0000];
    0005d124: if($t3<=0)
              {
    0005d128:     $a1=0x00000000;                      /* $a3<<2 */
    0005d124:     goto 0005d198;
              }
    0005d12c: $v1=mem[$s0+0x02c0];
    0005d130: while($at!=$r0)
              {
              $a1=0x00000018;
    0005d134: $a3=0x00000001;
    0005d138: $t4=0x00000008;
    0005d13c: mem[$s0+0x02c0]=$t4;
    0005d140: $v0=0x00000000;                      /* $v1|$r0 */
    0005d144:
    0005d148: $t5=0xE0000003;                      /* $a1>>3 (fill empty bits) */
    0005d144: if($a1>=0)
              {
                  goto 0005d154;
              }
    0005d14c: $at=0x0000001F;
    0005d150: $t5=0xE0000003;                      /* $at>>3 (fill empty bits) */
    0005d154: $t6=0x00000003;
    0005d158: $t7=0x00000300;
    0005d15c:                                      /* -_- */
    0005d160: $a2=0xDC08030A;                      /* G_MOVEMEM         */
    0005d164: mem[$v0+0x0000]=$a2;
    0005d168: mem[$v0+0x0004]=$a0;
    0005d16c: $v1=mem[$s0+0x02d0];
    0005d170: $t8=0x00000008;
    0005d174: mem[$s0+0x02d0]=$t8;
    0005d178: mem[$v1+0x0004]=$a0;
    0005d17c: mem[$v1+0x0000]=$a2;
    0005d180: (unsigned char)$t9=mem[$s1+0x0000];
    0005d184: $a0=0x00000020;
    0005d188: if($a3<$t9)
              {
                  $at=1;
              }
              else
              {
                  $at=0;
              }
    0005d18c:
    0005d190: $v1=mem[$s0+0x02c0];
    0005d18c:
    0005d194: }
              $a1=0x00000004;
    0005d198: $a1=0x00000003;                      /* $a1-$a3 */
    0005d19c: $a1=0x00000018;
    0005d1a0: $v1=mem[$s0+0x02c0];
    0005d1a4: $a1=0x00000048;
    0005d1a8: $t0=0xDC080000;                      /* G_MOVEMEM         */
    0005d1ac: $t1=0x00000008;
    0005d1b0: mem[$s0+0x02c0]=$t1;
    0005d1b4: $v0=0x00000000;                      /* $v1|$r0 */
    0005d1b8:
    0005d1bc: $t2=0xE0000009;                      /* $a1>>3 (fill empty bits) */
    0005d1b8: if($a1>=0)
              {
                  goto 0005d1c8;
              }
    0005d1c0: $at=0x0000004F;
    0005d1c4: $t2=0xE0000009;                      /* $at>>3 (fill empty bits) */
    0005d1c8: $t3=0x00000009;
    0005d1cc: $t4=0x00000900;
    0005d1d0:                                      /* -_- */
    0005d1d4: $a2=0xDC08090A;                      /* G_MOVEMEM         */
    0005d1d8: $a0=0x00000008;
    0005d1dc: mem[$v0+0x0004]=$a0;
    0005d1e0: mem[$v0+0x0000]=$a2;
    0005d1e4: $v1=mem[$s0+0x02d0];
    0005d1e8: $a1=0x00000000;                      /* $s0|$r0 */
    0005d1ec: $a3=0x00000160;
    0005d1f0: $t5=0x00000008;
    0005d1f4: mem[$s0+0x02d0]=$t5;
    0005d1f8: mem[$v1+0x0000]=$a2;
    0005d1fc:                                      /* ^_^ */
    0005d200: mem[$v1+0x0004]=$a0;
    0005d204: $a0=0xFFFFFFE4;
    0005d208:
    0005d20c: $a2=0x8013C8B0;                      /* 0011FA50 in your file */
    0005d208: function_0c6b54();                   /* 000A9CF4 in your file */
    0005d210: $ra=stack[(-104)+28];
    0005d214: $s0=stack[(-104)+20];
    0005d218: $s1=stack[(-104)+24];
    0005d21c:
    Press any key to continue . . .
     
    See the while loop?
    • Like 3
  3. UPDATE IN THE LATEST POST.

     

    Download decompile.zip by clicking on the blue Download button here:


     

    Features:

    +Currently supports 18 MIPS opcodes.

    +Supports F3DEX GBI 2 RDP command detection.

     

    This tool will interpret MIPS opcodes and print C-like syntax to the console window. Results may be inaccurate until there's full opcode support.

    It will also print comments. "^_^" means that something is unnecessary to print because it sets the high 16 bits of a pointer that's shown whole further down.

     

    Usage:

    1. Click and drag a file into decompile.exe. The engine file for OoT debug (code) is included for testing purposes. ***IT MUST BE AN EXTRACTED FILE THAT YOU KNOW THE PROGRAM COUNTER FOR. NOT A WHOLE ROM.**

    2. It will ask for a program counter. For the included file, type 1ce60 and hit Enter.

    3. It will ask for a function offset. Type one and hit Enter.

     

    There will be future updates to this tool. Source code is included.

  4. Off the top of my head, I'm banned from GameFAQs, GBAtemp and its IRC channel, IGN, and banned from posting to the gallery on Imgur.

     

    I'm Z-lined from BadnikNET, and banned from these other channels on these networks:

     

    #3dsdev on EFnet

    #n64dev on EFnet

    #citra on Freenode

    #.blank on Rizon

     

    I walked out on #dolphin-emu on Freenode when I learned two admins are Social Justice Warriors that have a problem with screenshots of Zero Suit Samus' butt in Smash 4.

     

    I wouldn't have it any other way. All of those places betrayed me or held me back. My primary Internet home is here now:

     


     

    I'm getting back into reverse engineering and am working on an individual function decompiler for N64 ROMs that works as well as how much context I'm baking into it.
    • Like 1
  5. The name is inspired by xdaniel's libbadRDP. All it does so far (from command line) is get past the bootstrap for Super Mario 64 (J) [!].

     

    badn64.h: https://pastebin.com/xBwTzH9d

     

    badn64.c: https://pastebin.com/prn1DCvM

     

         32175 a4000170: jumped inside function (a4000778)
         32206 a40007ec:  jumped inside function (a4000880)
         32215 a40008a0:   jumped inside function (a400090c)
         32220 a4000918:    jumped inside function (a4000a40)
         32252 a4000920:    returned from function
         32917 a40008a8:   returned from function
         32934 a40008e8:   jumped inside function (a4000980)
         32947 a40009b8:    jumped inside function (a4000a40)
         32983 a40009c0:    returned from function
         32985 a40009c0:    jumped inside function (a4000ad0)
         33024 a40009c8:    returned from function
         33026 a40009c8:    jumped inside function (a4000ad0)
         33065 a40009d0:    returned from function
         33083 a40008f0:   returned from function
         33088 a40007f4:  returned from function
         33094 a40007ec:  jumped inside function (a4000880)
         33103 a40008a0:   jumped inside function (a400090c)
         33108 a4000918:    jumped inside function (a4000a40)
         33140 a4000920:    returned from function
         33805 a40008a8:   returned from function
         33822 a40008e8:   jumped inside function (a4000980)
         33835 a40009b8:    jumped inside function (a4000a40)
         33871 a40009c0:    returned from function
         33873 a40009c0:    jumped inside function (a4000ad0)
         33912 a40009c8:    returned from function
         33914 a40009c8:    jumped inside function (a4000ad0)
         33953 a40009d0:    returned from function
         33971 a40008f0:   returned from function
         33976 a40007f4:  returned from function
         33982 a40007ec:  jumped inside function (a4000880)
         33991 a40008a0:   jumped inside function (a400090c)
         33996 a4000918:    jumped inside function (a4000a40)
         34028 a4000920:    returned from function
         34693 a40008a8:   returned from function
         34710 a40008e8:   jumped inside function (a4000980)
         34723 a40009b8:    jumped inside function (a4000a40)
         34759 a40009c0:    returned from function
         34761 a40009c0:    jumped inside function (a4000ad0)
         34800 a40009c8:    returned from function
         34802 a40009c8:    jumped inside function (a4000ad0)
         34841 a40009d0:    returned from function
         34859 a40008f0:   returned from function
         34864 a40007f4:  returned from function
         34870 a40007ec:  jumped inside function (a4000880)
         34879 a40008a0:   jumped inside function (a400090c)
         34884 a4000918:    jumped inside function (a4000a40)
         34916 a4000920:    returned from function
         35581 a40008a8:   returned from function
         35598 a40008e8:   jumped inside function (a4000980)
         35611 a40009b8:    jumped inside function (a4000a40)
         35647 a40009c0:    returned from function
         35649 a40009c0:    jumped inside function (a4000ad0)
         35688 a40009c8:    returned from function
         35690 a40009c8:    jumped inside function (a4000ad0)
         35729 a40009d0:    returned from function
         35747 a40008f0:   returned from function
         35752 a40007f4:  returned from function
         35759 a4000808:  jumped inside function (a4000a40)
         35795 a4000810:  returned from function
         35823 a4000178: returned from function
         35842 a40002ec: jumped inside function (a4000a40)
         35878 a40002f4: returned from function
       5782558
    r0: 00000000 at: a4600000 v0: 000b5080 v1: 00000000
    a0: 000b5080 a1: 0e4c728e a2: 0534d9ac a3: 4eaa3d0e
    t0: a4002000 t1: 80246000 t2: f8cb7f9e t3: b0000000
    t4: b9e50493 t5: 00000020 t6: f6870d10 t7: c8aff19b
    s0: 00000400 s1: a3f08000 s2: 00000000 s3: 00000000
    s4: 00000001 s5: 00000000 s6: 0000003f s7: 00000000
    t8: cd9078b7 t9: 8368dffa k0: a4300000 k1: 00000001
    gp: 00000008 sp: a4001ff0 fp: a4001f90 ra: a40002f4
    pc: 80246000
    Press any key to continue . . .

     

    • Like 2
  6. Sources and quotes:

     

    http://imgur.com/gallery/9oBOUjA

     

    I received 2 N64 Development Disks - One Titled è£ - URA

     

    9oBOUjA.jpg

     

     


    So this won't mean much to many, but The Legend of Zelda - Ocarina of Time was in part being developed for the Nintendo 64 Disk Drive, something that never saw light here in North America. In the code, you can find info about the disk drive and that is about all; the missing part was the disk. Generally, these things are destroyed or probably sitting in Miyamoto's house, collecting dust, 'cause dats how Nintendo roll'.

     

    Today, I have received that holy grail of my video game collecting, and perhaps everyone else in the world. This is a culmination of 15 years searching, tracking down developers, programmers, hell even mail clerks, to find information. When all was for naught, a designer who worked with Eiji Aonuma gave me a gift. Gave means I paid for, handsomely. So, just thought I would share this wonderful, wonderful gift to the world! Time to load this in the disk drive and pop a video up

     

    http://forum.pj64-emu.com/showthread.php?t=5195

     

     

    After talking to a few people on Reddit and getting in touch with Luigiblood (bsxproj.superfamicom.org/64dd/dump/) - I have decided not to play with these carts anymore, and have someone professionally look at these. I received two dev carts and two blue disks, one is a LOZ OOT early beta, and the other looks like an early Majora's Mask. OOT has no music and a different opening and sprite of Link, says Copyright 1997, but crashes right away. The Majora starts with the desert temple theme-ish music and has a large moon in the sky, which then pans down to a large fire and Navi pulling child Link backwards and then goes black. It then proceeds to freeze as well.

     

    OOT doesn't go anywhere, and I've tried a few times, and it's awesome. The Majora's I've plugged away at a bit, and a debug screen came up, but that's as far as it goes. It should be noted, I do not have a dev DD, only a regular Japanese one. I am posting a few videos and more pictures to my Imgur. Enjoy and if you have any ideas, let me know! We are trying to get these dumped without any more risk of damage. It's been suggested that this could be close to raw C, and compiled only to go on the cart to test, and that would be the major hope!

     

    <Seru-kun> "The game loads up to a title screen like I've never seen (Distorted colors, no music, strange looking Link, no Epona) and says copyright 1997. Upon start it comes to a debug BUT the disk just spins and an error comes up!"

     

    Now we wait for the ROM to tear apart...

    • Like 7
  7. xdan, here's my latest notes on animations:

     

    Any sample values provided are as they appear in little endian. This also focuses on the MM3D spec, which is a tad different than the OoT3D one, just like model data.

     

    CTR Skeletal Animation Binary (*.csab)

     

    0x0: magic "csab"

    0x4: file size (u32)

    0x8: version (u32, 05000000 = MM3D) (OoT3D is 03000000)

    0xC: always 00000000? (u32)

    0x10: 3 unknown floats?

    0x1C: always 01000000? (u32)

    0x20: animation node (anod) base (u32)

    0x24: padding

    0x34: frame count, minus 1 (u32)

    0x38: unknown property (u32, seen 01000000 and 00000000)

    0x3C: anod count (u32)

    0x40: bone count (u32)

     

     

    0x44: bone table (2*bone count in size)

     

    Contains signed shorts (16-bit), if set to -1 (FFFF) the bone has no anod, else is the anod number for the bone.

    2 bytes of padding after if the bone count is odd-numbered.

     

     

    0x(varies): anod table (4*anod count in size)

     

    Immediately after the bone table (+padding noted above), contains relative u32 pointers (to the anod base) to each anod.

     

     

    anod:

     

    0x0: magic "anod"

    0x4: property 1 (u16, if set to 0000, the anod is empty, AKA same as a bone not having an anod. Weird.)

    0x6: property 2 (u16, unknown purpose)

     

    0x8: transformation table

     

    Contains 6 u16 pointers, relative to the start of the anod:

     

    +0x0: X rotations

    +0x2: Y rotations

    +0x4: Z rotations

    +0x6: X translations

    +0x8: Y translations

    +0xA: Z translations

     

    If any of these are set to 0, the transformation is locked. (0 for all frames)

     

    0x14: 8 bytes of padding

     

     

    Rotation/translation data:

     

    +0x0: unknown property (u16)

    +0x2: unknown property (u16)

    +0x4: unknown float

    +0x8: unknown float

    +0xC: rotation/translation for each frame (u16) (rotations need to be converted to degrees the same way as N64 Zeldas)

     

     

    Hope something comes of this! I want some kind of video or GIF demonstrating an animation if this works, even if it's just the skeleton.  ;)

     

    Also, any of Link's animations have a larger bone table than he has bones, for some reason. More research will be needed for Link's special case.

    • Like 1
  8. And here's a GAR extractor I wrote in C.

    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
        FILE *gar, *out;
        unsigned int files,len,off,path,sizes,y;
        unsigned short count,x;
        char longname[97], shortname[65], check=1;
        gar=fopen(argv[1],"rb");
        fseek(gar,0xA,SEEK_SET);
        count=(unsigned short)(fgetc(gar)|(fgetc(gar)<<8));
        fseek(gar,4,SEEK_CUR);
        sizes=(unsigned int)(fgetc(gar)|(fgetc(gar)<<8)|(fgetc(gar)<<16)|(fgetc(gar)<<24));
        files=(unsigned int)(fgetc(gar)|(fgetc(gar)<<8)|(fgetc(gar)<<16)|(fgetc(gar)<<24));
        for(x=0;x<count;x+=1)
        {
            fseek(gar,files+4*x,SEEK_SET);
            off=(unsigned int)(fgetc(gar)|(fgetc(gar)<<8)|(fgetc(gar)<<16)|(fgetc(gar)<<24));
            fseek(gar,sizes+12*x,SEEK_SET);
            len=(unsigned int)(fgetc(gar)|(fgetc(gar)<<8)|(fgetc(gar)<<16)|(fgetc(gar)<<24));
            fseek(gar,4,SEEK_CUR);
            path=(unsigned int)(fgetc(gar)|(fgetc(gar)<<8)|(fgetc(gar)<<16)|(fgetc(gar)<<24));
            fseek(gar,path,SEEK_SET);
            while(check!=0){check=fgetc(gar);}
            while(check!=0x2F)
            {
                fseek(gar,-2,SEEK_CUR);
                check=fgetc(gar);
            }
            fgets(shortname,65,gar);
            fseek(gar,path,SEEK_SET);
            fgets(longname,97,gar);
            out=fopen(shortname,"wb");
            printf("Extracting file %d...\n%s\n",x,longname);
            fseek(gar,off,SEEK_SET);
            for(y=0;y<len;y+=1){fputc(fgetc(gar),out);}
            fclose(out);
        }
        return 0;
    }
    
    
    • Like 1
  9. So, I discovered that it's incredibly easy to dump games via Gateway's Launcher.dat and generate xorpads to decrypt them via another homebrew Launcher.dat and took some pics and a video to celebrate.  ^_^

     

    Shown is the dumping of Majora's Mask 3D...

     

    pnsfezy.jpg

     

    2vG8GBy.jpg

     

    • Like 1
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.