如果我想查看所有用C#挂载的卷,那么我将不得不查询真正的crypt驱动程序,因为没有可以发送给TrueCrypt.exe的命令,该命令将向我返回该信息。
因此,如果我想查看所有已安装的卷以及将它们安装到哪个驱动器中,我将调用TrueCryptHelper.GetMountedVolumes();
:
这是代码:
public static class TrueCryptHelper
{
public static Dictionary<char, string> GetMountedVolumes()
{
uint size = (uint)Marshal.SizeOf(typeof(MOUNT_LIST_STRUCT));
IntPtr buffer = Marshal.AllocHGlobal((int)size);
uint bytesReturned;
IntPtr _hdev = CreateFile("\\\\.\\TrueCrypt", FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
bool bResult = DeviceIoControl(_hdev, TC_GET_MOUNTED_VOLUMES, buffer, size, buffer, size, out bytesReturned, IntPtr.Zero);
MOUNT_LIST_STRUCT mount = new MOUNT_LIST_STRUCT();
Marshal.PtrToStructure(buffer, mount);
Marshal.FreeHGlobal(buffer);
Dictionary<char, string> items = new Dictionary<char, string>();
for (int i = 0; i < 26; i++)
{
string filePath = mount.wszVolume[i].ToString().Replace(@"\??\", "");
if (filePath.Length > 2)
{
items[(char)('A' + i)] = filePath;
}
//Console.WriteLine("{0}: => {1}", (char)('A' + i), mount.wszVolume[i]);
}
return items;
}
private static readonly uint TC_GET_DRIVER_VERSION = (uint)CTL_CODE(0x00000022, 0x800 + (01), 0, 0);
private static readonly uint TC_GET_BOOT_LOADER_VERSION = (uint)CTL_CODE(0x00000022, 0x800 + (02), 0, 0);
private static readonly uint TC_MOUNT_VOLUME = (uint)CTL_CODE(0x00000022, 0x800 + (03), 0, 0);
private static readonly uint TC_DISMOUNT_VOLUME = (uint)CTL_CODE(0x00000022, 0x800 + (04), 0, 0);
private static readonly uint TC_DISMOUNT_ALL_VOLUMES = (uint)CTL_CODE(0x00000022, 0x800 + (05), 0, 0);
private static readonly uint TC_GET_MOUNTED_VOLUMES = (uint)CTL_CODE(0x00000022, 0x800 + (06), 0, 0);
private static readonly uint TC_GET_VOLUME_PROPERTIES = (uint)CTL_CODE(0x00000022, 0x800 + (07), 0, 0);
private static readonly uint TC_GET_DEVICE_REFCOUNT = (uint)CTL_CODE(0x00000022, 0x800 + (08), 0, 0);
private static readonly uint TC_WAS_REFERENCED_DEVICE_DELETED = (uint)CTL_CODE(0x00000022, 0x800 + (09), 0, 0);
private static readonly uint TC_IS_ANY_VOLUME_MOUNTED = (uint)CTL_CODE(0x00000022, 0x800 + (10), 0, 0);
private static readonly uint TC_GET_PASSWORD_CACHE_STATUS = (uint)CTL_CODE(0x00000022, 0x800 + (11), 0, 0);
private static readonly uint TC_WIPE_PASSWORD_CACHE = (uint)CTL_CODE(0x00000022, 0x800 + (12), 0, 0);
private static readonly uint TC_OPEN_TEST = (uint)CTL_CODE(0x00000022, 0x800 + (13), 0, 0);
private static readonly uint TC_GET_DRIVE_PARTITION_INFO = (uint)CTL_CODE(0x00000022, 0x800 + (14), 0, 0);
private static readonly uint TC_GET_DRIVE_GEOMETRY = (uint)CTL_CODE(0x00000022, 0x800 + (15), 0, 0);
private static readonly uint TC_PROBE_REAL_DRIVE_SIZE = (uint)CTL_CODE(0x00000022, 0x800 + (16), 0, 0);
private static readonly uint TC_GET_RESOLVED_SYMLINK = (uint)CTL_CODE(0x00000022, 0x800 + (17), 0, 0);
private static readonly uint TC_GET_BOOT_ENCRYPTION_STATUS = (uint)CTL_CODE(0x00000022, 0x800 + (18), 0, 0);
private static readonly uint TC_BOOT_ENCRYPTION_SETUP = (uint)CTL_CODE(0x00000022, 0x800 + (19), 0, 0);
private static readonly uint TC_ABORT_BOOT_ENCRYPTION_SETUP = (uint)CTL_CODE(0x00000022, 0x800 + (20), 0, 0);
private static readonly uint TC_GET_BOOT_ENCRYPTION_SETUP_RESULT = (uint)CTL_CODE(0x00000022, 0x800 + (21), 0, 0);
private static readonly uint TC_GET_BOOT_DRIVE_VOLUME_PROPERTIES = (uint)CTL_CODE(0x00000022, 0x800 + (22), 0, 0);
private static readonly uint TC_REOPEN_BOOT_VOLUME_HEADER = (uint)CTL_CODE(0x00000022, 0x800 + (23), 0, 0);
private static readonly uint TC_GET_BOOT_ENCRYPTION_ALGORITHM_NAME = (uint)CTL_CODE(0x00000022, 0x800 + (24), 0, 0);
private static readonly uint TC_GET_PORTABLE_MODE_STATUS = (uint)CTL_CODE(0x00000022, 0x800 + (25), 0, 0);
private static readonly uint TC_SET_PORTABLE_MODE_STATUS = (uint)CTL_CODE(0x00000022, 0x800 + (26), 0, 0);
private static readonly uint TC_IS_HIDDEN_SYSTEM_RUNNING = (uint)CTL_CODE(0x00000022, 0x800 + (27), 0, 0);
private static readonly uint TC_GET_SYSTEM_DRIVE_CONFIG = (uint)CTL_CODE(0x00000022, 0x800 + (28), 0, 0);
private static readonly uint TC_DISK_IS_WRITABLE = (uint)CTL_CODE(0x00000022, 0x800 + (29), 0, 0);
private static readonly uint TC_START_DECOY_SYSTEM_WIPE = (uint)CTL_CODE(0x00000022, 0x800 + (30), 0, 0);
private static readonly uint TC_ABORT_DECOY_SYSTEM_WIPE = (uint)CTL_CODE(0x00000022, 0x800 + (31), 0, 0);
private static readonly uint TC_GET_DECOY_SYSTEM_WIPE_STATUS = (uint)CTL_CODE(0x00000022, 0x800 + (32), 0, 0);
private static readonly uint TC_GET_DECOY_SYSTEM_WIPE_RESULT = (uint)CTL_CODE(0x00000022, 0x800 + (33), 0, 0);
private static readonly uint TC_WRITE_BOOT_DRIVE_SECTOR = (uint)CTL_CODE(0x00000022, 0x800 + (34), 0, 0);
private static readonly uint TC_IS_SYSTEM_FAVORITE_VOLUME_DIRTY = (uint)CTL_CODE(0x00000022, 0x800 + (35), 0, 0);
private static readonly uint TC_SET_SYSTEM_FAVORITE_VOLUME_DIRTY = (uint)CTL_CODE(0x00000022, 0x800 + (36), 0, 0);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
private class MOUNT_LIST_STRUCT
{
public readonly UInt32 ulMountedDrives; /* Bitfield of all mounted drive letters */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public readonly MOUNT_LIST_STRUCT_VOLUME_NAME[] wszVolume; /* Volume names of mounted volumes */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public readonly UInt64[] diskLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public readonly int[] ea;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public readonly int[] volumeType; /* Volume type (e.g. PROP_VOL_TYPE_OUTER, PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, etc.) */
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
private struct MOUNT_LIST_STRUCT_VOLUME_NAME
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I2, SizeConst = 260)]
public readonly char[] wszVolume; /* Volume names of mounted volumes */
public override string ToString()
{
return (new String(wszVolume)).TrimEnd('\0');
}
}
private static int CTL_CODE(int DeviceType, int Function, int Method, int Access)
{
return (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2)
| (Method));
}
/// <summary>
/// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation.
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363216(v=vs.85).aspx
/// </summary>
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode,
IntPtr lpInBuffer, uint nInBufferSize,
IntPtr lpOutBuffer, uint nOutBufferSize,
out uint lpBytesReturned, IntPtr lpOverlapped);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CreateFile(
[MarshalAs(UnmanagedType.LPTStr)] string filename,
[MarshalAs(UnmanagedType.U4)] FileAccess access,
[MarshalAs(UnmanagedType.U4)] FileShare share,
IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
IntPtr templateFile);
}
注意我正在使用
TC_GET_MOUNTED_VOLUMES
标志。例如,如果我想挂载卷并使用TC_MOUNT_VOLUME
,我将如何指定密码?在哪里可以找到有关如何使用TrueCrypt驱动程序的更多信息?因此,我发现这篇不错的文章:http://stoned-vienna.com/html/index.php?page=abusing-the-truecrypt-driver 最佳答案
实际上,它有点高级,这并不容易,您需要阅读C++代码,理解它并用C#重新编写。我可以为您提供安装代码,但是对于其他功能,您需要了解Truecrypt UI与内核驱动程序的通信方式,并用C#对其进行重写。
关于安装...
1)下载适用于Windows的最新Truecrypt的源代码。
2)找到TrueCryptSource\Common\Dlgcode.c
转到第5963行,您将看到MountVolume函数:
// Use only cached passwords if password = NULL
//
// Returns:
// -1 = user aborted mount / error
// 0 = mount failed
// 1 = mount OK
// 2 = mount OK in shared mode
//
// Note that some code calling this relies on the content of the mountOptions struct
// to remain unmodified (don't remove the 'const' without proper revision).
int MountVolume (HWND hwndDlg,
int driveNo,
char *volumePath,
Password *password,
BOOL cachePassword,
BOOL sharedAccess,
const MountOptions* const mountOptions,
BOOL quiet,
BOOL bReportWrongPassword)
好的,如您所见,此函数接收多个参数并将其发送到内核驱动程序,但是在将它们传递给内核之前,它会更改一些变量,例如,当您输入
volumepath
时,如果其中确实包含“\?\”,该函数在将字符串传递给驱动程序之前将其删除。对于驱动器路径,它使用
VolumeGuidPathToDevicePath
获取该驱动器的完整设备路径(意味着将G:H:I:转换为完整设备路径,例如\Device\Harddisk%d\Partition%d)然后是mount结构,您需要在C#中对其进行重构:
MOUNT_STRUCT mount;
typedef struct
{
int nReturnCode; /* Return code back from driver */
BOOL FilesystemDirty;
BOOL VolumeMountedReadOnlyAfterAccessDenied;
BOOL VolumeMountedReadOnlyAfterDeviceWriteProtected;
wchar_t wszVolume[TC_MAX_PATH]; /* Volume to be mounted */
Password VolumePassword; /* User password */
BOOL bCache; /* Cache passwords in driver */
int nDosDriveNo; /* Drive number to mount */
uint32 BytesPerSector;
BOOL bMountReadOnly; /* Mount volume in read-only mode */
BOOL bMountRemovable; /* Mount volume as removable media */
BOOL bExclusiveAccess; /* Open host file/device in exclusive access mode */
BOOL bMountManager; /* Announce volume to mount manager */
BOOL bPreserveTimestamp; /* Preserve file container timestamp */
BOOL bPartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
int nPartitionInInactiveSysEncScopeDriveNo; /* If bPartitionInInactiveSysEncScope is TRUE, this contains the drive number of the system drive on which the partition is located. */
BOOL SystemFavorite;
// Hidden volume protection
BOOL bProtectHiddenVolume; /* TRUE if the user wants the hidden volume within this volume to be protected against being overwritten (damaged) */
Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
BOOL UseBackupHeader;
BOOL RecoveryMode;
} MOUNT_STRUCT;
您需要用C#重新编写它,然后初始化该结构的新实例,然后设置安装卷所需的所有参数(密码, key 文件等)。
最后,使用您创建的
MOUNT_STRUCT
实例调用驱动程序:bResult = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, &mount,
sizeof (mount), &mount, sizeof (mount), &dwResult, NULL);
就这样,就像
TrueCrypt
一样,不要忘记将密码发送到内核后从内存中擦除密码,为此,TrueCrypt
具有一个名为burn
的函数,也可以在C#中重写它,或者干脆销毁那些由于该卷太敏感,因此持有该卷的密码。除了上面我说的所有内容之外,truecrypt确实具有命令行界面,您可以从命令提示符下挂载卷。您无法使用命令提示符来查看已安装驱动器的列表,因此您需要一个简单的C#代码来列出已安装的卷,但是可以使用命令提示符进行安装:
truecrypt /v myvolume.tc /lx /a /p MyPassword /e /b
关于c# - 通过使用其驱动程序而不是命令提示符来自动化TrueCrypt,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21386827/