diff --git a/BinaryObjectScanner/Packer/SevenZipSFX.cs b/BinaryObjectScanner/Packer/SevenZipSFX.cs
index 29614da0..71b3495e 100644
--- a/BinaryObjectScanner/Packer/SevenZipSFX.cs
+++ b/BinaryObjectScanner/Packer/SevenZipSFX.cs
@@ -1,10 +1,16 @@
+using System;
+using System.IO;
using System.Linq;
using BinaryObjectScanner.Interfaces;
using SabreTools.Serialization.Wrappers;
+#if NET462_OR_GREATER || NETCOREAPP
+using SharpCompress.Archives;
+using SharpCompress.Archives.SevenZip;
+using SharpCompress.Readers;
+#endif
namespace BinaryObjectScanner.Packer
{
- // TODO: Add extraction
public class SevenZipSFX : IExtractablePortableExecutable, IPortableExecutableCheck
{
///
@@ -47,7 +53,57 @@ namespace BinaryObjectScanner.Packer
///
public string? Extract(string file, PortableExecutable pex, bool includeDebug)
{
+ if (!File.Exists(file))
+ return null;
+
+#if NET462_OR_GREATER || NETCOREAPP
+ try
+ {
+ // Create a temp output directory
+ string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
+ Directory.CreateDirectory(tempPath);
+
+ using (SevenZipArchive sevenZipFile = SevenZipArchive.Open(file, new ReaderOptions() { LookForHeader = true }))
+ {
+ foreach (var entry in sevenZipFile.Entries)
+ {
+ try
+ {
+ // If the entry is a directory
+ if (entry.IsDirectory)
+ continue;
+
+ // If the entry has an invalid key
+ if (entry.Key == null)
+ continue;
+
+ // If we have a partial entry due to an incomplete multi-part archive, skip it
+ if (!entry.IsComplete)
+ continue;
+
+ string tempFile = Path.Combine(tempPath, entry.Key);
+ var directoryName = Path.GetDirectoryName(tempFile);
+ if (directoryName != null && !Directory.Exists(directoryName))
+ Directory.CreateDirectory(directoryName);
+ entry.WriteToFile(tempFile);
+ }
+ catch (Exception ex)
+ {
+ if (includeDebug) Console.WriteLine(ex);
+ }
+ }
+ }
+
+ return tempPath;
+ }
+ catch (Exception ex)
+ {
+ if (includeDebug) Console.WriteLine(ex);
+ return null;
+ }
+#else
return null;
+#endif
}
}
}