⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootencryption.cpp

📁 使用visual studio 2005 开发的开源文件、磁盘加密软件。这是6.1a版。加密自己资料的好工具。也是学习的优秀范本。结成了众多加密算法。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		device.SeekAt (0);
		device.Write (mbr, sizeof (mbr));

		byte mbrVerificationBuf[SECTOR_SIZE];
		device.SeekAt (0);
		device.Read (mbrVerificationBuf, sizeof (mbr));

		if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
			throw ErrorException ("ERROR_MBR_PROTECTED");
	}


	unsigned int BootEncryption::GetHiddenOSCreationPhase ()
	{
		byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];

		ReadBootSectorConfig (configFlags, sizeof(configFlags));

		return (configFlags[0] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE);
	}


	void BootEncryption::SetHiddenOSCreationPhase (unsigned int newPhase)
	{
#if TC_BOOT_CFG_FLAG_AREA_SIZE != 1
#	error TC_BOOT_CFG_FLAG_AREA_SIZE != 1; revise GetHiddenOSCreationPhase() and SetHiddenOSCreationPhase()
#endif
		byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];

		ReadBootSectorConfig (configFlags, sizeof(configFlags));

		configFlags[0] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;

		configFlags[0] |= newPhase;

		WriteBootSectorConfig (configFlags);
	}


#ifndef SETUP

	void BootEncryption::StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm)
	{
		if (!IsHiddenOSRunning())
			throw ParameterIncorrect (SRC_POS);

		WipeDecoySystemRequest request;
		ZeroMemory (&request, sizeof (request));

		request.WipeAlgorithm = wipeAlgorithm;
		
		if (Randinit() != ERR_SUCCESS)
			throw ParameterIncorrect (SRC_POS);

		if (!RandgetBytes (request.WipeKey, sizeof (request.WipeKey), TRUE))
			throw ParameterIncorrect (SRC_POS);

		CallDriver (TC_IOCTL_START_DECOY_SYSTEM_WIPE, &request, sizeof (request), NULL, 0);

		burn (&request, sizeof (request));
	}


	void BootEncryption::AbortDecoyOSWipe ()
	{
		CallDriver (TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE);
	}

	
	DecoySystemWipeStatus BootEncryption::GetDecoyOSWipeStatus ()
	{
		DecoySystemWipeStatus status;
		CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS, NULL, 0, &status, sizeof (status));
		return status;
	}


	void BootEncryption::CheckDecoyOSWipeResult ()
	{
		CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT);
	}


	void BootEncryption::WipeHiddenOSCreationConfig ()
	{
		if (IsHiddenOSRunning() || Randinit() != ERR_SUCCESS)
			throw ParameterIncorrect (SRC_POS);

		Device device (GetSystemDriveConfiguration().DevicePath);
		byte mbr[SECTOR_SIZE];

		device.SeekAt (0);
		device.Read (mbr, sizeof (mbr));
		
		finally_do_arg (BootEncryption *, this,
		{
			try
			{
				finally_arg->SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
			} catch (...) { }
		});

#if PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE
#	error PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE
#endif

		byte randData[PRAND_DISK_WIPE_PASSES];
		if (!RandgetBytes (randData, sizeof (randData), FALSE))
			throw ParameterIncorrect (SRC_POS);

		for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
		{
			for (int i = 0; i < TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE; ++i)
			{
				mbr[TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + i] = randData[wipePass];
			}

			mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
			mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] |= randData[wipePass] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;

			if (wipePass == PRAND_DISK_WIPE_PASSES - 1)
				memset (mbr + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, 0, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE);

			device.SeekAt (0);
			device.Write (mbr, sizeof (mbr));
		}

		for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES/4 + 1; wipePass++)
		{
			SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
			SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_CLONING);
			SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPING);
			SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPED);
		}
		SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
	}

#endif // !SETUP


	void BootEncryption::InstallBootLoader (bool preserveUserConfig, bool hiddenOSCreation)
	{
		byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
		CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation);

		// Write MBR
		Device device (GetSystemDriveConfiguration().DevicePath);
		byte mbr[SECTOR_SIZE];

		device.SeekAt (0);
		device.Read (mbr, sizeof (mbr));

		if (preserveUserConfig)
		{
			uint16 version = BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET));
			if (version != 0)
			{
				bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
				memcpy (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
			}
		}

		memcpy (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE);

		device.SeekAt (0);
		device.Write (mbr, sizeof (mbr));

		byte mbrVerificationBuf[SECTOR_SIZE];
		device.SeekAt (0);
		device.Read (mbrVerificationBuf, sizeof (mbr));

		if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
			throw ErrorException ("ERROR_MBR_PROTECTED");

		// Write boot loader
		device.SeekAt (SECTOR_SIZE);
		device.Write (bootLoaderBuf + SECTOR_SIZE, sizeof (bootLoaderBuf) - SECTOR_SIZE);
	}


	string BootEncryption::GetSystemLoaderBackupPath ()
	{
		char pathBuf[MAX_PATH];

		throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf)));
		
		string path = string (pathBuf) + "\\" TC_APP_NAME;
		CreateDirectory (path.c_str(), NULL);

		return path + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME;
	}


	void BootEncryption::RenameDeprecatedSystemLoaderBackup ()
	{
		char pathBuf[MAX_PATH];

		if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA, NULL, 0, pathBuf)))
		{
			string path = string (pathBuf) + "\\" TC_APP_NAME + '\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY;

			if (FileExists (path.c_str()) && !FileExists (GetSystemLoaderBackupPath().c_str()))
				throw_sys_if (rename (path.c_str(), GetSystemLoaderBackupPath().c_str()) != 0);
		}
	}


#ifndef SETUP
	void BootEncryption::CreateRescueIsoImage (bool initialSetup, const string &isoImagePath)
	{
		BootEncryptionStatus encStatus = GetStatus();
		if (encStatus.SetupInProgress)
			throw ParameterIncorrect (SRC_POS);

		Buffer imageBuf (RescueIsoImageSize);
		
		byte *image = imageBuf.Ptr();
		memset (image, 0, RescueIsoImageSize);

		// Primary volume descriptor
		strcpy ((char *)image + 0x8000, "\001CD001\001");
		strcpy ((char *)image + 0x7fff + 41, "TrueCrypt Rescue Disk           ");
		*(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048;
		*(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048);
		image[0x7fff + 121] = 1;
		image[0x7fff + 124] = 1;
		image[0x7fff + 125] = 1;
		image[0x7fff + 128] = 1;
		image[0x7fff + 130] = 8;
		image[0x7fff + 131] = 8;

		image[0x7fff + 133] = 10;
		image[0x7fff + 140] = 10;
		image[0x7fff + 141] = 0x14;
		image[0x7fff + 157] = 0x22;
		image[0x7fff + 159] = 0x18;

		// Boot record volume descriptor
		strcpy ((char *)image + 0x8801, "CD001\001EL TORITO SPECIFICATION");
		image[0x8800 + 0x47] = 0x19;

		// Volume descriptor set terminator
		strcpy ((char *)image + 0x9000, "\377CD001\001");

		// Path table
		image[0xA000 + 0] = 1;
		image[0xA000 + 2] = 0x18;
		image[0xA000 + 6] = 1;

		// Root directory
		image[0xc000 + 0] = 0x22;
		image[0xc000 + 2] = 0x18;
		image[0xc000 + 9] = 0x18;
		image[0xc000 + 11] = 0x08;
		image[0xc000 + 16] = 0x08;
		image[0xc000 + 25] = 0x02;
		image[0xc000 + 28] = 0x01;
		image[0xc000 + 31] = 0x01;
		image[0xc000 + 32] = 0x01;
		image[0xc000 + 34] = 0x22;
		image[0xc000 + 36] = 0x18;
		image[0xc000 + 43] = 0x18;
		image[0xc000 + 45] = 0x08;
		image[0xc000 + 50] = 0x08;
		image[0xc000 + 59] = 0x02;
		image[0xc000 + 62] = 0x01;
		*(uint32 *) (image + 0xc000 + 65) = 0x010101;

		// Validation entry
		image[0xc800] = 1;
		int offset = 0xc800 + 0x1c;
		image[offset++] = 0xaa;
		image[offset++] = 0x55;
		image[offset++] = 0x55;
		image[offset] = 0xaa;

		// Initial entry
		offset = 0xc820;
		image[offset++] = 0x88;
		image[offset++] = 2;
		image[0xc820 + 6] = 1;
		image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR;

		// TrueCrypt Boot Loader
		CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true);

		// Volume header
		if (initialSetup)
		{
			if (!RescueVolumeHeaderValid)
				throw ParameterIncorrect (SRC_POS);

			memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
		}
		else
		{
			Device bootDevice (GetSystemDriveConfiguration().DevicePath, true);
			bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
			bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
		}

		// Original system loader
		try
		{
			File sysBakFile (GetSystemLoaderBackupPath(), true);
			sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE);
			
			image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER;
		}
		catch (Exception &e)
		{
			e.Show (ParentWindow);
			Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK");
		}
		
		// Boot loader backup
		CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false);

		RescueIsoImage = new byte[RescueIsoImageSize];
		if (!RescueIsoImage)
			throw bad_alloc();
		memcpy (RescueIsoImage, image, RescueIsoImageSize);

		if (!isoImagePath.empty())
		{
			File isoFile (isoImagePath, false, true);
			isoFile.Write (image, RescueIsoImageSize);
		}
	}
#endif

	bool BootEncryption::VerifyRescueDisk ()
	{
		if (!RescueIsoImage)
			throw ParameterIncorrect (SRC_POS);

		for (char drive = 'Z'; drive >= 'D'; --drive)
		{
			try
			{
				string path = "X:";
				path[0] = drive;

				Device driveDevice (path, true);
				size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048;
				Buffer buffer ((verifiedSectorCount + 1) * 2048);

				DWORD bytesRead = driveDevice.Read (buffer.Ptr(), buffer.Size());
				if (bytesRead != buffer.Size())
					continue;

				if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0)
					return true;
			}
			catch (...) { }
		}

		return false;
	}


#ifndef SETUP

	void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5)
	{
		PCRYPTO_INFO cryptoInfo = NULL;

		throw_sys_if (Randinit () != 0);
		throw_sys_if (CreateVolumeHeaderInMemory (TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, NULL, &cryptoInfo,
			volumeSize, 0, encryptedAreaStart, 0, TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION, TC_HEADER_FLAG_ENCRYPTED_SYSTEM, FALSE) != 0);

		finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); });

		// Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize)
		memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader));
		ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, NULL, cryptoInfo);

		DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

		if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x54525545)
			throw ParameterIncorrect (SRC_POS);

		byte *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH;
		mputInt64 (fieldPos, volumeSize);

		// CRC of the header fields
		uint32 crc = GetCrc32 (RescueVolumeHeader + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
		fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_HEADER_CRC;
		mputLong (fieldPos, crc);

		EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo);

		VolumeHeaderValid = true;
		RescueVolumeHeaderValid = true;
	}


	void BootEncryption::InstallVolumeHeader ()
	{
		if (!VolumeHeaderValid)
			throw ParameterIncorrect (SRC_POS);

		Device device (GetSystemDriveConfiguration().DevicePath);

		device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
		device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader));
	}


	// For synchronous operations use AbortSetupWait()
	void BootEncryption::AbortSetup ()
	{
		CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
	}


	// For asynchronous operations use AbortSetup()
	void BootEncryption::AbortSetupWait ()
	{
		CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);

		BootEncryptionStatus encStatus = GetStatus();

		while (encStatus.SetupInProgress)
		{
			Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL);
			encStatus = GetStatus();
		}
	}


	void BootEncryption::BackupSystemLoader ()
	{
		Device device (GetSystemDriveConfiguration().DevicePath, true);
	
		byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];

		device.SeekAt (0);
		device.Read (bootLoaderBuf, sizeof (bootLoaderBuf));

		// Prevent TrueCrypt loader from being backed up
		for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i)
		{
			if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
			{
				if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED") == IDNO)
					throw UserAbort (SRC_POS);
				return;
			}
		}

		File backupFile (GetSystemLoaderBackupPath(), false, true);
		backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
	}


	void BootEncryption::RestoreSystemLoader ()
	{
		byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * SECTOR_SIZE];

		File backupFile (GetSystemLoaderBackupPath(), true);
		
		if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf))
			throw ParameterIncorrect (SRC_POS);

		Device device (GetSystemDriveConfiguration().DevicePath);

		// Preserve current partition table
		byte mbr[SECTOR_SIZE];
		device.SeekAt (0);
		device.Read (mbr, sizeof (mbr));
		memcpy (bootLoaderBuf + TC_MAX_MBR_BOOT_CODE_SIZE, mbr + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbr) - TC_MAX_MBR_BOOT_CODE_SIZE);

		device.SeekAt (0);
		device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
	}

#endif // SETUP

	void BootEncryption::RegisterDeviceClassFilter (bool registerFilter, const GUID *deviceClassGuid)
	{
		HKEY classRegKey = SetupDiOpenClassRegKey (deviceClassGuid, KEY_READ | KEY_WRITE);
		throw_sys_if (classRegKey == INVALID_HANDLE_VALUE);
		finally_do_arg (HKEY, classRegKey, { RegCloseKey (finally_arg); });

		if (registerFilter)
		{
			// Register class filter below all other filters in the stack

			size_t strSize = strlen ("truecrypt") + 1;
			byte regKeyBuf[65536];
			DWORD size = sizeof (regKeyBuf) - strSize;

			// SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly
			strncpy ((char *) regKeyBuf, "truecrypt", sizeof (regKeyBuf));

			if (RegQueryValueEx (classRegKey, "UpperFilters", NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS)
				size = 1;

			throw_sys_if (RegSetValueEx (classRegKey, "UpperFilters", 0, REG_MULTI_SZ, regKeyBuf, strSize + size) != ERROR_SUCCESS);
		}
		else
		{
			// Unregister a class filter
			string infFileName = GetTempPath() + "\\truecrypt_device_filter.inf";

			File infFile (infFileName, false, true);
			finally_do_arg (string, infFileName, { DeleteFile (finally_arg.c_str()); });

			string infTxt = "[truecrypt]\r\n"
							"DelReg=truecrypt_reg\r\n\r\n"
							"[truecrypt_reg]\r\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -