コード例 #1
0
ファイル: ShellBag0x00.cs プロジェクト: wyrover/Lnk
        private void ProcessZipFileContents(byte[] rawBytes)
        {
            FriendlyName = "Variable: Zip file contents";

            if (rawBytes[0x28] == 0x2f || (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41) ||
                rawBytes[0x1c] == 0x2f || (rawBytes[0x18] == 0x4e && rawBytes[0x1a] == 0x2f && rawBytes[0x1c] == 0x41))
            {
                //we have a good date

                var zip = new ShellBagZipContents(rawBytes);
                FriendlyName   = zip.FriendlyName;
                LastAccessTime = zip.LastAccessTime;

                Value = zip.Value;
            }
            else
            {
                Value = "!!! Unable to determine Value !!!";
            }
        }
コード例 #2
0
        public ShellBag0X31(byte[] rawBytes)
        {
            FriendlyName = "Directory";


            ExtensionBlocks = new List <IExtensionBlock>();


            var index = 2;

            if (rawBytes.Length > 0x29 && (rawBytes[0x27] == 0x00 && rawBytes[0x28] == 0x2f && rawBytes[0x29] == 0x00 ||
                                           rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
            {
                //we have a good date

                try
                {
                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName   = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
                catch (Exception)
                {
                    //this isnt really this kind of entry despite our best efforts to make sure it is, so fall thru and process normally
                }
            }

            index += 1;

            //skip unknown byte
            index += 1;

            index += 4; // skip file size since always 0 for directory

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(rawBytes.Skip(index).Take(4).ToArray());

            index += 4;

            index += 2;

            var len = 0;

            var beefPos = BitConverter.ToString(rawBytes).IndexOf("04-00-EF-BE", StringComparison.InvariantCulture) / 3;

            beefPos = beefPos - 4; //add header back for beef

            var strLen = beefPos - index;

            if (rawBytes[2] == 0x35)
            {
                len = strLen;
            }
            else
            {
                while (rawBytes[index + len] != 0x0)
                {
                    len += 1;
                }
            }


            var tempBytes = new byte[len];

            Array.Copy(rawBytes, index, tempBytes, 0, len);

            index += len;

            var shortName = "";

            if (rawBytes[2] == 0x35)
            {
                shortName = Encoding.Unicode.GetString(tempBytes);
            }
            else
            {
                shortName = Encoding.GetEncoding(1252).GetString(tempBytes);
            }

            ShortName = shortName;

            Value = shortName;

            if (rawBytes.Length == index)
            {
                return;
            }

            while (rawBytes[index] == 0x0)
            {
                index += 1;

                if (rawBytes.Length == index)
                {
                    return;
                }
            }

            // here is where we need to cut up the rest into extension blocks
            var chunks = new List <byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                if (block.Signature.ToString("X").StartsWith("BEEF00"))
                {
                    ExtensionBlocks.Add(block);
                }


                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                var beef0005 = block as Beef0005;
                if (beef0005 != null)
                {
                    //TODO Resolve this
//                    foreach (var internalBag in beef0005.InternalBags)
//                    {
//                        ExtensionBlocks.Add(new BeefPlaceHolder(null));
//
//
//                    }
                }

                index += extsize;
            }
        }
コード例 #3
0
        private void ProcessPropertyViewDefault(byte[] rawBytes)
        {
            FriendlyName = "Variable: Users property view";
            var index = 10;

            var shellPropertySheetListSize = BitConverter.ToInt16(rawBytes, index);

            index += 2;

            var identifiersize = BitConverter.ToInt16(rawBytes, index);

            index += 2;

            var identifierData = new byte[identifiersize];

            Array.Copy(rawBytes, index, identifierData, 0, identifiersize);


            index += identifiersize;

            if (shellPropertySheetListSize > 0)
            {
                var propBytes = rawBytes.Skip(index).Take(shellPropertySheetListSize).ToArray();
                var propStore = new PropertyStore(propBytes);

                PropertyStore = propStore;

                var p = propStore.Sheets.Where(t => t.PropertyNames.ContainsKey("32"));

                if (p.Any())
                {
                    //we can now look thry prop bytes for extension blocks
                    //TODO this is a hack until we can process vectors natively

                    var extOffsets = new List <int>();
                    try
                    {
                        var regexObj    = new Regex("([0-9A-F]{2})-00-EF-BE", RegexOptions.IgnoreCase);
                        var matchResult = regexObj.Match(BitConverter.ToString(propBytes));
                        while (matchResult.Success)
                        {
                            extOffsets.Add(matchResult.Index);
                            matchResult = matchResult.NextMatch();
                        }

                        foreach (var extOffset in extOffsets)
                        {
                            var binaryOffset = extOffset / 3 - 4;
                            var exSize       = BitConverter.ToInt16(propBytes, binaryOffset);

                            var exBytes = propBytes.Skip(binaryOffset).Take(exSize).ToArray();

                            var signature1 = BitConverter.ToUInt32(exBytes, 4);

                            var block1 = Utils.GetExtensionBlockFromBytes(signature1, exBytes);

                            ExtensionBlocks.Add(block1);
                        }
                    }
                    catch (ArgumentException ex)
                    {
                        throw ex;
                        // Syntax error in the regular expression
                    }
                }
            }
            else
            {
                if (rawBytes[0x28] == 0x2f ||
                    rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41)
                {
                    //we have a good date

                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName   = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
                Debug.Write("Oh no! No property sheets!");


                Value = "!!! Unable to determine Value !!!";
            }

            index += shellPropertySheetListSize;

            index += 2; //move past end of property sheet terminator

            var extBlockSize = BitConverter.ToInt16(rawBytes, index);

            if (extBlockSize > 0)
            {
                //process extension blocks

                while (extBlockSize > 0)
                {
                    var extBytes = rawBytes.Skip(index).Take(extBlockSize).ToArray();

                    index += extBlockSize;

                    var signature1 = BitConverter.ToUInt32(extBytes, 4);


                    var block1 = Utils.GetExtensionBlockFromBytes(signature1, extBytes);

                    ExtensionBlocks.Add(block1);


                    extBlockSize = BitConverter.ToInt16(rawBytes, index);
                }
            }

            int terminator = BitConverter.ToInt16(rawBytes, index);

            if (terminator > 0)
            {
                throw new Exception($"Expected terminator of 0, but got {terminator}");
            }

            var valuestring = (from propertySheet in PropertyStore.Sheets
                               from propertyName in propertySheet.PropertyNames
                               where propertyName.Key == "10"
                               select propertyName.Value).FirstOrDefault();

            if (valuestring == null)
            {
                var namesList =
                    (from propertySheet in PropertyStore.Sheets
                     from propertyName in propertySheet.PropertyNames
                     select propertyName.Value)
                    .ToList();

                valuestring = string.Join("::", namesList.ToArray());
            }

            if (valuestring == "")
            {
                valuestring = "No Property sheet value found";
            }

            Value = valuestring;
        }
コード例 #4
0
ファイル: ShellBag0x74.cs プロジェクト: EricZimmerman/Lnk
        public ShellBag0X74(byte[] rawBytes)
        {
            FriendlyName = "Users Files Folder";

            ExtensionBlocks = new List<IExtensionBlock>();

            var index = 2;

            index += 2; // move past type  and an unknown

            var size = BitConverter.ToUInt16(rawBytes, index);

            index += 2;

            var sig74 = Encoding.GetEncoding(1252).GetString(rawBytes, index, 4);

            if (sig74 == "CF\0\0")
            {
                if (rawBytes[0x28] == 0x2f ||
                    (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
                {
                    //we have a good date

                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
            }

            if (sig74 != "CFSF")
            {
                throw new Exception($"Invalid signature! Should be CFSF but was {sig74}");
            }

            index += 4;

            var subShellSize = BitConverter.ToUInt16(rawBytes, index);
            index += 2;

            var subClasstype = rawBytes[index];
            index += 1;

            index += 1; // skip unknown

            var filesize = BitConverter.ToUInt32(rawBytes, index);

            index += 4;

            FileSize = (int) filesize;

            var tempBytes = new byte[4];
            Array.Copy(rawBytes, index, tempBytes, 0, 4);

            index += 4;

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(tempBytes);

            index += 2; //skip file attribute flag

            var len = 0;

            while (rawBytes[index + len] != 0x0)
            {
                len += 1;
            }

            tempBytes = new byte[len];
            Array.Copy(rawBytes, index, tempBytes, 0, len);

            index += len;

            var primaryName = Encoding.GetEncoding(1252).GetString(tempBytes);


            while (rawBytes[index] == 0x0)
            {
                index += 1;
            }

            var delegateGuidRaw = new byte[16];

            Array.Copy(rawBytes, index, delegateGuidRaw, 0, 16);


            var delegateGuid = Utils.ExtractGuidFromShellItem(delegateGuidRaw);

            if (delegateGuid != "5e591a74-df96-48d3-8d67-1733bcee28ba")
            {
                throw new Exception(
                    $"Delegate guid not expected value of 5e591a74-df96-48d3-8d67-1733bcee28ba. Actual value: {delegateGuid}");
            }

            index += 16;

            var itemIdentifierGuidRaw = new byte[16];
            Array.Copy(rawBytes, index, itemIdentifierGuidRaw, 0, 16);

            var itemIdentifierGuid = Utils.ExtractGuidFromShellItem(itemIdentifierGuidRaw);

            var itemName = Utils.GetFolderNameFromGuid(itemIdentifierGuid);
            index += 16;

            //0xbeef0004 section

            //we are at extensnon blocks, so cut them up and process
            // here is where we need to cut up the rest into extension blocks
            var chunks = new List<byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                index += extsize;
            }
        }
コード例 #5
0
        public ShellBag0X32(byte[] rawBytes)
        {
            FriendlyName = "File";

            ExtensionBlocks = new List <IExtensionBlock>();

            ShortName = string.Empty;

            var index = 2;

            if (rawBytes[0x28] == 0x2f || rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41)
            {
                //we have a good date

                try
                {
                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName   = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
                catch (Exception)
                {
                }
            }

            index += 1;

            //skip unknown byte
            index += 1;

            var fileSize = BitConverter.ToUInt32(rawBytes, index);


            FileSize = (int)fileSize;

            index += 4; // skip file size since always 0 for directory

            var tempBytes = new byte[4];

            Array.Copy(rawBytes, index, tempBytes, 0, 4);
            var lastmodifiedUtcRaw = tempBytes;

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(lastmodifiedUtcRaw);


            index += 4;

            index += 2;

            var len = 0;

            while (rawBytes[index + len] != 0x0)
            {
                len += 1;
            }

            tempBytes = new byte[len];
            Array.Copy(rawBytes, index, tempBytes, 0, len);

            index += len;

            var shortName = Encoding.GetEncoding(1252).GetString(tempBytes);

            ShortName = shortName;

            while (rawBytes[index] == 0x0)
            {
                index += 1;
            }

            //we are at extension blocks, so cut them up and process
            // here is where we need to cut up the rest into extension blocks
            var chunks = new List <byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                index += extsize;
            }
        }
コード例 #6
0
ファイル: ShellBag0x00.cs プロジェクト: palaniyappanBala/Lnk
        private void ProcessPropertyViewDefault(byte[] rawBytes)
        {
            FriendlyName = "Variable: Users property view";
            var index = 10;

            var shellPropertySheetListSize = BitConverter.ToInt16(rawBytes, index);

            index += 2;

            var identifiersize = BitConverter.ToInt16(rawBytes, index);

            index += 2;

            if (identifiersize > rawBytes.Length)
            {
                index = 0xc;

                var strs = Encoding.GetEncoding(1252).GetString(rawBytes, index, rawBytes.Length - index).Split('\0');

                var p2 = string.Join(",", strs.Skip(1).ToList());

                Value = $"{strs[0]} ({p2})";

                return;
            }

            var identifierData = new byte[identifiersize];

            Array.Copy(rawBytes, index, identifierData, 0, identifiersize);

            index += identifiersize;

            if (shellPropertySheetListSize > 0)
            {
                var propBytes = rawBytes.Skip(index).Take(shellPropertySheetListSize).ToArray();
                var propStore = new PropertyStore(propBytes);

                PropertyStore = propStore;

                var p = propStore.Sheets.Where(t => t.PropertyNames.ContainsKey("32"));

                if (p.Any())
                {
                    //we can now look thry prop bytes for extension blocks
                    //TODO this is a hack until we can process vectors natively

                    var extOffsets = new List <int>();
                    try
                    {
                        var regexObj    = new Regex("([0-9A-F]{2})-00-EF-BE", RegexOptions.IgnoreCase);
                        var matchResult = regexObj.Match(BitConverter.ToString(propBytes));
                        while (matchResult.Success)
                        {
                            extOffsets.Add(matchResult.Index);
                            matchResult = matchResult.NextMatch();
                        }

                        foreach (var extOffset in extOffsets)
                        {
                            var binaryOffset = extOffset / 3 - 4;
                            var exSize       = BitConverter.ToInt16(propBytes, binaryOffset);

                            var exBytes = propBytes.Skip(binaryOffset).Take(exSize).ToArray();

                            var signature1 = BitConverter.ToUInt32(exBytes, 4);

                            //Debug.WriteLine(" 0x1f bag sig: " + signature1.ToString("X8"));

                            var block1 = Utils.GetExtensionBlockFromBytes(signature1, exBytes);

                            ExtensionBlocks.Add(block1);
                        }
                    }
                    catch (ArgumentException ex)
                    {
                        throw ex;
                        // Syntax error in the regular expression
                    }

                    //     Debug.WriteLine("Found 32 key");
                }
            }
            else
            {
                //   Debug.Write("Oh no! No property sheets!");
                // SiAuto.Main.LogWarning("Oh no! No property sheets!");

                if (rawBytes[0x28] == 0x2f ||
                    rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41)
                {
                    //we have a good date

                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName   = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }

                //41-75-67-4D is AugM

                if (rawBytes[4] == 0x41 && rawBytes[5] == 0x75 && rawBytes[6] == 0x67 && rawBytes[7] == 0x4D)
                {
                    var cdb = new ShellBagCDBurn(rawBytes);

                    Value                = cdb.Value;
                    FriendlyName         = cdb.FriendlyName;
                    CreatedOnTime        = cdb.CreatedOnTime;
                    LastModificationTime = cdb.LastModificationTime;
                    LastAccessTime       = cdb.LastAccessTime;


                    return;
                }


                Debug.Write("Oh no! No property sheets!");

                Value = "!!! Unable to determine Value !!!";
            }

            index += shellPropertySheetListSize;

            index += 2; //move past end of property sheet terminator

            if (shellPropertySheetListSize > 0 && index < rawBytes.Length)
            {
                var extBlockSize = BitConverter.ToInt16(rawBytes, index);

                if (extBlockSize > 0)
                {
                    //process extension blocks

                    while (extBlockSize > 0)
                    {
                        var extBytes = rawBytes.Skip(index).Take(extBlockSize).ToArray();

                        index += extBlockSize;

                        var signature1 = BitConverter.ToUInt32(extBytes, 4);


                        var block1 = Utils.GetExtensionBlockFromBytes(signature1, extBytes);

                        ExtensionBlocks.Add(block1);

                        if (index >= rawBytes.Length)
                        {
                            break;
                        }

                        extBlockSize = BitConverter.ToInt16(rawBytes, index);
                    }
                }

//                int terminator = BitConverter.ToInt16(rawBytes, index);
//
//                if (terminator > 0)
//                {
//                    throw new Exception($"Expected terminator of 0, but got {terminator}");
//                }
            }

            var valuestring = (from propertySheet in PropertyStore.Sheets
                               from propertyName in propertySheet.PropertyNames
                               where propertyName.Key == "10"
                               select propertyName.Value).FirstOrDefault();

            if (valuestring == null)
            {
                var namesList =
                    (from propertySheet in PropertyStore.Sheets
                     from propertyName in propertySheet.PropertyNames
                     select propertyName.Value)
                    .ToList();

                valuestring = string.Join("::", namesList.ToArray());
            }

            if (valuestring == "")
            {
                valuestring = "No Property sheet value found";
            }

            Value = valuestring;
        }
コード例 #7
0
        public ShellBag0X32(byte[] rawBytes)
        {
            FriendlyName = "File";

            ExtensionBlocks = new List <IExtensionBlock>();

            ShortName = string.Empty;

            var index = 2;

            if (rawBytes.Length > 0x28 && (rawBytes[0x28] == 0x2f || rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
            {
                //we have a good date

                if (rawBytes[0x28] == 0x2f || rawBytes[0x26] == 0x2f || rawBytes[0x1a] == 0x2f ||
                    rawBytes[0x1c] == 0x2f)
                // forward slash in date or N / A
                {
                    //zip?


                    try
                    {
                        var zip = new ShellBagZipContents(rawBytes);
                        FriendlyName   = zip.FriendlyName;
                        LastAccessTime = zip.LastAccessTime;

                        Value = zip.Value;

                        if (Value.Contains("Unable to determine value") == false)
                        {
                            return;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            index += 1;

            //skip unknown byte
            index += 1;

            var fileSize = BitConverter.ToUInt32(rawBytes, index);


            FileSize = (int)fileSize;

            index += 4; // skip file size since always 0 for directory

            var tempBytes = new byte[4];

            Array.Copy(rawBytes, index, tempBytes, 0, 4);
            var lastmodifiedUtcRaw = tempBytes;

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(lastmodifiedUtcRaw);


            index += 4;

            index += 2;

            var len     = 0;
            var beefPos = BitConverter.ToString(rawBytes).IndexOf("04-00-EF-BE", StringComparison.InvariantCulture) / 3;

            if (beefPos == 0)
            {
                var hackName = Encoding.GetEncoding(1255).GetString(rawBytes, index, rawBytes.Length - index);

                var segs = hackName.Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);

                ShortName = string.Join("|", segs);

                Value = ShortName;
                return;
            }


            beefPos = beefPos - 4; //add header back for beef

            var strLen = beefPos - index;

            if (rawBytes[2] == 0x36)
            {
                len = strLen;
            }
            else
            {
                while (rawBytes[index + len] != 0x0)
                {
                    len += 1;
                }
            }

            tempBytes = new byte[len];
            Array.Copy(rawBytes, index, tempBytes, 0, len);

            var shortName = "";

            if (rawBytes[2] == 0x36)
            {
                shortName = Encoding.Unicode.GetString(tempBytes);
            }
            else
            {
                shortName = Encoding.GetEncoding(1252).GetString(tempBytes);
            }

            ShortName = shortName;

            Value = shortName;

            index = beefPos;

            //we are at extension blocks, so cut them up and process
            // here is where we need to cut up the rest into extension blocks
            var chunks = new List <byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                index += extsize;
            }
        }
コード例 #8
0
ファイル: ShellBag0x00.cs プロジェクト: EricZimmerman/Lnk
        private void ProcessZipFileContents(byte[] rawBytes)
        {
            FriendlyName = "Variable: Zip file contents";

            if (rawBytes[0x28] == 0x2f || (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41) ||
                rawBytes[0x1c] == 0x2f || (rawBytes[0x18] == 0x4e && rawBytes[0x1a] == 0x2f && rawBytes[0x1c] == 0x41))
            {
                //we have a good date

                var zip = new ShellBagZipContents(rawBytes);
                FriendlyName = zip.FriendlyName;
                LastAccessTime = zip.LastAccessTime;

                Value = zip.Value;
            }
            else
            {
                Value = "!!! Unable to determine Value !!!";
            }
        }
コード例 #9
0
ファイル: ShellBag0x00.cs プロジェクト: EricZimmerman/Lnk
        private void ProcessPropertyViewDefault(byte[] rawBytes)
        {
            FriendlyName = "Variable: Users property view";
            var index = 10;

            var shellPropertySheetListSize = BitConverter.ToInt16(rawBytes, index);

            index += 2;

            var identifiersize = BitConverter.ToInt16(rawBytes, index);

            index += 2;

            var identifierData = new byte[identifiersize];

            Array.Copy(rawBytes, index, identifierData, 0, identifiersize);

            index += identifiersize;

            if (shellPropertySheetListSize > 0)
            {
                var propBytes = rawBytes.Skip(index).Take(shellPropertySheetListSize).ToArray();
                var propStore = new PropertyStore(propBytes);

                PropertyStore = propStore;

                var p = propStore.Sheets.Where(t => t.PropertyNames.ContainsKey("32"));

                if (p.Any())
                {
                    //we can now look thry prop bytes for extension blocks
                    //TODO this is a hack until we can process vectors natively

                    var extOffsets = new List<int>();
                    try
                    {
                        var regexObj = new Regex("([0-9A-F]{2})-00-EF-BE", RegexOptions.IgnoreCase);
                        var matchResult = regexObj.Match(BitConverter.ToString(propBytes));
                        while (matchResult.Success)
                        {
                            extOffsets.Add(matchResult.Index);
                            matchResult = matchResult.NextMatch();
                        }

                        foreach (var extOffset in extOffsets)
                        {
                            var binaryOffset = extOffset/3 - 4;
                            var exSize = BitConverter.ToInt16(propBytes, binaryOffset);

                            var exBytes = propBytes.Skip(binaryOffset).Take(exSize).ToArray();

                            var signature1 = BitConverter.ToUInt32(exBytes, 4);

                            //Debug.WriteLine(" 0x1f bag sig: " + signature1.ToString("X8"));

                            var block1 = Utils.GetExtensionBlockFromBytes(signature1, exBytes);

                            ExtensionBlocks.Add(block1);
                        }
                    }
                    catch (ArgumentException ex)
                    {
                        throw ex;
                        // Syntax error in the regular expression
                    }

                    //     Debug.WriteLine("Found 32 key");
                }
            }
            else
            {
                //   Debug.Write("Oh no! No property sheets!");
                // SiAuto.Main.LogWarning("Oh no! No property sheets!");

                if (rawBytes[0x28] == 0x2f ||
                    (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
                {
                    //we have a good date

                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }

                //41-75-67-4D is AugM

                if (rawBytes[4] == 0x41 && rawBytes[5] == 0x75 && rawBytes[6] == 0x67 && rawBytes[7] == 0x4D)
                {
                    var cdb = new ShellBagCDBurn(rawBytes);

                    Value = cdb.Value;
                    FriendlyName = cdb.FriendlyName;
                    CreatedOnTime = cdb.CreatedOnTime;
                    LastModificationTime = cdb.LastModificationTime;
                    LastAccessTime = cdb.LastAccessTime;
                    

                    return;
                }

                

                Debug.Write("Oh no! No property sheets!");

                Value = "!!! Unable to determine Value !!!";
            }

            index += shellPropertySheetListSize;

            index += 2; //move past end of property sheet terminator

            if (shellPropertySheetListSize > 0 && index < rawBytes.Length)
            {
                var extBlockSize = BitConverter.ToInt16(rawBytes, index);

                if (extBlockSize > 0)
                {
                    //process extension blocks

                    while (extBlockSize > 0)
                    {
                        var extBytes = rawBytes.Skip(index).Take(extBlockSize).ToArray();

                        index += extBlockSize;

                        var signature1 = BitConverter.ToUInt32(extBytes, 4);


                        var block1 = Utils.GetExtensionBlockFromBytes(signature1, extBytes);

                        ExtensionBlocks.Add(block1);

                        if (index >= rawBytes.Length)
                        {
                            break;
                        }

                        extBlockSize = BitConverter.ToInt16(rawBytes, index);
                    }
                }

//                int terminator = BitConverter.ToInt16(rawBytes, index);
//
//                if (terminator > 0)
//                {
//                    throw new Exception($"Expected terminator of 0, but got {terminator}");
//                }
            }

            var valuestring = (from propertySheet in PropertyStore.Sheets
                from propertyName in propertySheet.PropertyNames
                where propertyName.Key == "10"
                select propertyName.Value).FirstOrDefault();

            if (valuestring == null)
            {
                var namesList =
                    (from propertySheet in PropertyStore.Sheets
                        from propertyName in propertySheet.PropertyNames
                        select propertyName.Value)
                        .ToList();

                valuestring = string.Join("::", namesList.ToArray());
            }

            if (valuestring == "")
            {
                valuestring = "No Property sheet value found";
            }

            Value = valuestring;
        }
コード例 #10
0
ファイル: ShellBag0x32.cs プロジェクト: EricZimmerman/Lnk
        public ShellBag0X32(byte[] rawBytes)
        {
            FriendlyName = "File";

            ExtensionBlocks = new List<IExtensionBlock>();

            ShortName = string.Empty;

            var index = 2;

            if (rawBytes[0x28] == 0x2f || (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
            {
                //we have a good date

                try
                {
                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
                catch (Exception)
                {
                }
            }

            index += 1;

            //skip unknown byte
            index += 1;

            var fileSize = BitConverter.ToUInt32(rawBytes, index);


            FileSize = (int) fileSize;

            index += 4; // skip file size since always 0 for directory

            var tempBytes = new byte[4];
            Array.Copy(rawBytes, index, tempBytes, 0, 4);
            var lastmodifiedUtcRaw = tempBytes;

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(lastmodifiedUtcRaw);


            index += 4;

            index += 2;

            var len = 0;

            while (rawBytes[index + len] != 0x0)
            {
                len += 1;
            }

            tempBytes = new byte[len];
            Array.Copy(rawBytes, index, tempBytes, 0, len);

            index += len;

            var shortName = Encoding.GetEncoding(1252).GetString(tempBytes);

            ShortName = shortName;

            while (rawBytes[index] == 0x0)
            {
                index += 1;
            }

            //we are at extension blocks, so cut them up and process
            // here is where we need to cut up the rest into extension blocks
            var chunks = new List<byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                index += extsize;
            }
        }
コード例 #11
0
ファイル: ShellBag0x2e.cs プロジェクト: wyrover/Lnk
        public ShellBag0X2E(byte[] rawBytes)
        {
            ExtensionBlocks = new List <IExtensionBlock>();

            var index = 0;

            var postSig = BitConverter.ToInt64(rawBytes, rawBytes.Length - 8);

            if (postSig == 0x0000ee306bfe9555)
            {
                FriendlyName = "User profile";

                var la = Utils.ExtractDateTimeOffsetFromBytes(rawBytes.Skip(rawBytes.Length - 14).Take(4).ToArray());

                LastAccessTime = la;

                index = 10;

                var tempString = Encoding.Unicode.GetString(rawBytes.Skip(index).ToArray()).Split('\0')[0];

                Value = tempString;

                return;
            }

            //this needs to change to be the default
            if (rawBytes[0] == 20 || rawBytes[0] == 50 || rawBytes[0] == 0x3a)
            {
                ProcessGuid(rawBytes);
                return;
            }

            //this needs to change to be the default
            if (rawBytes[2] == 0x53)
            {
                ProcessGuid2(rawBytes);
                return;
            }

            //zip file contents check
            if (rawBytes[0x28] == 0x2f || (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
            {
                //we have a good date

                var zip = new ShellBagZipContents(rawBytes);
                FriendlyName   = zip.FriendlyName;
                LastAccessTime = zip.LastAccessTime;

                Value = zip.Value;

                return;
            }


            try
            {
                ProcessPropertyViewDefault(rawBytes);

                return;
            }
            catch (Exception)
            {
            }

            //this is a different animal,

            FriendlyName = "Root folder: MPT device";

            index = 0x1e;

            var storageStringNameLen = BitConverter.ToInt32(rawBytes, index);

            index += 4;

            var storageIdStringLen = BitConverter.ToInt32(rawBytes, index);

            index += 4;

            var fileSystemNameLen = BitConverter.ToInt32(rawBytes, index);

            index = 0x28;

            var storageName = Encoding.Unicode.GetString(rawBytes, index, storageStringNameLen * 2 - 2);

            index += storageStringNameLen * 2;

            var storageIdName = Encoding.Unicode.GetString(rawBytes, index, storageIdStringLen * 2 - 2);

            index += storageIdStringLen * 2;

            Value = storageName;
        }
コード例 #12
0
        public ShellBag0X74(byte[] rawBytes)
        {
            FriendlyName = "Users Files Folder";

            ExtensionBlocks = new List <IExtensionBlock>();

            var index = 2;

            index += 2; // move past type  and an unknown

            var size = BitConverter.ToUInt16(rawBytes, index);

            index += 2;

            var sig74 = Encoding.GetEncoding(1252).GetString(rawBytes, index, 4);

            if (sig74 == "CF\0\0")
            {
                if (rawBytes[0x28] == 0x2f ||
                    (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
                {
                    //we have a good date

                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName   = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
            }

            if (sig74 != "CFSF")
            {
                throw new Exception($"Invalid signature! Should be CFSF but was {sig74}");
            }

            index += 4;

            var subShellSize = BitConverter.ToUInt16(rawBytes, index);

            index += 2;

            var subClasstype = rawBytes[index];

            index += 1;

            index += 1; // skip unknown

            var filesize = BitConverter.ToUInt32(rawBytes, index);

            index += 4;

            FileSize = (int)filesize;

            var tempBytes = new byte[4];

            Array.Copy(rawBytes, index, tempBytes, 0, 4);

            index += 4;

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(tempBytes);

            index += 2; //skip file attribute flag

            var len = 0;

            while (rawBytes[index + len] != 0x0)
            {
                len += 1;
            }

            tempBytes = new byte[len];
            Array.Copy(rawBytes, index, tempBytes, 0, len);

            index += len;

            var primaryName = Encoding.GetEncoding(1252).GetString(tempBytes);


            while (rawBytes[index] == 0x0)
            {
                index += 1;
            }

            var delegateGuidRaw = new byte[16];

            Array.Copy(rawBytes, index, delegateGuidRaw, 0, 16);


            var delegateGuid = Utils.ExtractGuidFromShellItem(delegateGuidRaw);

            if (delegateGuid != "5e591a74-df96-48d3-8d67-1733bcee28ba")
            {
                throw new Exception(
                          $"Delegate guid not expected value of 5e591a74-df96-48d3-8d67-1733bcee28ba. Actual value: {delegateGuid}");
            }

            index += 16;

            var itemIdentifierGuidRaw = new byte[16];

            Array.Copy(rawBytes, index, itemIdentifierGuidRaw, 0, 16);

            var itemIdentifierGuid = Utils.ExtractGuidFromShellItem(itemIdentifierGuidRaw);

            var itemName = Utils.GetFolderNameFromGuid(itemIdentifierGuid);

            index += 16;

            //0xbeef0004 section

            //we are at extensnon blocks, so cut them up and process
            // here is where we need to cut up the rest into extension blocks
            var chunks = new List <byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                index += extsize;
            }
        }
コード例 #13
0
ファイル: LnkFile.cs プロジェクト: EricZimmerman/Lnk
        public LnkFile(byte[] rawBytes, string sourceFile)
        {
            RawBytes = rawBytes;
            SourceFile = Path.GetFullPath(sourceFile);
            var headerBytes = new byte[76];
            Buffer.BlockCopy(rawBytes, 0, headerBytes, 0, 76);

            Header = new Header(headerBytes);

            var fi = new FileInfo(sourceFile);
            SourceCreated = new DateTimeOffset(fi.CreationTimeUtc);
            SourceModified = new DateTimeOffset(fi.LastWriteTimeUtc);
            SourceAccessed = new DateTimeOffset(fi.LastAccessTimeUtc);

            if (SourceCreated.Value.Year == 1601)
            {
                SourceCreated = null;
            }

            if (SourceModified.Value.Year == 1601)
            {
                SourceModified = null;
            }

            if (SourceAccessed.Value.Year == 1601)
            {
                SourceAccessed = null;
            }

            var index = 76;

            TargetIDs = new List<ShellBag>();

            if ((Header.DataFlags & Header.DataFlag.HasTargetIdList) == Header.DataFlag.HasTargetIdList)
            {
                //process shell items
                var shellItemSize = BitConverter.ToInt16(rawBytes, index);
                index += 2;

                var shellItemBytes = new byte[shellItemSize];
                Buffer.BlockCopy(rawBytes, index, shellItemBytes, 0, shellItemSize);

                var shellItemsRaw = new List<byte[]>();
                var shellItemIndex = 0;

                while (shellItemIndex < shellItemBytes.Length)
                {
                    var shellSize = BitConverter.ToUInt16(shellItemBytes, shellItemIndex);

                    if (shellSize == 0)
                    {
                        break;
                    }
                    var itemBytes = new byte[shellSize];
                    Buffer.BlockCopy(shellItemBytes, shellItemIndex, itemBytes, 0, shellSize);

                    shellItemsRaw.Add(itemBytes);
                    shellItemIndex += shellSize;
                }

                //TODO try catch and add placeholder for shellitem when exeption happens? or ?
                foreach (var shellItem in shellItemsRaw)
                {
                    switch (shellItem[2])
                    {
                        case 0x1f:
                            var f = new ShellBag0X1F(shellItem);
                            TargetIDs.Add(f);
                            break;

                        case 0x2f:
                            var ff = new ShellBag0X2F(shellItem);
                            TargetIDs.Add(ff);
                            break;
                        case 0x2e:
                            var ee = new ShellBag0X2E(shellItem);
                            TargetIDs.Add(ee);
                            break;
                        case 0xbd:
                        case 0x6e:
                            var bd = new ShellBagZipContents(shellItem);
                            TargetIDs.Add(bd);
                            break;
                        case 0xb1:
                        case 0x31:
                        case 0x35:
                            var d = new ShellBag0X31(shellItem);
                            TargetIDs.Add(d);
                            break;
                        case 0x36:
                        case 0x32:
                            var d2 = new ShellBag0X32(shellItem);
                            TargetIDs.Add(d2);
                            break;
                        case 0x00:
                            var v0 = new ShellBag0X00(shellItem);
                            TargetIDs.Add(v0);
                            break;
                        case 0x01:
                            var one = new ShellBag0X01(shellItem);
                            TargetIDs.Add(one);
                            break;
                        case 0x71:
                            var sevenone = new ShellBag0X71(shellItem);
                            TargetIDs.Add(sevenone);
                            break;
                        case 0x61:
                            var sixone = new ShellBag0X61(shellItem);
                            TargetIDs.Add(sixone);
                            break;

                        case 0xC3:
                            var c3 = new ShellBag0Xc3(shellItem);
                            TargetIDs.Add(c3);
                            break;

                        case 0x74:
                        case 0x77:
                            var sev = new ShellBag0X74(shellItem);
                            TargetIDs.Add(sev);
                            break;

                        case 0xae:
                        case 0xaa:
                        case 0x79:
                            var ae = new ShellBagZipContents(shellItem);
                            TargetIDs.Add(ae);
                            break;

                        case 0x41:
                        case 0x42:
                        case 0x43:
                        case 0x46:
                        case 0x47:
                            var forty = new ShellBag0X40(shellItem);
                            TargetIDs.Add(forty);
                            break;
                        default:
                            throw new Exception($"Unknown shell item ID: 0x{shellItem[2]:X}. Please send to [email protected] so support can be added.");
                    }
                }

                //TODO tie back extra block for SpecialFolderDataBlock and KnownFolderDataBlock??

                index += shellItemSize;
            }

            if ((Header.DataFlags & Header.DataFlag.HasLinkInfo) == Header.DataFlag.HasLinkInfo)
            {
                var locationItemSize = BitConverter.ToInt32(rawBytes, index);
                var locationBytes = new byte[locationItemSize];
                Buffer.BlockCopy(rawBytes, index, locationBytes, 0, locationItemSize);

                if (locationBytes.Length > 20)
                {
                    var locationInfoHeaderSize = BitConverter.ToInt32(locationBytes, 4);

                LocationFlags = (LocationFlag) BitConverter.ToInt32(locationBytes, 8);

                var volOffset = BitConverter.ToInt32(locationBytes, 12);
                var vbyteSize = BitConverter.ToInt32(locationBytes, volOffset);
                var volBytes = new byte[vbyteSize];
                Buffer.BlockCopy(locationBytes, volOffset, volBytes, 0, vbyteSize);

                if (volOffset > 0)
                {
                    VolumeInfo = new VolumeInfo(volBytes);
                }

                var localPathOffset = BitConverter.ToInt32(locationBytes, 16);
                var networkShareOffset = BitConverter.ToInt32(locationBytes, 20);

                if ((LocationFlags & LocationFlag.VolumeIdAndLocalBasePath) == LocationFlag.VolumeIdAndLocalBasePath)
                {
                    LocalPath = Encoding.GetEncoding(1252)
                        .GetString(locationBytes, localPathOffset, locationBytes.Length - localPathOffset)
                        .Split('\0')
                        .First();
                }
                if ((LocationFlags & LocationFlag.CommonNetworkRelativeLinkAndPathSuffix) ==
                    LocationFlag.CommonNetworkRelativeLinkAndPathSuffix)
                {
                    var networkShareSize = BitConverter.ToInt32(locationBytes, networkShareOffset);
                    var networkBytes = new byte[networkShareSize];
                    Buffer.BlockCopy(locationBytes, networkShareOffset, networkBytes, 0, networkShareSize);

                    NetworkShareInfo = new NetworkShareInfo(networkBytes);
                }

                var commonPathOffset = BitConverter.ToInt32(locationBytes, 24);

                CommonPath = Encoding.GetEncoding(1252)
                    .GetString(locationBytes, commonPathOffset, locationBytes.Length - commonPathOffset)
                    .Split('\0')
                    .First();

                if (locationInfoHeaderSize > 28)
                {
                    var uniLocalOffset = BitConverter.ToInt32(locationBytes, 28);
                    
                    var unicodeLocalPath = Encoding.Unicode.GetString(locationBytes, uniLocalOffset, locationBytes.Length - uniLocalOffset).Split('\0').First();
                    LocalPath = unicodeLocalPath;
                }

                if (locationInfoHeaderSize > 32)
                {
                    var uniCommonOffset = BitConverter.ToInt32(locationBytes, 32);
                  
                    var unicodeCommonPath = Encoding.Unicode.GetString(locationBytes, uniCommonOffset, locationBytes.Length - uniCommonOffset).Split('\0').First();
                    CommonPath = unicodeCommonPath;
                }
                }

                

                index += locationItemSize;
            }

            if ((Header.DataFlags & Header.DataFlag.HasName) == Header.DataFlag.HasName)
            {
                var nameLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    Name = Encoding.Unicode.GetString(rawBytes, index, nameLen*2);
                    index += nameLen;
                }
                else
                {
                    Name = Encoding.GetEncoding(1252).GetString(rawBytes, index, nameLen);
                }
                index += nameLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasRelativePath) == Header.DataFlag.HasRelativePath)
            {
                var relLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    RelativePath = Encoding.Unicode.GetString(rawBytes, index, relLen*2);
                    index += relLen;
                }
                else
                {
                    RelativePath = Encoding.GetEncoding(1252).GetString(rawBytes, index, relLen);
                }
                index += relLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasWorkingDir) == Header.DataFlag.HasWorkingDir)
            {
                var workLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    WorkingDirectory = Encoding.Unicode.GetString(rawBytes, index, workLen*2);
                    index += workLen;
                }
                else
                {
                    WorkingDirectory = Encoding.GetEncoding(1252).GetString(rawBytes, index, workLen);
                }
                index += workLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasArguments) == Header.DataFlag.HasArguments)
            {
                var argLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    Arguments = Encoding.Unicode.GetString(rawBytes, index, argLen*2);
                    index += argLen;
                }
                else
                {
                    Arguments = Encoding.GetEncoding(1252).GetString(rawBytes, index, argLen);
                }
                index += argLen;
            }

            if ((Header.DataFlags & Header.DataFlag.HasIconLocation) == Header.DataFlag.HasIconLocation)
            {
                var icoLen = BitConverter.ToInt16(rawBytes, index);
                index += 2;
                if ((Header.DataFlags & Header.DataFlag.IsUnicode) == Header.DataFlag.IsUnicode)
                {
                    IconLocation = Encoding.Unicode.GetString(rawBytes, index, icoLen*2);
                    index += icoLen;
                }
                else
                {
                    IconLocation = Encoding.GetEncoding(1252).GetString(rawBytes, index, icoLen);
                }
                index += icoLen;
            }


            var extraByteBlocks = new List<byte[]>();
            //extra blocks
            while (index < rawBytes.Length)
            {
                var extraSize = BitConverter.ToInt32(rawBytes, index);
                if (extraSize == 0)
                {
                    break;
                }

                var extraBytes = new byte[extraSize];
                Buffer.BlockCopy(rawBytes, index, extraBytes, 0, extraSize);

                extraByteBlocks.Add(extraBytes);

                index += extraSize;
            }

            ExtraBlocks = new List<ExtraDataBase>();

            foreach (var extraBlock in extraByteBlocks)
            {
                var sig = (ExtraDataTypes) BitConverter.ToInt32(extraBlock, 4);

                switch (sig)
                {
                    case ExtraDataTypes.TrackerDataBlock:
                        var tb = new TrackerDataBaseBlock(extraBlock);
                        ExtraBlocks.Add(tb);
                        break;
                    case ExtraDataTypes.ConsoleDataBlock:
                        var cdb = new ConsoleDataBlock(extraBlock);
                        ExtraBlocks.Add(cdb);
                        break;
                    case ExtraDataTypes.ConsoleFeDataBlock:
                        var cfeb = new ConsoleFeDataBlock(extraBlock);
                        ExtraBlocks.Add(cfeb);
                        break;
                    case ExtraDataTypes.DarwinDataBlock:
                        var db = new DarwinDataBlock(extraBlock);
                        ExtraBlocks.Add(db);
                        break;
                    case ExtraDataTypes.EnvironmentVariableDataBlock:
                        var eb = new EnvironmentVariableDataBlock(extraBlock);
                        ExtraBlocks.Add(eb);
                        break;
                    case ExtraDataTypes.IconEnvironmentDataBlock:
                        var ib = new IconEnvironmentDataBlock(extraBlock);
                        ExtraBlocks.Add(ib);
                        break;
                    case ExtraDataTypes.KnownFolderDataBlock:
                        var kf = new KnownFolderDataBlock(extraBlock);
                        ExtraBlocks.Add(kf);
                        break;
                    case ExtraDataTypes.PropertyStoreDataBlock:
                        var ps = new PropertyStoreDataBlock(extraBlock);

                        ExtraBlocks.Add(ps);
                        break;
                    case ExtraDataTypes.ShimDataBlock:
                        var sd = new KnownFolderDataBlock(extraBlock);
                        ExtraBlocks.Add(sd);
                        break;
                    case ExtraDataTypes.SpecialFolderDataBlock:
                        var sf = new SpecialFolderDataBlock(extraBlock);
                        ExtraBlocks.Add(sf);
                        break;
                    case ExtraDataTypes.VistaAndAboveIdListDataBlock:
                        var vid = new VistaAndAboveIdListDataBlock(extraBlock);
                        ExtraBlocks.Add(vid);
                        break;
                    default:
                        throw new Exception(
                            $"Unknown extra data block signature: 0x{sig:X}. Please send lnk file to [email protected] so support can be added");
                }
            }
        }
コード例 #14
0
ファイル: ShellBag0x2e.cs プロジェクト: EricZimmerman/Lnk
        public ShellBag0X2E(byte[] rawBytes)
        {
            ExtensionBlocks = new List<IExtensionBlock>();

            var index = 0;

            var postSig = BitConverter.ToInt64(rawBytes, rawBytes.Length - 8);

            if (postSig == 0x0000ee306bfe9555)
            {
                FriendlyName = "User profile";

                var la = Utils.ExtractDateTimeOffsetFromBytes(rawBytes.Skip(rawBytes.Length - 14).Take(4).ToArray());

                LastAccessTime = la;

                index = 10;

                var tempString = Encoding.Unicode.GetString(rawBytes.Skip(index).ToArray()).Split('\0')[0];

                Value = tempString;

                return;
            }

            //this needs to change to be the default
            if (rawBytes[0] == 20 || rawBytes[0] == 50 || rawBytes[0] == 0x3a)
            {
                ProcessGuid(rawBytes);
                return;
            }

            //this needs to change to be the default
            if (rawBytes[2] == 0x53)
            {
                ProcessGuid2(rawBytes);
                return;
            }

            //zip file contents check
            if (rawBytes[0x28] == 0x2f || (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
            {
                //we have a good date

                var zip = new ShellBagZipContents( rawBytes);
                FriendlyName = zip.FriendlyName;
                LastAccessTime = zip.LastAccessTime;

                Value = zip.Value;

                return;
            }


            try
            {
                ProcessPropertyViewDefault(rawBytes);

                return;
            }
            catch (Exception)
            {
            }

            //this is a different animal,

            FriendlyName = "Root folder: MPT device";

            index = 0x1e;

            var storageStringNameLen = BitConverter.ToInt32(rawBytes, index);

            index += 4;

            var storageIdStringLen = BitConverter.ToInt32(rawBytes, index);

            index += 4;

            var fileSystemNameLen = BitConverter.ToInt32(rawBytes, index);

            index = 0x28;

            var storageName = Encoding.Unicode.GetString(rawBytes, index, storageStringNameLen*2 - 2);

            index += storageStringNameLen*2;

            var storageIdName = Encoding.Unicode.GetString(rawBytes, index, storageIdStringLen*2 - 2);

            index += storageIdStringLen*2;

            Value = storageName;
        }
コード例 #15
0
ファイル: ShellBag0x2e.cs プロジェクト: EricZimmerman/Lnk
        private void ProcessPropertyViewDefault(byte[] rawBytes)
        {
            FriendlyName = "Variable: Users property view";
            var index = 10;

            var shellPropertySheetListSize = BitConverter.ToInt16(rawBytes, index);


            index += 2;

            var identifiersize = BitConverter.ToInt16(rawBytes, index);


            index += 2;

            var identifierData = new byte[identifiersize];

            Array.Copy(rawBytes, index, identifierData, 0, identifiersize);


            index += identifiersize;

            if (shellPropertySheetListSize > 0)
            {
                var propBytes = rawBytes.Skip(index).Take(shellPropertySheetListSize).ToArray();
                var propStore = new PropertyStore(propBytes);

                PropertyStore = propStore;

                var p = propStore.Sheets.Where(t => t.PropertyNames.ContainsKey("32"));

                if (p.Any())
                {
                    //we can now look thry prop bytes for extension blocks
                    //TODO this is a hack until we can process vectors natively

                    var extOffsets = new List<int>();
                    try
                    {
                        var regexObj = new Regex("([0-9A-F]{2})-00-EF-BE", RegexOptions.IgnoreCase);
                        var matchResult = regexObj.Match(BitConverter.ToString(propBytes));
                        while (matchResult.Success)
                        {
                            extOffsets.Add(matchResult.Index);
                            matchResult = matchResult.NextMatch();
                        }

                        foreach (var extOffset in extOffsets)
                        {
                            var binaryOffset = extOffset/3 - 4;
                            var exSize = BitConverter.ToInt16(propBytes, binaryOffset);

                            var exBytes = propBytes.Skip(binaryOffset).Take(exSize).ToArray();

                            var signature1 = BitConverter.ToUInt32(exBytes, 4);


                            var block1 = Utils.GetExtensionBlockFromBytes(signature1, exBytes);

                            ExtensionBlocks.Add(block1);
                        }
                    }
                    catch (ArgumentException ex)
                    {
                        throw ex;
                        // Syntax error in the regular expression
                    }

                }
            }
            else
            {

                if (rawBytes[0x28] == 0x2f ||
                    (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
                {
                    //we have a good date

                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
                Debug.Write("Oh no! No property sheets!");
            }

            index += shellPropertySheetListSize;

            index += 2; //move past end of property sheet terminator

            var rawguid = Utils.ExtractGuidFromShellItem(rawBytes.Skip(index).Take(16).ToArray());
            index += 16;

            rawguid = Utils.ExtractGuidFromShellItem(rawBytes.Skip(index).Take(16).ToArray());
            index += 16;

            var name = Utils.GetFolderNameFromGuid(rawguid);

            Value = name;

            var extBlockSize = BitConverter.ToInt16(rawBytes, index);

            if (extBlockSize > 0)
            {
                //process extension blocks

                while (extBlockSize > 0)
                {
                    var extBytes = rawBytes.Skip(index).Take(extBlockSize).ToArray();

                    index += extBlockSize;

                    var signature1 = BitConverter.ToUInt32(extBytes, 4);


                    var block1 = Utils.GetExtensionBlockFromBytes(signature1, extBytes);

                    ExtensionBlocks.Add(block1);

                    extBlockSize = BitConverter.ToInt16(rawBytes, index);
                }
            }

            int terminator = BitConverter.ToInt16(rawBytes, index);

            if (terminator > 0)
            {
                throw new Exception($"Expected terminator of 0, but got {terminator}");
            }
        }
コード例 #16
0
ファイル: ShellBag0x31.cs プロジェクト: EricZimmerman/Lnk
        public ShellBag0X31( byte[] rawBytes)
        {
            FriendlyName = "Directory";


            ExtensionBlocks = new List<IExtensionBlock>();


            var index = 2;
            if ((rawBytes[0x27] == 0x00 && rawBytes[0x28] == 0x2f && rawBytes[0x29] == 0x00) ||
                (rawBytes[0x24] == 0x4e && rawBytes[0x26] == 0x2f && rawBytes[0x28] == 0x41))
            {
                //we have a good date

                try
                {
                    var zip = new ShellBagZipContents(rawBytes);
                    FriendlyName = zip.FriendlyName;
                    LastAccessTime = zip.LastAccessTime;

                    Value = zip.Value;

                    return;
                }
                catch (Exception)
                {
                    //this isnt really this kind of entry despite our best efforts to make sure it is, so fall thru and process normally
                }
            }

            index += 1;

            //skip unknown byte
            index += 1;

            index += 4; // skip file size since always 0 for directory

            LastModificationTime = Utils.ExtractDateTimeOffsetFromBytes(rawBytes.Skip(index).Take(4).ToArray());

            index += 4;

            index += 2;

            var len = 0;

            var beefPos = BitConverter.ToString(rawBytes).IndexOf("04-00-EF-BE", StringComparison.InvariantCulture)/3;
            beefPos = beefPos - 4; //add header back for beef

            var strLen = beefPos - index;

            if (rawBytes[2] == 0x35)
            {
                len = strLen;
            }
            else
            {
                while (rawBytes[index + len] != 0x0)
                {
                    len += 1;
                }
            }


            var tempBytes = new byte[len];
            Array.Copy(rawBytes, index, tempBytes, 0, len);

            index += len;

            var shortName = "";

            if (rawBytes[2] == 0x35)
            {
                shortName = Encoding.Unicode.GetString(tempBytes);
            }
            else
            {
                shortName = Encoding.GetEncoding(1252).GetString(tempBytes);
            }

            ShortName = shortName;

            Value = shortName;

            while (rawBytes[index] == 0x0)
            {
                index += 1;
            }

            // here is where we need to cut up the rest into extension blocks
            var chunks = new List<byte[]>();

            while (index < rawBytes.Length)
            {
                var subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

                if (subshellitemdatasize == 1)
                {
                    //some kind of separator
                    index += 2;
                }
                else
                {
                    chunks.Add(rawBytes.Skip(index).Take(subshellitemdatasize).ToArray());
                    index += subshellitemdatasize;
                }
            }

            foreach (var bytes in chunks)
            {
                index = 0;

                var extsize = BitConverter.ToInt16(bytes, index);

                var signature = BitConverter.ToUInt32(bytes, 0x04);

                //TODO does this need to check if its a 0xbeef?? regex?
                var block = Utils.GetExtensionBlockFromBytes(signature, bytes);

                if (block.Signature.ToString("X").StartsWith("BEEF00"))
                {
                    ExtensionBlocks.Add(block);
                }


                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    Value = beef0004.LongName;
                }

                var beef0005 = block as Beef0005;
                if (beef0005 != null)
                {
                    //TODO Resolve this
//                    foreach (var internalBag in beef0005.InternalBags)
//                    {
//                        ExtensionBlocks.Add(new BeefPlaceHolder(null));
//
//
//                    }
                }

                index += extsize;
            }
        }