Article un peu obsolète car écrit en 2012 prenant l’exemple de truecrypt (retiré du marché en 2014 [1]), et de windows XP (même si l’astuce en compatible avec les versions ultérieures, il doit être possible de faire plus simple).
But
Critique
- Pourquoi voudrait-on protéger quelque chose sans chiffrer ? c’est idiot, c’est une fausse sécurité puisqu’il "suffit" d’obtenir les privilèges admin en bootant sur un liveCD quelconque.
- j’ai écrit ça sous XP, mais ça s’applique à mon avis à Seven et Vista
Avantages
- On peut contrer la critique ci-dessus en chiffrant tout le disque dur (et en mettant un mot de passe sur le bios tant qu’à faire).
- C’est très geek de monter un disque secret sous sa session...
- un malware quelconque (web based attacks ; USB autorun attack ; session laissée ouverte...) aura du mal à voler des fichiers que le système d’exploitation ne voit pas.
- Comme le disque est déjà chiffré, je ne vais quand même pas créer un container truecrypt pour le même résultat : le double chiffrage prend vraiment trois plombes. (Déjà, le simple chiffrage, c’est très perceptible sur les usages intensifs du disque : sortie d’hibernation par ex.)
Comment (théorie) ?
En pratique
- votre session principale windows doit être utilisateur ; vous devez avoir accès à un compte administrateur
- créez une partition primaire (les partitions étendues sont incompatibles sous XP avec truecrypt whole disk encryption ; mais ça passe sous Vista/Seven)
- cf Paragon Partition Manager™ 11 Free par ex., c’est mieux que Partition Magic.
- ne lui donnez pas de point de montage (si c’est déjà le cas, ça se supprime avec le "Gestion des disques" de windows (
C:\WINDOWS\system32\diskmgmt.msc
)

- lancez une console avec les droits admin (ex, créez un raccourci sur cmd.exe, faites clic-droit "éxécuter en tant que", utlilisateur suivant, compte admin) (ou faites le depuis le compte admin)
- tappez
montvol /?

- "aucun point de montage", c’est votre disque secret normalement. Copiez-coller votre ligne ( \\ ?\Volumebbc6926a-8348-11e1-ab7f-080027003cfb\ ici) quelque part, ça va servir (clic droit, sélection, enter).
- faites un test en console
- montage :
mountvol h: \\?\Volume{bbc6926a-8348-11e1-ab7f-080027003cfb}\
(où h : est le point de montage ; on peut mettre un répertoire NTFS vide à la place) - démontage :
mountvol h: /d
Version manuelle (didactique...)
- créez un raccourci sur le bureau avec les commandes ci-dessus
(ça tombe bien, il y a des icones de cadenas dans %SystemRoot%\system32\SHELL32.dll
)- dans (clic droit icone) les options, on peut cocher une touche de raccourci (hotkey) et demander les droits admin (pas très pratique)

- créez une icône de démontage de même (
mountvol h: /d
)
Version automatisée
Un jour j’écrirai un installeur... (bon ok, jamais).
Démonter automatiquement à chaque redémarrage du système
Je discute là différentes pistes, mais j’ai retenu celle de l’écriture d’un service, ce qui marche très bien.
- utiliser l’éditeur de stratégie du groupe local gpedit.msc pour lancer la commande de démontage
- nécessite une version "pro" de windows
- cf ressources en bas de page
- 2e essai : on peut exécuter un service avec les privilèges "system" en pré-logon... (c’est à dire que windows utilisera le plus haut niveau de privilèges pour exécuter notre commande, avant même qu’un utilisateur tape un mot de passe)
- le plus simple est de le lancer via l’outil de microsoft Srvany.exe
- mais c’est plus geek power d’écrire un service
- tutoriel en c http://www.devx.com/cplus/Article/9857
- ce tutoriel est très clair, de grande qualité (et il est indispensable d’en lire les pages 4 et 5 qui expliquent comment installer le service compilé)
- code modifié : cf annexe).
- Ce code est celui du tutoriel dont j’ai mis en commentaires la fonction de logging inutile en pratique, et ajouté la commande d’intérêt.
- la commande qui démonte notre partition est
system("mountvol.exe h: /d")
, où system
en c est la fonction qui exécute une commande comme dans la console windows. - n’importe quel compilateur c fera l’affaire, il en existe même en ligne si on tape "online c compiler"
- dans regedit.exe,
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[nom du service]
, créer la valeur Description = le msg de description, permet d’avoir un nom explicite dans la liste des services du panneau de configuration.
Usage
FAQ
- que se passe-t-il si le volume est démonté pendant une écriture de fichier ?
- windows, c’est bien fait pour une fois... : le point de montage est supprimé immédiatement sans avertissement, mais l’écriture se poursuit jusqu’à sa fin sans perte.
Ressources diverses
Annexes : Commandes pour monter démonter des volumes truecrypt

- Pour faire des icônes sur le bureau...
Monter
-
"C:\Program Files\TrueCrypt\TrueCrypt.exe" /v \Device\Harddisk0\Partition3 /l H /q background
- affiche juste la boîte de mot de passe.
-
\Device\Harddisk0\Partition3
à remplacer par votre partition chiffrée / container
Tout démonter
-
"C:\Program Files\TrueCrypt\TrueCrypt.exe" /dismount /quit
code service.c
#include <windows.h> #include <stdio.h> #include <stdlib.h> #define SLEEP_TIME 5000 //#define LOGFILE "d:\\temp\\runassvc.txt" SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hStatus; void ServiceMain(int argc, char** argv); void ControlHandler(DWORD request); int InitService(); /* int WriteToLog(char* str) { FILE* log; log = fopen(LOGFILE, "a+"); if (log == NULL) return -1; fprintf(log, "%s\n", str); fclose(log); return 0; } */ void main() { SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = "MemoryStatus"; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; // Start the control dispatcher thread for our service StartServiceCtrlDispatcher(ServiceTable); } void ServiceMain(int argc, char** argv) { //int error; ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; hStatus = RegisterServiceCtrlHandler( "MemoryStatus", (LPHANDLER_FUNCTION)ControlHandler); if (hStatus == (SERVICE_STATUS_HANDLE)0) { // Registering Control Handler failed return; } // Initialize Service /* error = InitService(); if (error) { // Initialization failed ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = -1; SetServiceStatus(hStatus, &ServiceStatus); return; } */ // We report the running status to SCM. ServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus (hStatus, &ServiceStatus); /* int ecrire=1; int result=0; char pchar[10]; */ //MEMORYSTATUS memory; // The worker loop of a service while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { // if (ecrire) { //------------------------ c'est ici le code !! --------------------------------- /* result=*/system("mountvol.exe h: /d"); ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = 0; SetServiceStatus(hStatus, &ServiceStatus); return; //------------------------ /c'est ici le code !! -------------------------------- // sprintf(pchar,"%d",result); // WriteToLog(pchar); // ecrire=0; } /* char buffer[16]; GlobalMemoryStatus(&memory); sprintf(buffer, "%d", memory.dwAvailPhys); int result = WriteToLog(buffer); if (result) { ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = -1; SetServiceStatus(hStatus, &ServiceStatus); return; } Sleep(SLEEP_TIME); */ } return; } // Service initialization /* int InitService() { int result; result = WriteToLog("Monitoring started."); return(result); } */ // Control handler function void ControlHandler(DWORD request) { switch(request) { case SERVICE_CONTROL_STOP: // WriteToLog("Monitoring stopped."); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus (hStatus, &ServiceStatus); return; case SERVICE_CONTROL_SHUTDOWN: // WriteToLog("Monitoring stopped."); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus (hStatus, &ServiceStatus); return; default: break; } // Report current status SetServiceStatus (hStatus, &ServiceStatus); return; }
Notes : [1] mais dont l’expertise en cours ce jour orientera peut être plus sur une pression politique qu’un défaut du logiciel