59 lines
2.3 KiB
C#
59 lines
2.3 KiB
C#
using WxAgent.Core;
|
|
|
|
namespace WxAgent.Windows;
|
|
|
|
public sealed record AccountDatabaseFile(string FullPath, string RelativePath, byte[] FirstPage, string Salt);
|
|
|
|
public sealed record AccountDatabaseRoot(string AccountRootPath, string Fingerprint, IReadOnlyList<AccountDatabaseFile> Databases);
|
|
|
|
public static class WechatDatabaseDiscovery
|
|
{
|
|
public static IReadOnlyList<AccountDatabaseRoot> FindAccountRoots(
|
|
string? xwechatFilesRoot = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
var root = xwechatFilesRoot ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "xwechat_files");
|
|
if (!Directory.Exists(root))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
var accounts = new List<AccountDatabaseRoot>();
|
|
foreach (var accountDirectory in Directory.EnumerateDirectories(root))
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
var dbStorage = Path.Combine(accountDirectory, "db_storage");
|
|
if (!Directory.Exists(dbStorage))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var databases = new List<AccountDatabaseFile>();
|
|
foreach (var path in Directory.EnumerateFiles(dbStorage, "*.db", SearchOption.AllDirectories))
|
|
{
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
try
|
|
{
|
|
var page = new byte[SqlCipherPageVerifier.PageSize];
|
|
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
|
|
stream.ReadExactly(page);
|
|
|
|
var relativePath = Path.GetRelativePath(dbStorage, path).Replace('\\', '/');
|
|
databases.Add(new AccountDatabaseFile(path, relativePath, page, Convert.ToHexString(page.AsSpan(0, SqlCipherPageVerifier.SaltSize)).ToLowerInvariant()));
|
|
}
|
|
catch (IOException)
|
|
{
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
}
|
|
}
|
|
|
|
accounts.Add(new AccountDatabaseRoot(dbStorage, AccountRootFingerprint.Create(dbStorage), databases));
|
|
}
|
|
|
|
return accounts;
|
|
}
|
|
}
|