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 !!!"; } }
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; } }
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; } }
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; } }
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; }
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; }
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}"); } }
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; }
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}"); } }
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; } }
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 = CodePagesEncodingProvider.Instance.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; } }
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; } }