/// <summary> /// Returns the position of the given string id. /// </summary> /// <param name="hashId"></param> /// <param name="target_occurance">1 for the first occurance</param> /// <returns></returns> public int GetStringLoc(UInt32 hashId, int target_occurance) { int stringLoc = (int)BodyStart; int occurance = 0; UInt32 currentHash = 0; while (true) { currentHash = BinUtils.GetNumberAtLocation(stringLoc, mData); if (currentHash == hashId) { occurance++; if (occurance == target_occurance) { break; } } stringLoc = NextStringLoc(stringLoc); if (stringLoc + 10 > mData.Count) { return(-1); } } return(stringLoc); }
private void AddBodySize(int size) { uint bodySize = BinUtils.GetNumberAtLocation(BodySizeLoc, mData); bodySize = (uint)(bodySize + size); BinUtils.WriteNumberAtLocation(BodySizeLoc, bodySize, mData); }
private uint ReadNumber() { uint retVal = BinUtils.GetNumberAtLocation(mCurrentPos, mData); ConsumeBytes(4); return(retVal); }
public string GetSummary() { string retVal = string.Format( "Name: {0}\nType: {1}\nStart: 0x{2:x}\nLength: 0x{3:x}\nSize: {4:n} kb", Name, Type, Start, Length, (Length / 1024.0)); long loc = BinUtils.GetLocationOfGivenBytes(0, ASCIIEncoding.ASCII.GetBytes("INFO"), Data, 80); if (loc > -1) { loc += 4; // advance to position to read uint info = BinUtils.GetNumberAtLocation(loc, Data); retVal += String.Format("\nINFO: 0x{0:x8}", info); } if (Name.StartsWith("0x")) { uint hash = UInt32.Parse(Name.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier); string unHashed = HashHelper.GetStringFromHash(hash); if (unHashed != null) { retVal += string.Format("hash lookup for: {0}>'{1}' \n", Name, unHashed); } else { retVal += "Unknown name hash\n"; } } return(retVal); }
private string ReadName() { string retVal = null; if (BinUtils.BinCompare(NAME, mData, mCurrentPos)) { ConsumeBytes(4); uint nameLen = BinUtils.GetNumberAtLocation(mCurrentPos, mData); ConsumeBytes(4); retVal = ReadString((int)nameLen); } return(retVal); }
private string ReadNameHash() { string retVal = null; if (BinUtils.BinCompare(NAME, mData, mCurrentPos)) { ConsumeBytes(4); uint nameLen = BinUtils.GetNumberAtLocation(mCurrentPos, mData); ConsumeBytes(4); uint nameHash = BinUtils.GetNumberAtLocation(mCurrentPos, mData); ConsumeBytes(4); retVal = String.Format("0x{0:x}", nameHash); } return(retVal); }
public byte[] GetBodyData() { byte[] BodyBytes = { 0x42, 0x4f, 0x44, 0x59 }; long loc = BinUtils.GetLocationOfGivenBytes(0, BodyBytes, Data, 80); if (loc > -1) { uint bodyLen = BinUtils.GetNumberAtLocation(loc + 4, Data); long bodyStart = loc + 8; long bodyEnd = loc + 8 + bodyLen; byte[] bodyData = new byte[bodyLen]; Array.Copy(Data, bodyStart, bodyData, 0, bodyLen); return(bodyData); } return(null); }
/// <summary> /// Places the string with the given hashid into the stringbuilder passed in. /// String ids can be present multiple times. This will return the last occurance /// of the string. /// </summary> /// <param name="hashId"></param> /// <param name="sb">string will be added to the builder</param> /// <returns>The location of the string id, -1 if not found </returns> public int GetString(UInt32 hashId, StringBuilder sb) { int stringLoc = (int)BodyStart; int occurance = 0; int target_occurance = 1; if (mStringSet2 != null && mStringSet2.ContainsKey(hashId)) { target_occurance++; } UInt32 currentHash = 0; while (true) { currentHash = BinUtils.GetNumberAtLocation(stringLoc, mData); if (currentHash == hashId) { occurance++; if (occurance == target_occurance) { break; } } stringLoc = NextStringLoc(stringLoc); if (stringLoc + 10 > mData.Count) { return(-1); } } UInt16 sz = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData); int byteStart = stringLoc + 6; int byteEnd = stringLoc + sz - 1; char current = '\0'; for (int i = byteStart; i < byteEnd; i += 2) { current = (char)BinUtils.Get2ByteNumberAtLocation(i, mData); if (current != '\0') { sb.Append(current); } } return(stringLoc); }
public string GetAllStrings() { /*bool debug = true; * UInt16 prevSz = 0; * int prevLoc = 0; debug stuff*/ mStringSet = new Dictionary <uint, string>(2000); mStringSet2 = new Dictionary <uint, string>(200); StringBuilder cur = new StringBuilder(80); StringBuilder sb = new StringBuilder(50 * 3200); int stringLoc = (int)BodyStart; UInt32 currentHash = 0; UInt16 sz = 0; int byteStart = 0; int byteEnd = 0; char current = '\0'; string stringId = ""; while ((currentHash = BinUtils.GetNumberAtLocation(stringLoc, mData)) > 0) { stringId = HashHelper.GetStringFromHash(currentHash); if (stringId == null) { stringId = String.Format("0x{0:x6}", currentHash); } sb.Append(stringId); sb.Append("=\""); sz = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData); //Console.WriteLine("GetAllStrings: Size={0}", sz); byteStart = stringLoc + 6; byteEnd = stringLoc + sz - 1; current = '\0'; for (int i = byteStart; i < byteEnd; i += 2) { current = (char)BinUtils.Get2ByteNumberAtLocation(i, mData); if (current == '"') { sb.Append("\\\""); // escape the quote cur.Append("\\\""); } else if (current == '\\') { sb.Append("\\\\"); // escape the escape! cur.Append("\\\\"); } else if (current != '\0') { sb.Append(current); cur.Append(current); } } if (currentHash != 0xffffffff) { if (mStringSet.ContainsKey(currentHash)) { if (!mStringSet2.ContainsKey(currentHash)) { mStringSet2.Add(currentHash, cur.ToString()); } else { Console.WriteLine("Sorry, not showing 3+ instances of string 0x{0:x}:'{1}'", currentHash, cur.ToString()); } //Console.WriteLine("Error! key 0x{0:x} ({1}) already exists as: {2}", currentHash, stringId, mStringSet[currentHash]); //Console.WriteLine("Cannot add {0}:{1}",stringId, cur.ToString() ); } else { mStringSet.Add(currentHash, cur.ToString()); } } /*if (debug && cur.Length == 0) * Console.WriteLine("MT, sz:0x{0:x2} pos:0x{1:x6} prevSz:0x{2:x2} prevPos:0x{3:x6}", sz, stringLoc, prevSz, prevLoc); * prevLoc = stringLoc; // TODO remove these 2 after debugging * prevSz = sz; */ cur.Length = 0; // clear sb.Append("\"\n"); stringLoc = NextStringLoc(stringLoc); if (stringLoc + 10 > mData.Count) // for a string you need minimum 4 bytes for the hash, 2 for size and 4 for nulls { break; } } //Console.WriteLine("mStringSet2.Count:{0}",mStringSet2.Count); return(sb.ToString()); }
private string PeekName(uint location, string chunkType) { string name = ""; if (chunkType == "plan") { string lvlName = GetLvlFileName(); return(lvlName.Replace(".lvl", "")); } long loc = 0; if (chunkType == "lvl_") { uint hash = BinUtils.GetNumberAtLocation(location + 8, mData); string str = HashHelper.GetStringFromHash(hash); if (str != null) { name = str; } else { name = "0x" + hash.ToString("X"); } } if (chunkType == "entc") { loc = BinUtils.GetLocationOfGivenBytes(location, ASCIIEncoding.ASCII.GetBytes("TYPE"), mData, 80); } else { loc = BinUtils.GetLocationOfGivenBytes(location, ASCIIEncoding.ASCII.GetBytes("NAME"), mData, 80); } if (loc > -1) { int nameLen = mData[(int)loc + 4] - 1; // -1 for null byte if (loc > 0) { name = Encoding.ASCII.GetString(mData, (int)loc + 8, (int)nameLen); int zeroTest = name.IndexOf('\0'); if (zeroTest > -1) { name = name.Substring(0, zeroTest); } } List <string> hexNameTypes = new List <string> { "mcfg", "sanm", "fx__" }; if (nameLen == 3 && (hexNameTypes.IndexOf(chunkType) > -1 || HasBadCharacters(name)))//sf__ { uint hash = BinUtils.GetNumberAtLocation(loc + 8, mData); string str = HashHelper.GetStringFromHash(hash); if (str != null) { name = str; } else { name = String.Format("0x{0:X}", hash); } } } return(name); }
private uint PeekNumber(uint location) { uint retVal = BinUtils.GetNumberAtLocation(location, mData); return(retVal); }