private BinaryReader getBinaryReader(Stream s) { return(BigEndianBinaryReader.GetEndianSpecificBinaryReader(s, isBigEndian)); }
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(); }
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); } }