コード例 #1
0
        private int NextStringLoc(int stringLoc)
        {
            UInt16 sz     = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData);
            int    retVal = sz + stringLoc;

            return(retVal);
        }
コード例 #2
0
        /// <summary>
        /// String size seem to be always be a multiple of 4. With 4-6 'zero bytes' at the end
        /// </summary>
        /// <param name="stringId">the id of the string to modify</param>
        /// <param name="newValue">the new value</param>
        /// <returns>The string location, -1 if not found</returns>
        public int SetString(string stringId, string newValue)
        {
            uint          hashId    = GetHashId(stringId);
            StringBuilder sb        = new StringBuilder(20);
            int           stringLoc = GetString(hashId, sb);
            string        prevValue = sb.ToString();

            if (stringLoc > 0 && prevValue != newValue)
            {
                UInt32 oldSz = BinUtils.Get2ByteNumberAtLocation(stringLoc + 4, mData);
                UInt16 sz    = (UInt16)((newValue.Length * 2) + 2 + 4 + 4); // 2:size info 4:hashId 4 min zero bytes
                if (sz % 4 != 0)
                {
                    sz += (UInt16)2;
                }
                bool sixZeros = false;
                int  diff     = (int)(sz - oldSz); //2 * (newValue.Length - prevValue.Length);
                if (diff % 4 != 0)
                {
                    diff     = diff + 2;
                    sixZeros = true;
                }
                int dataEnd = mData.Count + diff;
                if (diff > 0)
                {
                    AddBytes(diff);
                    ShiftDataDown(stringLoc, diff, dataEnd);
                }
                else if (diff < 0)
                {
                    ShiftDataUp(stringLoc, -1 * diff, dataEnd);
                }
                //write hashId
                BinUtils.WriteNumberAtLocation(stringLoc, hashId, mData);

                // write the size
                BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, sz, mData);
                // lay down string
                stringLoc += 6; /** MODIFYING 'stringLoc' NOW!! **/
                for (int i = 0; i < newValue.Length; i++)
                {
                    BinUtils.Write2ByteNumberAtLocation(stringLoc, newValue[i], mData);
                    stringLoc += 2;
                }
                BinUtils.WriteNumberAtLocation(stringLoc, 0, mData);
                if (sixZeros)
                {
                    BinUtils.Write2ByteNumberAtLocation(stringLoc + 4, 0, mData);
                }
                AddBodySize(diff);
            }
            return(stringLoc);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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());
        }