Created
May 27, 2017 04:39
-
-
Save hfiref0x/9c3120f630241304699ecd7d93446d5f to your computer and use it in GitHub Desktop.
BitLocker detect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define BITLOCKER_SIGNATURE "-FVE-FS-" | |
#define BITLOCKER_SIGNATURE_SIZE sizeof(BITLOCKER_SIGNATURE) | |
#pragma pack(push,1) | |
typedef struct _FVEFS_BOOT_RECORD { | |
BYTE JumpCode[3]; //+0x0 | |
BYTE Signature[8]; //+0x3 | |
WORD SectorSize; //+0xB | |
BYTE SectorsPerCluster; //+0xD | |
WORD ReservedClusters; //+0xE | |
BYTE FatCount; //+0x10 | |
WORD RootEntries; //+0x11 | |
WORD Reserved1; //+0x13 | |
BYTE MediaDescriptor; //+0x15 | |
WORD SectorsPerFat; //+0x16 | |
WORD SectorsPerTrack; //+0x18 | |
WORD NumberOfHeads; //+0x1A | |
DWORD HiddenSectors; //+0x1C | |
DWORD Reserved2; //+0x20 | |
BYTE Reserved3[4]; //+0x24 | |
UINT64 Reserved4; //+0x28 | |
UINT64 MFTStartCluster; //+0x30 | |
union { //+0x38 | |
UINT64 MetaDataLcn; | |
UINT64 MftMirror; | |
}; | |
//incomplete | |
} FVEFS_BOOT_RECORD, *PFVEFS_BOOT_RECORD; | |
#pragma pack(pop) | |
/* | |
* supIsBitLockerVolume | |
* | |
* Purpose: | |
* | |
* Detect if the given volume is BitLocker encrypted. | |
* | |
* Remarks: | |
* | |
* Elevation required. | |
* | |
*/ | |
BOOL supIsBitLockerVolume( | |
_In_ LPWSTR lpVolume | |
) | |
{ | |
BOOL bResult = FALSE, bIoCtl = FALSE, bCond = FALSE; | |
HANDLE hVolume = NULL, hDisk = NULL; | |
DWORD BytesNeeded = 0; | |
NTSTATUS Status; | |
OBJECT_ATTRIBUTES Obja; | |
IO_STATUS_BLOCK IoSB; | |
UNICODE_STRING uStr; | |
PFVEFS_BOOT_RECORD BootRecord; | |
PVOLUME_DISK_EXTENTS VDExt; | |
BYTE DataBuffer[512]; | |
WCHAR szPhysicalDrive[100]; | |
PBYTE DiskData = NULL; | |
DWORD DiskDataSize = 0, c = 0, LastError = 0; | |
LARGE_INTEGER ByteOffset; | |
do { | |
// | |
// Open volume. | |
// | |
uStr.Buffer = NULL; | |
RtlInitUnicodeString(&uStr, lpVolume); | |
InitializeObjectAttributes(&Obja, &uStr, OBJ_CASE_INSENSITIVE, NULL, NULL); | |
Status = NtCreateFile(&hVolume, | |
GENERIC_READ | SYNCHRONIZE, | |
&Obja, | |
&IoSB, | |
NULL, | |
0, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
FILE_OPEN, | |
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, | |
NULL, | |
0); | |
if (!NT_SUCCESS(Status)) | |
break; | |
// | |
// Query volume offset. | |
// | |
DiskDataSize = 4096; | |
do { | |
DiskData = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, | |
HEAP_ZERO_MEMORY, DiskDataSize); | |
if (DiskData == NULL) | |
break; | |
DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, | |
NULL, | |
0, | |
DiskData, | |
DiskDataSize, | |
&BytesNeeded, | |
NULL); | |
LastError = GetLastError(); | |
if (LastError == ERROR_MORE_DATA) { | |
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, | |
0, | |
DiskData); | |
DiskData = NULL; | |
DiskDataSize *= 2; | |
c++; | |
if (c > 5) | |
break; | |
} | |
} while (LastError == ERROR_MORE_DATA); | |
NtClose(hVolume); | |
hVolume = NULL; | |
if (DiskData == NULL) | |
break; | |
// | |
// Open disk as physical device. | |
// | |
VDExt = (PVOLUME_DISK_EXTENTS)DiskData; | |
_strcpy(szPhysicalDrive, L"\\??\\PhysicalDrive"); | |
ultostr(VDExt->Extents[0].DiskNumber, _strend(szPhysicalDrive)); | |
ByteOffset = VDExt->Extents[0].StartingOffset; | |
uStr.Buffer = NULL; | |
RtlInitUnicodeString(&uStr, szPhysicalDrive); | |
InitializeObjectAttributes(&Obja, &uStr, OBJ_CASE_INSENSITIVE, NULL, NULL); | |
Status = NtCreateFile(&hDisk, | |
GENERIC_READ | SYNCHRONIZE, | |
&Obja, | |
&IoSB, | |
NULL, | |
0, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
FILE_OPEN, | |
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, | |
NULL, | |
0); | |
if (!NT_SUCCESS(Status)) | |
break; | |
// | |
// Read Volume boot record. | |
// | |
Status = NtReadFile(hDisk, | |
NULL, | |
NULL, | |
NULL, | |
&IoSB, | |
DataBuffer, | |
sizeof(DataBuffer), | |
&ByteOffset, | |
NULL); | |
NtClose(hDisk); | |
hDisk = NULL; | |
if (!NT_SUCCESS(Status)) | |
break; | |
BootRecord = (PFVEFS_BOOT_RECORD)DataBuffer; | |
// | |
// Is BitLocker volume? | |
// | |
bResult = (_strncmpi_a(BootRecord->Signature, | |
BITLOCKER_SIGNATURE, | |
BITLOCKER_SIGNATURE_SIZE) == 0); | |
} while (bCond); | |
if (hVolume != NULL) NtClose(hVolume); | |
if (hDisk != NULL) NtClose(hDisk); | |
if (DiskData != NULL) | |
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DiskData); | |
return bResult; | |
} | |
void main() | |
{ | |
LPWSTR lpSystemRoot, lpVolume; | |
WCHAR szVolume[MAX_PATH * 2]; | |
RtlSecureZeroMemory(szVolume, sizeof(szVolume)); | |
lpSystemRoot = (LPWSTR)&USER_SHARED_DATA->NtSystemRoot; | |
_strcpy(szVolume, L"\\??\\"); | |
lpVolume = _strend(szVolume); | |
while (*lpSystemRoot != 0) { | |
if (*lpSystemRoot == L'\\') | |
break; | |
*lpVolume = *lpSystemRoot; | |
lpVolume++; | |
lpSystemRoot++; | |
} | |
if (supIsBitLockerVolume(szVolume)) | |
MessageBox(GetDesktopWindow(), TEXT("Volume is Bitlocker encrypted"), szVolume, MB_OK); | |
ExitProcess(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment