コード例 #1
0
ファイル: ShellBagCDBurn.cs プロジェクト: theCanary/Lnk
        public ShellBagCDBurn(byte[] rawBytes)
        {
            ShortName = string.Empty;

            PropertyStore = new PropertyStore();


            ExtensionBlocks = new List <IExtensionBlock>();


            FriendlyName = "CDBurn";

            var index = 8; //reset index to after signature

            index += 4;    //skip 4 unknown
            index += 4;    //skip 4 unknown
            index += 4;    //skip 4 unknown

            var chunks = new List <byte[]>();

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

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

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

            var oldIndex = index;

            //if (chunks.Count != 2)
            //{
            //    Debug.WriteLine(chunks.Count);
            //}

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

                var typeIndicator = bytes[index];
                index += 1;
                index += 1; //skip unknown empty value

                var filesize = BitConverter.ToInt32(rawBytes, index);
                index += 4;

                FileSize = filesize;

                var modDate =
                    Utils.ExtractDateTimeOffsetFromBytes(bytes.Skip(index).Take(4).ToArray());

                LastModificationTime = modDate;

                index += 4;

                index += 2; //skip 2 bytes for file attributes

                var len = 0;

                var shortName = string.Empty;

                //get position of beef0004

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

                var strLen = beefPos - index;

                if (typeIndicator == 0x35)
                {
                    //unicode
                    var tempString = Encoding.Unicode.GetString(bytes, index, strLen - 2);

                    shortName = tempString;
                    index    += strLen;
                }
                else
                {
                    //ascii

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

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

                    index    += len;
                    shortName = Encoding.ASCII.GetString(tempBytes);
                }


                ShortName = shortName;

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

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

                var signature = BitConverter.ToUInt32(bytes, index + 4);

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

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    CreatedOnTime  = beef0004.CreatedOnTime;
                    LastAccessTime = beef0004.LastAccessTime;
                    Value          = beef0004.LongName;
                }
                else
                {
                    Value = "!!! Unable to determine Value !!!";
                }
            }

            if (oldIndex + 5 < rawBytes.Length)
            {
                index = oldIndex + 2;

                _extraBag = new ShellBag0X31(rawBytes.Skip(index).ToArray());

                foreach (var ex in _extraBag.ExtensionBlocks)
                {
                    ExtensionBlocks.Add(new BeefPlaceHolder(null));
                }
            }
        }
コード例 #2
0
ファイル: ShellBagCDBurn.cs プロジェクト: EricZimmerman/Lnk
        public ShellBagCDBurn(byte[] rawBytes)
        {
            

            ShortName = string.Empty;

            PropertyStore = new PropertyStore();

            

            ExtensionBlocks = new List<IExtensionBlock>();


            FriendlyName = "CDBurn";

            int index = 8; //reset index to after signature

            index += 4; //skip 4 unknown
            index += 4; //skip 4 unknown
            index += 4; //skip 4 unknown

            var chunks = new List<byte[]>();

            while (index < rawBytes.Length)
            {
                short subshellitemdatasize = BitConverter.ToInt16(rawBytes, index);
                index += 2;

                if (subshellitemdatasize <= 0)
                {
                    break;
                }

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

            var oldIndex = index;

            //if (chunks.Count != 2)
            //{
            //    Debug.WriteLine(chunks.Count);
            //}

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

                byte typeIndicator = bytes[index];
                index += 1;
                index += 1; //skip unknown empty value

                int filesize = BitConverter.ToInt32(rawBytes, index);
                index += 4;

                FileSize = filesize;

                DateTimeOffset? modDate =
                    Utils.ExtractDateTimeOffsetFromBytes(bytes.Skip(index).Take(4).ToArray());

                LastModificationTime = modDate;

                index += 4;

                index += 2; //skip 2 bytes for file attributes

                int len = 0;

                string shortName = string.Empty;

                //get position of beef0004

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

                var strLen = beefPos - index;

                if (typeIndicator == 0x35)
                {
                    //unicode
                    var tempString = Encoding.Unicode.GetString(bytes,index, strLen - 2);

                    shortName = tempString;
                    index += strLen;
                }
                else
                {
                    //ascii

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

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

                    index += len;
                    shortName = Encoding.ASCII.GetString(tempBytes);
                }




                ShortName = shortName;

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

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

                var signature = BitConverter.ToUInt32(bytes, index + 4);

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

                ExtensionBlocks.Add(block);

                var beef0004 = block as Beef0004;
                if (beef0004 != null)
                {
                    CreatedOnTime = beef0004.CreatedOnTime;
                    LastAccessTime = beef0004.LastAccessTime;
                    Value = beef0004.LongName;
                }
                else
                {
                    Value = "!!! Unable to determine Value !!!";
                }
            }

            if (oldIndex+5 < rawBytes.Length)
            {
                index = oldIndex + 2;

                _extraBag = new ShellBag0X31(rawBytes.Skip(index).ToArray());

                foreach (var ex in _extraBag.ExtensionBlocks)
                {
                    ExtensionBlocks.Add(new BeefPlaceHolder(null));
                }
            }
      
        }
コード例 #3
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");
                }
            }
        }
コード例 #4
0
        public VistaAndAboveIdListDataBlock(byte[] rawBytes)
        {
            Signature = ExtraDataTypes.VistaAndAboveIdListDataBlock;

            Size = BitConverter.ToUInt32(rawBytes, 0);

            var index = 8;
            //process shell items
            var shellItemSize = BitConverter.ToInt16(rawBytes, index);

            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;
            }


            TargetIDs = new List<ShellBag>();

            foreach (var bytese in shellItemsRaw)
            {
                switch (bytese[2])
                {
                    case 0x1f:
                        var f = new ShellBag0X1F(bytese);
                        TargetIDs.Add(f);
                        break;

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

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

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

                    case 0x41:
                    case 0x42:
                    case 0x43:
                    case 0x46:
                    case 0x47:
                        var forty = new ShellBag0X40(bytese);
                        TargetIDs.Add(forty);
                        break;
                    default:
                        throw new Exception($"Unknown item ID: 0x{bytese[2]:X}");
                }
            }
        }