/*
****************************
***
TrueCrypt Format 分析
***
****************************
*/
TrueCrypt分为两部分:一部分是TrueCrypt Format,用来创建加密卷.
另一部分是 TrueCrypt Mount,用来Mount/DisMount虚拟磁盘到分区.
1.TrueCrypt Format
打开 TrueCrypt Format.exe程序,会出现一个创建加密卷的向导,
一共会出现加密卷位置,加密卷的类型,加密卷大小,加密算法,加密格式化等参数.
这些选项最终会保存在一个名为FORMAT_VOL_PARAMETERS的结构中.
typedef struct
{
BOOL bDevice; // 是否为一个分区卷
BOOL hiddenVol;// 是否为一个隐藏卷
char *volumePath;//用户选择的加密卷文件路径
unsigned __int64 size;// 加密卷大小,(byte为单位)
unsigned __int64 hiddenVolHostSize;// 隐藏加密卷大小(byte为单位)
int ea; //encryption algorithm e.g nVolumeA = 1
int pkcs5;// 哈希算法
uint32 headerFlags; //
int fileSystem;// 文件系统类型
int clusterSize;// 簇(cluster)大小
BOOL sparseFileSwitch;// 是否切换为稀疏文件
BOOL quickFormat;// 是否快速格式化
int sectorSize;// 扇区大小
int *realClusterSize; //
Password *password;// 用户的加密口令
HWND hwndDlg;// 传入的窗口句柄
}FORMAT_VOL_PARAMETERS;
1. MainDlgProc()函数分析
回想一下 TrueCrypt Format.exe这个加密卷向导的界面程序.
该向导由MainDlgProc()这个函数来完成.用户根据自身需要,
设置了上述的这些参数,并保存在全局变量中.
然后调用volTransformThreadFunction()函数,这是实现Format的真正处理函数.
//
// e.g
// 打开 TrueCrypt Format.exe的时候,会出现一个关于加密卷类型的选择
//
/*
@ create a encrypted file container
@ encrypt a non-system Partiton/driver
@ Encrypt the system Partiton or entire system
*/
在MainDlgProc()函数中对应的代码如下:
switch (GetSelectedWizardMode (hCurPage))
{
case WIZARD_MODE_FILE_CONTAINER: // 创建一个加密文件的container
// 省略部分代码....
WaitCursor ();
CloseSysEncMutex ();
ChangeWizardMode (WIZARD_MODE_FILE_CONTAINER);
bHiddenOS = FALSE;// 设置bHiddenOS
bInPlaceEncNonSys = FALSE;
nNewPageNo = VOLUME_TYPE_PAGE - 1; // Skip irrelevant pages
break;
case WIZARD_MODE_NONSYS_DEVICE: // 加密一个非系统盘/分区
WaitCursor ();
CloseSysEncMutex ();
if (!ChangeWizardMode (WIZARD_MODE_NONSYS_DEVICE))
{
NormalCursor ();
return 1;
}
bHiddenOS = FALSE;
nNewPageNo = VOLUME_TYPE_PAGE - 1; // Skip irrelevant pages
break;
case WIZARD_MODE_SYS_DEVICE: // 加密系统盘
WaitCursor ();
bHiddenVol = FALSE;
bInPlaceEncNonSys = FALSE;
SwitchWizardToSysEncMode ();
return 1;
}
}
类似的我们在点击完"NEXT"后,会看到一个关于Standard 和 Hidden 的选择
相应的代码如下:
if (IsButtonChecked (GetDlgItem (hCurPage, IDC_HIDDEN_VOL)))
{
// 选择 HIdden Volume
if (!IsAdmin() && !IsUacSupported ()
&& IDNO == MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_HIDVOL"),
lpszTitle, MB_ICONWARNING|MB_YESNO|MB_DEFBUTTON2))
{
return 1;
}
else
{
// 设置全局变量,这些变量最终会写入FORMAT_VOL_PARAMETERS的结构中.
bHiddenVol = TRUE;
bHiddenVolHost = TRUE;
bInPlaceEncNonSys = FALSE;
}
//省略代码....
}
经过一系列的 next by next ,用户对加密卷的创建做好了选择,也就是设置好了这些全局变量.
然后创建一个线程,调用volTransformThreadFunction()函数.
//...
_beginthread (volTransformThreadFunction, 0, MainDlg);
//...
2.下面看下volTransformThreadFunction()函数,
该函数主要功能是设置好结构 volParams.
然后调用核心函数TcFormatVolume().
static void __cdecl volTransformThreadFunction (void *hwndDlgArg)
{
//省略部分代码...
// 给结构体volParams 分配内存.
volatile FORMAT_VOL_PARAMETERS *volParams = (FORMAT_VOL_PARAMETERS *) malloc (sizeof(FORMAT_VOL_PARAMETERS));
if (volParams == NULL)
AbortProcess ("ERR_MEM_ALLOC");
// 锁定内存
VirtualLock ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS));
//省略部分代码....
// 初始化结构体volParams的成员变量.
bHidden = bHiddenVol && !bHiddenVolHost;
volParams->bDevice = bDevice;
volParams->hiddenVol = bHidden;
volParams->volumePath = szDiskFile;
volParams->size = nVolumeSize;
volParams->hiddenVolHostSize = nHiddenVolHostSize;
volParams->ea = nVolumeEA;
volParams->pkcs5 = hash_algo;
volParams->headerFlags = CreatingHiddenSysVol() ? TC_HEADER_FLAG_ENCRYPTED_SYSTEM : 0;
volParams->fileSystem = fileSystem;
volParams->clusterSize = clusterSize;
volParams->sparseFileSwitch = bSparseFileSwitch;
volParams->quickFormat = quickFormat;
volParams->sectorSize = GetFormatSectorSize();
volParams->realClusterSize = &realClusterSize;
volParams->password = &volumePassword;
volParams->hwndDlg = hwndDlg;
if(bInPlaceEncNonSys)
{
//这部分是讨论给非系统盘加密的操作
//略去...
}
else
{
InitProgressBar (GetVolumeDataAreaSize (bHidden, nVolumeSize), 0, FALSE, FALSE, FALSE, TRUE);
//核心函数 TCFormatVolume(),该函数是通过给驱动发送IOCTL_CODE,真正完成FORMAT操作.
nStatus =TCFormatVolume (volParams);
}
//省略余下代码....
}
3.核心函数TCFormatVolume()的分析参见下篇.