Public feed
#380603
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
}
}
}