예제 #1
0
 private BinaryReader getBinaryReader(Stream s)
 {
     return(BigEndianBinaryReader.GetEndianSpecificBinaryReader(s, isBigEndian));
 }
예제 #2
0
        public ScriptFile(string inFilename, byte[] rawData, bool bigEndian = false)
        {
            filename = inFilename;
            int inFilesize, outFilesize;

            if (!bigEndian)
            {
                outFilesize = BitConverter.ToInt32(rawData, 0);
                inFilesize  = BitConverter.ToInt32(rawData, 4);
            }
            else
            {
                byte[] outFilesizeBytes = new byte[] { rawData[3], rawData[2], rawData[1], rawData[0] };
                byte[] inFilesizeBytes  = new byte[] { rawData[7], rawData[6], rawData[5], rawData[4] };
                if (BitConverter.ToUInt32(inFilesizeBytes, 0) > rawData.Length)
                {
                    //Stupid hack to try to fix tobitama
                    outFilesize = BitConverter.ToInt32(outFilesizeBytes.Reverse().ToArray(), 0);
                    inFilesize  = BitConverter.ToInt32(inFilesizeBytes.Reverse().ToArray(), 0);
                }
                else
                {
                    outFilesize = BitConverter.ToInt32(outFilesizeBytes, 0);
                    inFilesize  = BitConverter.ToInt32(inFilesizeBytes, 0);
                }
            }

            byte[] temp = new byte[inFilesize];
            Array.Copy(rawData, 0x1C, temp, 0, inFilesize);
            byte[] decompressed = PrsCompDecomp.Decompress(temp, (uint)outFilesize);

            MemoryStream scriptStream = new MemoryStream(decompressed);
            BinaryReader scriptReader;

            if (bigEndian)
            {
                scriptReader = new BigEndianBinaryReader(scriptStream);
            }
            else
            {
                scriptReader = new BinaryReader(scriptStream);
            }
            scriptStream.Seek(4, SeekOrigin.Begin);
            int stringListPtr    = scriptReader.ReadInt32();
            int stringListLength = scriptReader.ReadInt32();

            scriptStream.Seek(stringListPtr + 0xC, SeekOrigin.Begin);
            stringNames = new string[stringListLength / 0x20];
            for (int i = 0; i < stringNames.Length; i++)
            {
                stringNames[i] = ASCIIEncoding.UTF8.GetString(scriptReader.ReadBytes(0x20));
                stringNames[i] = stringNames[i].TrimEnd('\0');
            }
            scriptStream.Seek(0xC, SeekOrigin.Begin);

            //ArrayList subroutines = new ArrayList();
            while (scriptStream.Position < stringListPtr)
            {
                int    nextSubLoc     = scriptReader.ReadInt32() + 0xC;
                string subroutineName = ASCIIEncoding.UTF8.GetString(scriptReader.ReadBytes(0x20)).TrimEnd('\0');
                int    subLength      = scriptReader.ReadInt32();
                int    subType        = scriptReader.ReadLittleEndianInt32();
                int    locals         = scriptReader.ReadInt32();
                int    currLoc        = (int)scriptStream.Position;
                int    subEnd         = currLoc + subLength;
                scriptStream.Seek(subLength, SeekOrigin.Current);
                int[] localNums = new int[locals];
                int[] localLocs = new int[locals];
                if (subType == 0x4C)
                {
                    for (int i = 0; i < locals; i++)
                    {
                        localNums[i] = scriptReader.ReadInt32();
                        localLocs[i] = scriptReader.ReadInt32() * 4;
                    }
                }
                List <operation> operations = new List <operation>();
                List <int>       opcodeLocs = new List <int>();

                scriptStream.Seek(currLoc, SeekOrigin.Begin);
                while (scriptStream.Position < subEnd)
                {
                    opcodeLocs.Add((int)(scriptStream.Position - currLoc));
                    int currOpcode = scriptReader.ReadInt32();

                    operation tempOp = new operation();
                    if (opcodeTypes[currOpcode] == 3)
                    {
                        tempOp.floatArg = scriptReader.ReadSingle();
                    }
                    else if (opcodeTypes[currOpcode] > 1 && opcodeTypes[currOpcode] != 4 && !localLocs.Contains((int)(scriptStream.Position - currLoc)))
                    {
                        tempOp.intArg = scriptReader.ReadInt32();
                    }
                    else if (localLocs.Contains((int)(scriptStream.Position - currLoc)))
                    {
                        tempOp.strArg = stringNames[localNums[Array.IndexOf(localLocs, (int)(scriptStream.Position - currLoc))]];
                        tempOp.intArg = scriptReader.ReadInt32();
                    }
                    if (opcodeTypes[currOpcode] == 99)
                    {
                        tempOp.strArg = ASCIIEncoding.GetEncoding("shift-jis").GetString(scriptReader.ReadBytes(tempOp.intArg * 4)).TrimEnd('\0');
                    }
                    tempOp.opcode = currOpcode;
                    operations.Add(tempOp);
                }

                for (int i = 0; i < operations.Count; i++)
                {
                    if (((operation)operations[i]).opcode > 0x2B && ((operation)operations[i]).opcode < 0x2F)
                    {
                        int branchSource  = opcodeLocs[i] + 0x8;
                        int branchDestRaw = branchSource + 4 * ((operation)operations[i]).intArg;
                        for (int j = 0; j < operations.Count; j++)
                        {
                            if (branchDestRaw == opcodeLocs[j])
                            {
                                ((operation)operations[i]).intArg = j;
                                break;
                            }
                        }
                    }
                }
                subroutine tempSub = new subroutine();
                tempSub.name    = subroutineName;
                tempSub.subType = subType;
                if (subType != 0x4C)
                {
                    tempSub.miscData = locals;
                }
                else
                {
                    tempSub.miscData = -1;
                }
                tempSub.opcodes = operations;

                subroutines.Add(tempSub);
                if (nextSubLoc == 0xC)
                {
                    break;
                }
                scriptStream.Seek(nextSubLoc, SeekOrigin.Begin);
            }
            scriptReader.Close();
        }
예제 #3
0
        private void decryptNMLBToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                byte[] fileContents = File.ReadAllBytes(openFileDialog1.FileName);

                MemoryStream fileStream = new MemoryStream(fileContents);
                fileStream.Seek(3, SeekOrigin.Begin);
                byte endian = (byte)fileStream.ReadByte();
                fileStream.Seek(0, SeekOrigin.Begin);
                BinaryReader fileLoader;
                bool         bigEndian = false;
                if (endian == 0x42)
                {
                    fileLoader = new BigEndianBinaryReader(fileStream);
                    bigEndian  = true;
                }
                else
                {
                    fileLoader = new BinaryReader(fileStream);
                }

                string formatName          = new String(fileLoader.ReadChars(4));
                ushort fileVersion         = fileLoader.ReadUInt16();
                ushort chunkFilenameLength = fileLoader.ReadUInt16();
                uint   headerSize          = fileLoader.ReadUInt32();
                uint   nmllCount           = fileLoader.ReadUInt32();
                uint   uncompressedSize    = fileLoader.ReadUInt32();
                uint   compressedSize      = fileLoader.ReadUInt32();
                uint   pointerLength       = fileLoader.ReadUInt32() / 4;
                uint   blowfishKey         = fileLoader.ReadUInt32();
                uint   tmllHeaderSize      = fileLoader.ReadUInt32();
                uint   tmllDataSizeUncomp  = fileLoader.ReadUInt32();
                uint   tmllDataSizeComp    = fileLoader.ReadUInt32();
                uint   tmllCount           = fileLoader.ReadUInt32();
                uint   tmllHeaderLoc       = 0;

                uint pointerLoc = 0;

                uint size = compressedSize == 0 ? uncompressedSize : compressedSize;

                uint nmllDataLoc = (uint)((headerSize + 0x7FF) & 0xFFFFF800);
                pointerLoc = (uint)(nmllDataLoc + size + 0x7FF) & 0xFFFFF800;
                if (tmllCount > 0)
                {
                    tmllHeaderLoc = (pointerLoc + pointerLength * 4 + 0x7FF) & 0xFFFFF800;
                }

                BlewFish fish = new BlewFish(blowfishKey, bigEndian);

                for (int i = 0; i < nmllCount; i++)
                {
                    int    headerLoc = 0x40 + i * 0x60;
                    byte[] toDecrypt = new byte[0x30];
                    Array.Copy(fileContents, headerLoc, toDecrypt, 0, 0x30);
                    toDecrypt = fish.decryptBlock(toDecrypt);
                    Array.Copy(toDecrypt, 0, fileContents, headerLoc, 0x30);
                }

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < tmllCount; i++)
                {
                    uint   headerLoc = (uint)(tmllHeaderLoc + 0x30 + i * 0x60);
                    byte[] toDecrypt = new byte[0x30];
                    Array.Copy(fileContents, headerLoc, toDecrypt, 0, 0x30);
                    toDecrypt = fish.decryptBlock(toDecrypt);
                    Array.Copy(toDecrypt, 0, fileContents, headerLoc, 0x30);

                    sb.Append(ASCIIEncoding.ASCII.GetString(toDecrypt, 0, 0x20).Split('\0')[0] + "\t");
                    //sb.Append(BitConverter.ToUInt16(fileContents, (int)(headerLoc + 0x4C)) + "\t");
                    //sb.Append(BitConverter.ToUInt16(fileContents, (int)(headerLoc + 0x4E)) + "\n");
                }

                fileStream.Seek(nmllDataLoc, SeekOrigin.Begin);
                byte[] encryptedNmll    = fileLoader.ReadBytes((int)size);
                byte[] decryptedNmll    = fish.decryptBlock(encryptedNmll);
                byte[] decompressedNmll = compressedSize != 0 ? PrsCompDecomp.Decompress(decryptedNmll, uncompressedSize) : decryptedNmll;

                File.WriteAllText(openFileDialog1.FileName + ".tml.list", sb.ToString());
                File.WriteAllBytes(openFileDialog1.FileName + ".decrypt", fileContents);
                File.WriteAllBytes(openFileDialog1.FileName + ".encryptNmll", encryptedNmll);
                File.WriteAllBytes(openFileDialog1.FileName + ".decryptNmll", decryptedNmll);
                File.WriteAllBytes(openFileDialog1.FileName + ".decompressNmll", decompressedNmll);
            }
        }