Public feed #380603

Someone

public text v1 · immutable
Raw Edit
·published 2007-03-04 04:58 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace nbhgen
{
    public class NBH
    {
        /* some small byte helpers i used while reving it */
        public class ByteHelpers
        {
            public static string ByteArrayToString(byte[] b_in)
            {
                string temp = "";

                foreach (byte b in b_in)
                    temp += (char)b;
                return temp;
            }
            public static string ByteArrayToHexString(byte[] b_in)
            {
                string temp = "";

                foreach (byte b in b_in)
                    temp += string.Format("{0:x2} ", b);

                return temp;
            }
            public static int LongIntToDecimal(byte[] b_in)
            {
                return b_in[0] + b_in[1] * 256 + b_in[2] * 65536 + b_in[3] * 16777216;
            }
        }
        
        public class NBHRom
        {
            public class NBHBlock
            {
                public byte[] b_blocksize;
                public byte[] b_signaturesize;
                public int b_flag;
                public byte[] b_block;
                public byte[] b_signature;

                private FileStream fs_nbhstream;

                public NBHBlock(FileStream nbh)
                {
                    fs_nbhstream = nbh;

                    b_blocksize = new byte[4];
                    b_signaturesize = new byte[4];
                    b_flag = new byte();
                }

                public void ReadBlock()
                {
                    /*
                     * block:
                     * 
                     * [ 4byte blocksize ][4byte signature][1byte flag][ x-bytes block][ x-bytes signature]
                     * the last block has flag == 2, and only contains a signature, probably for the whole file. 
                     */
                    fs_nbhstream.Read(b_blocksize, 0, 4);
                    fs_nbhstream.Read(b_signaturesize, 0, 4);
                    b_flag = fs_nbhstream.ReadByte();


                    int blocksize = ByteHelpers.LongIntToDecimal(b_blocksize);
                    int signaturesize = ByteHelpers.LongIntToDecimal(b_blocksize);

                    /*
                    Console.WriteLine("blocksize: {0} signaturesize: {1} flag: {2}",
                        blocksize, signaturesize, b_flag);
                    */

                    b_block = new byte[blocksize];
                    fs_nbhstream.Read(b_block, 0, blocksize);

                    b_signature = new byte[signaturesize];
                    fs_nbhstream.Read(b_signature, 0, signaturesize);
                }
            }

            public delegate void debugPrint(string function, params object[] arg);
            debugPrint DebugPrint;
            string s_fileIn;

            public NBHRom ( string s_filein, debugPrint debugprint )
            {
                s_fileIn = s_filein;
                DebugPrint = debugprint;
            }

            /* convert a rom to the rbh format, the rbh format is the nbh format without the signatures and the block headers */
            public void ConvertToRBH( string s_fileout )
            {
                FileStream nbh = new FileStream( s_fileIn, FileMode.Open, FileAccess.Read);

                byte[] b_headercode = new byte[23]; /* according to xda-dev wiki 7bytes filetype+16 bytes garbage */
                nbh.Read(b_headercode, 0, b_headercode.Length);
                DebugPrint("headercode: {0}", ByteHelpers.ByteArrayToString(b_headercode));

                FileStream rnbout = new FileStream(s_fileout, FileMode.Create, FileAccess.Write);

                /* write the raw RNB format */
                NBHBlock nbhblock = new NBHBlock(nbh);
                do
                {
                    nbhblock.ReadBlock();
                    rnbout.Write(nbhblock.b_block, 0, nbhblock.b_block.Length);
                }
                while (nbhblock.b_flag != 2); /* flag 2 = last block */

                rnbout.Close();
                nbh.Close();
            }
        }
        public class NBRom
        {
            /* image types, also used for filenames */
            public enum NBImageType
            {
                IPL = 0x100,
                SPL = 0x200,
                Radio = 0x300,
                Windows = 0x400,
                PrimarySplash = 0x600,
                SecondarySplash = 0x601,
                ExtendedRom = 0x700
            }
            public NBImageType ImageType;
            public long offset;
            public long length;

            public NBRom(int i_type)
            {
                ImageType = (NBImageType)i_type;
            }
        }
        public class RNBRom
        {
            public string s_cid;
            public string s_language;
            public string s_version;
            public string s_device;
            public string s_imagetype;

            FileStream fs_rbh;
            List<NBRom> nbr_list;

            public delegate void debugPrint(string function, params object[] arg);
            debugPrint DebugPrint;

            public RNBRom(debugPrint myprint)
            {
                DebugPrint = myprint;
                nbr_list = new List<NBRom>();
            }
            public void LoadRom(string s_filename)
            {
                if (fs_rbh != null)
                    throw new IOException("please close first romhandle prior to opening another with the same object");

                fs_rbh = new FileStream(s_filename, FileMode.Open, FileAccess.Read);

                /* read rom type */
                byte[] b_imagetype = new byte[32];
                fs_rbh.Read(b_imagetype, 0, b_imagetype.Length);
                s_imagetype = System.Text.Encoding.UTF32.GetString(b_imagetype);
                DebugPrint("imagetype: {0}", s_imagetype);

                /* read device type */
                fs_rbh.Read(b_imagetype, 0, b_imagetype.Length);
                s_device = System.Text.Encoding.ASCII.GetString(b_imagetype);
                DebugPrint("devicetype: {0}", s_device);

                /* read rom types */
                byte[] b_romtype = new byte[4];
                for (int i = 0; i < 128; i += 4)
                {
                    fs_rbh.Read(b_romtype, 0, b_romtype.Length);

                    int i_romtype = ByteHelpers.LongIntToDecimal(b_romtype);

                    if (i_romtype != 0)
                    {
                        NBRom nbr_rom = new NBRom(i_romtype);
                        nbr_list.Add(nbr_rom);
                        DebugPrint("found rom: {0} (0x{1:x2})", nbr_rom.ImageType, (int)nbr_rom.ImageType);
                    }
                }
                DebugPrint("numer of roms in nbh: {0}", nbr_list.Count);

                /* read rom offests */
                byte[] b_romoffset = new byte[4];
                for (int i = 0; i < 128; i += 4)
                {
                    fs_rbh.Read(b_romoffset, 0, b_romoffset.Length);

                    int i_offset = ByteHelpers.LongIntToDecimal(b_romoffset);
                    int rom_no = i / 4;

                    if (i_offset != 0 && rom_no < nbr_list.Count)
                    {
                        nbr_list[rom_no].offset = i_offset;
                        DebugPrint("found offset: {0} (0x{1:x2})", nbr_list[rom_no].ImageType, (int)nbr_list[rom_no].offset);
                    }
                }

                /* read rom lengths */
                byte[] b_romlength = new byte[4];
                for (int i = 0; i < 128; i += 4)
                {
                    fs_rbh.Read(b_romlength, 0, b_romlength.Length);

                    int i_length = ByteHelpers.LongIntToDecimal(b_romlength);
                    int rom_no = i / 4;

                    if (i_length != 0 && rom_no < nbr_list.Count)
                    {
                        nbr_list[rom_no].length = i_length;
                        DebugPrint("found length: {0} (0x{1:x2})", nbr_list[rom_no].ImageType, (int)nbr_list[rom_no].length);
                    }
                }
            }
            public void CloseRom()
            {
                nbr_list = new List<NBRom>();
                fs_rbh.Close();
                fs_rbh = null;
            }
            public void ExtractNBH(string s_outdir)
            {
                if (fs_rbh == null)
                    throw new Exception("no filehandle to rbh rom");
                if (nbr_list.Count == 0)
                    throw new Exception("please load the rom prior to extracting it");

                if (s_outdir.EndsWith("\\") == false )
                    s_outdir += "\\";

                for (int i = 0; i < nbr_list.Count; i++)
                {
                    FileStream fs_out = new FileStream(s_outdir + nbr_list[i].ImageType + ".nb", FileMode.Create, FileAccess.Write);

                    fs_rbh.Seek(nbr_list[i].offset, SeekOrigin.Begin);
                    
                    int peeksize = 1024;
                    for (long bytesleft = nbr_list[i].length; bytesleft >= 0; bytesleft -= peeksize)
                    {
                        byte[] bytes;

                        if (bytesleft < peeksize)
                        {
                            bytes = new byte[bytesleft];
                            fs_rbh.Read(bytes, 0, bytes.Length);
                            fs_out.Write(bytes, 0, bytes.Length);
                            break;
                        }
                        bytes = new byte[peeksize];
                        fs_rbh.Read(bytes, 0, bytes.Length);
                        fs_out.Write(bytes, 0, bytes.Length);
                    }
                    fs_out.Close();
                }
            }
        }

    }
    class Program
    {
       static void Main(string[] args)
       {
#if false
        
           /* do this */
           NBH.NBHRom nbhrom = new NBH.NBHRom("..\\rom\\Ruu_signed.nbh", Console.WriteLine);
           nbhrom.ConvertToRBH("ruu.bin");
#else
           /* then this */
           NBH.RNBRom rnbrom = new NBH.RNBRom(Console.WriteLine);

           rnbrom.LoadRom("..\\rom\\ruu.bin");
           rnbrom.ExtractNBH("..\\rom");
           rnbrom.CloseRom();
#endif 
            

        }
    }
}