SEGA NN Framework *.BNK

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

SEGA NN Framework *.BNK

Post by LolHacksRule »

So the Transformers Human Alliance arcade game was finally dumped and I wanted to datamine it, but the majority (3GB!) of the game data is in 153 BNK files. They use a unique header (most likely its own file) of IZCA (? ? Compressed/Container Archive? Chunk Array) and they end with a footer of EOFC (End Of File Container? Chunk) before a bunch of null bytes, heck some BNK files have multiple IZCA archives in the IZCA archives in them! offzip -s/a doesn't really help on them. Can someone crack 'em so extraction is possible? Will upload samples soon. If there's other games using this, this page will be updated to relate to multiple. DBLK (DATABLOCK)[SCNE], models (ZNO/ZNM), sounds (extensionless ADX/AHXs?), texts (MFNT? HNFN?, BBTF?, MBUN? [not mentioned in EXE]?), textures (DDS, DDM DSFN [DeSign File Number?], HTEX) Games with this appear to run off the NN library and use the Sega CANVAS engine for graphics. CriWare packs (CPKs) UPDATE: https://drive.google.com/open?id=1MwbSr ... OwrXl3pCFc, I think H in names means Hydro or Hyuga, probably that one and I to be Izumi. This plugin set for Blender could help https://github.com/Argx2121/Sega_NN_tools.

Code: Select all

I tried
MAIN ARCHIVE:
METADATA (32bytes):
4bytes: Header (IZCA, 495A4341)   
2-4bytes: Filesize for container data (little endian)
1byte: 10 (appears to always be 10 idk why)
7bytes: zero
1byte: 01 (appears to always be 01 idk why)
7bytes: zero
1byte: 20 (appears to always be 20 idk why)
3bytes: zero
1byte: File count?
BEYOND (Archive data):
TBC
FILE ARCHIVE END (16bytes):
4bytes: EOFC (454F4643)
4bytes: zero
1byte: 10 (appears to always be 10 idk why)
7bytes: zero

SUB-ARCHIVE (Subtitle archives use this):
METADATA (16bytes):
4bytes: Header (IZCA, 495A4341)
2-4bytes: Filesize for container data (little endian)
1byte: 14 (appears to always be 14 idk why)
7bytes: zero
1byte: 01 (appears to always be 01 idk why)
7bytes: zero
1byte: 20 (appears to always be 20 idk why)
3bytes: zero
1byte: File count?


Other pages regarding IZCA extraction:
viewtopic.php?t=679
viewtopic.php?f=9&t=11711
Last edited by LolHacksRule on Tue Jan 19, 2021 6:19 pm, edited 7 times in total.
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Transformers Human Alliance (Sega, Arcade, *.BNK)

Post by chrrox »

sounds like same engine as valkyria chronicles.
https://github.com/gomtuu/import_valkyr ... _init__.py
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

Re: Transformers Human Alliance (Sega, Arcade, *.BNK)

Post by LolHacksRule »

Thanks so much, that's not it in these archives tho... There's some more. But how would I extract the BNKs?
LokiReborn
Posts: 190
Joined: Fri Aug 26, 2016 3:11 pm

Re: Transformers Human Alliance (Sega, Arcade, *.BNK)

Post by LokiReborn »

LolHacksRule wrote:Thanks so much, that's not it in these archives tho... There's some more. But how would I extract the BNKs?

The container format is super simple

Code: Select all

49 5A 43 41 //Magic
DC B7 00 00 //Container Size
10 00 00 00
00 00 00 00
01 00 00 00
00 00 00 00
20 00 00 00
03 00 00 00 //Count
   2C 00 00 00 //Start offsets of files (not relative)
   8C 33 00 00
   BC 36 00 00
---- Will be first file
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

Re: SEGA Modern Arcade *.BNK

Post by LolHacksRule »

Thanks so much
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

Re: Transformers Human Alliance (Sega, Arcade, *.BNK)

Post by LolHacksRule »

chrrox wrote:sounds like same engine as valkyria chronicles.
https://github.com/gomtuu/import_valkyr ... _init__.py

Thanks but I'm not really one who looks at models...
SporeAltair
Posts: 7
Joined: Sun Dec 10, 2017 7:17 pm

Re: SEGA NN Framework *.BNK

Post by SporeAltair »

Why aren't all files completely unpacked? for example, from Starscream's model, I can get only his weapon.
From a 60MB file, I got 9MB.
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

Re: SEGA NN Framework *.BNK

Post by LolHacksRule »

The 8 DDS files are consuming the majority of the said file (55MB), that's not a problem with the script, it just excludes extraction of files that are not models. Dragon Unpacker's HyperRipper or RavioliGameTools RExplorer can help find and extract them (without proper names).
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

Re: SEGA NN Framework *.BNK

Post by LolHacksRule »

Bored so I made this WIP script! Upon looking at the exe, IZCA likely stands for IZumi Chunk Array.

Code: Select all

//------------------------------------------------
//--- 010 Editor v11.0.1 Binary Template
//
//      File: Sega Izumi Chunk Array (WIP!)
//    Authors: LolHacksRule
//    Version: 1
//    Purpose: Reading of IZCA format from Sega's Izumi Engine
//   Category: Modding
// File Mask: IZCA
//   ID Bytes: 495A4341
//    History:
//------------------------------------------------


LittleEndian();

typedef enum <int32> {
   NZObject = 1,
   NZTextureList = 2,
} NZIFContentType;
      
struct IZumiChunkArray {
   struct IZCAHdr {
      char      IZCAStr[4];
      int32      IZCASize;
      int32      padding[5];
        int32      cBlkCnt;
        int32      cBlkOffset[izumiContainerArchiveHdr.cBlkCnt];
        //ubyte     Content[IZCASize];
   } izumiContainerArchiveHdr<bgcolor=cBlue>;
   Printf("IZumi ContAiner\nFileSize:\nContentBlockCount:\n");
   struct ContentBlock
   {
      char blockType[4]<bgcolor=cPurple>;
      if (blockType == "HMDL")
      {
         Printf("Hydrogen Model detected.");
         struct HydrogenModelBlock
         {
            uint32 blockHdrSize;
            uint64 blockPadding;
            } hydrogenMdlHdr<bgcolor=cPurple>;
            struct ZNInfoBlock
         {
             char  znoInfBlkHdr[4];
             int32 padding; //Offset from it?
             NZIFContentType contentType; //Content type?
             int32 unkVal;
             int32 NZxToNOF0Size;
             int32 NZIFToNOF0Size;
             int32 N0F0HdrSize;
             int32 dummy;
                char  nextBlockType[4];
             if (nextBlockType == "NZOB") //NZ/ZN O/Object
             {
                 Printf("ZNO Model detected.");
                struct ZNOObjBinBlock
                {
                   int32 NZOBinSize;
                   int32 unk;
                   int32 unkVal[2];
                    } znoObjBin;
                }
                else if (nextBlockType == "NZTL") //NZ/ZN Texture List
             {
                    Printf("NZ/ZN Texture List detected.");
                struct ZNOTexListBinBlock
                {
                   uint32 blockSize;
                    int32  unk;
                        int64  nothing;
                } ZNOTexListBin;
             }
            } znInfoBlk;
        }
        else if (blockType == "HCAM") //Hydrogen Camera Surface Animation
      {
          Printf("Hydrogen CAMera detected.");
         struct HydrogenCamBlock
         {
            uint32 blockSize;
            uint64 blockPadding;
         } hydrogenCam;
      }
      else if (blockType == "HCSA") //Hydrogen Camera Surface Animation
      {
          Printf("Hydrogen Camera Surface Animation detected.");
         struct HydrogenSfcCamBlock
         {
            uint32 blockSize;
            uint64 blockPadding;
         } hydrogenSfcCam;
      }
        else if (blockType == "HNFN") //Hydrogen Font?
        {
            Printf("HydrogeN FoNt?");
            struct HydrogenFont
            {
                uint32 SubArcblockSize;
            uint64 blockPadding;
            } hGenFont;
            struct IzumiSubArc
                {
                    char    IZSubArc[4];
                    int32   IZCASubSize;
                  int32   padding;
                    int32   dummyBytes;
                  //int32   subArcBlkOffset[subArcBlkCnt];
                    struct BBTFBlk
                    {
                        char    BBTFBlkHdr[4];
                        int32   padding[5];
                        int32   unknown;
                        int32   unknown2;
                    } bbtfBlkContent;
                    struct MFNTBlock
                    {
                        char    BBTFBlkHdr[4];
                        int32   unknown;
                        int32   padding[2];
                        int32   unknown2;
                    } bbtfBlkContent;
                    char finalBlockType[4];
                    if (finalBlockType == "EOFC") //End Of File Container
                    {
                        Printf("End Of File Container");
                        struct EndOfFileContaner_HFNT
                        {
                            int32 dummy[3];
                        } EOFC_FntHdr<bgcolor=cRed>;
                    }
                } iZSubArc;
        }
      else if (blockType == "HSND") //Hydrogen SouND
      {
          Printf("Hydrogen SouND detected.");
         struct HydrogenSoundBlock
         {
            uint32 blockHdrSize;
            uint64 blockPadding;
            char   criSndBinBlk[4];
            struct CriSoundBinaryContainer
            {
               uint32 ACBFileSize;
               uint64 blockPadding;
               ubyte  ACBFile[ACBFileSize]<bgcolor=cGreen>;
               int32  dummyACBBytes;
            } criSndBin;
                char finalBlockType[4];
                if (finalBlockType == "EOFC") //End Of File Container
                {
                    Printf("End Of File Container");
                    struct EndOfFileContaner_HSND
                    {
                        int32 dummy[3];
                    } EOFC_SndHdr<bgcolor=cRed>;
                }
         } hydrogenSoundBlock<bgcolor=cYellow>;
      }
      else if (blockType == "HMAT") //Hydrogen Material Animation
        {
          Printf("Hydrogen Material detected.");      
         struct HydrogenMatBlock
         {
            uint32 blockHdrSize;
            uint64 blockPadding;
         } hydrogenMat;
      }
      //else if (blockType == "HCAM") //Hydrogen CAMera
      //else if (blockType == "HMAT") //Hydrogen MATerial
         //uint32 blockHdrSize;
         //uint64 blockPadding;
      //} hydrogenMatHdr;
   } contentBlock[izumiContainerArchiveHdr.cBlkCnt];
    char endBlockType[4]<bgcolor=cRed>;
    if (endBlockType == "EOFC") //End Of File Container
    {
        Printf("End Of File Container");
        struct EndOfFileContaner
        {
            int32 dummy[3];
        } EOFCHdr<bgcolor=cRed>;
    }
    //if (blockType == "DBLKSCNE") //Data BLoCk SCeNE
    //if (blockType == "DBLKTEXC") //Data BLoCk TEXture Compressed
   //if (blockType == "NZMA") //NZ/ZN Animation
    //else if (blockType == "HMAT") //Hydrogen MATerial
            //uint32 blockHdrSize;
            //uint64 blockPadding;
         //} hydrogenMatHdr;
} IZCAChunkBin;
Argg
Posts: 6
Joined: Sat Mar 28, 2020 6:00 pm

Re: SEGA NN Framework *.BNK

Post by Argg »

I've added partial .bnk file support - It only extracts textures and files using the nn library.
It skips extracting the files to HMDL and other in between file formats and goes directly to and zno file for convenience.
Modelwise, the normal maps in the samples were channel packed so they're ignored on import.

https://github.com/Argx2121/Sega_NN_tools/releases

If there's any issues please tell me in the discord server - I don't check here very often.

Image
LolHacksRule
Posts: 865
Joined: Fri Apr 20, 2018 12:41 am

Re: SEGA NN Framework *.BNK

Post by LolHacksRule »

Thank you, I'll try it out soon.