On m'a demandé de mettre à jour des macros Excel 2003, mais les projets VBA sont protégés par un mot de passe et il semble qu'il y ait un manque de documentation ... personne ne connaît les mots de passe.
Existe-t-il un moyen de supprimer ou de déchiffrer le mot de passe d'un projet VBA?
Vous pouvez essayer cette approche directe VBA
qui ne nécessite pas d’édition HEX. Cela fonctionnera pour tous les fichiers (* .xls, * .xlsm, * .xlam ...).
Testé et fonctionne sur:
Excel 2007
Excel 2010
Excel 2013 - version 32 bits
Excel 2016 - version 32 bits
Vous recherchez une version 64 bits? Voir cette réponse
Je vais essayer de mon mieux pour expliquer comment cela fonctionne - veuillez excuser mon anglais.
S'il vous plaît sauvegarder vos fichiers d'abord!
Créez un nouveau fichier xlsm et stockez ce code dans Module1
code credited to Siwtom (nick name), a Vietnamese developer
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, _
ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As Long) As Long
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As Long
Dim OriginProtect As Long
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Collez ce code sous le code ci-dessus dans Module1 et exécutez-le.
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Revenez à vos projets VBA et profitez-en.
Oui, tant que vous utilisez une feuille de calcul au format .xls
(valeur par défaut pour Excel jusqu’en 2003). À partir de Excel 2007, la valeur par défaut est .xlsx
, qui est un format relativement sécurisé. Cette méthode ne fonctionnera pas.
Comme Treb dit, c'est une simple comparaison. Une méthode consiste simplement à permuter l'entrée du mot de passe dans le fichier en utilisant un éditeur hexadécimal (voir Hex editors for Windows ). Exemple pas à pas:
Copiez les lignes en commençant par les clés suivantes:
CMG=....
DPB=...
GC=...
FIRST BACKUP le fichier Excel pour lequel vous ne connaissez pas le mot de passe VBA, puis ouvrez-le à l'aide de votre éditeur hexadécimal et collez les lignes copiées ci-dessus du modèle factice. fichier.
Si vous devez travailler avec Excel 2007 ou 2010, voici quelques réponses qui pourraient vous aider, notamment: 1 , 2 , .
EDIT Février 2015: pour une autre méthode qui semble très prometteuse, regardez cette nouvelle réponse par Thanc Thanh Nguyễn.
Il existe une autre solution (un peu plus facile), sans les problèmes de taille. J'ai utilisé cette approche aujourd'hui (sur un fichier XLS 2003, avec Excel 2007) et j'ai réussi.
DPB=...
DPB=...
par DPx=...
* REMARQUE: assurez-vous que le mot de passe a été remplacé par une nouvelle valeur, sinon Excel signalera des erreurs lors de la prochaine ouverture de la feuille de calcul (erreur inattendue). Lorsque vous accéderez à la liste des modules VBA, les noms des modules source, mais recevez une autre erreur lors de la tentative d’ouverture de formulaires/code/etc. Pour remédier à cela, retournez dans les propriétés du projet VBA et définissez le mot de passe sur une nouvelle valeur. Enregistrez et rouvrez le document Excel et vous devriez être prêt à partir!
Je me suis inspiré de la réponse fantastique de Thanc Thanh Nguyễn pour permettre à cette méthode de fonctionner avec les versions 64 bits d'Excel. J'utilise Excel 2010 64 bits sous Windows 7 64 bits.
Créez un nouveau fichier xlsm et stockez ce code dans Module1
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As LongPtr
Dim OriginProtect As LongPtr
Hook = False
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = GetPtr(AddressOf MyDialogBoxParam)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Collez ce code dans Module2 et exécutez-le.
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
DISCLAIMER Cela a fonctionné pour moi et je l'ai documenté ici dans l'espoir que cela puisse aider quelqu'un. Je ne l'ai pas complètement testé . Assurez-vous de sauvegarder tous les fichiers ouverts avant de continuer avec cette option.
Colin Pickard a une excellente réponse, mais il y en a un à surveiller. Il existe des cas (je n'ai pas encore déterminé la cause) où la longueur totale de l'entrée "CMG = ........ GC = ...." dans le fichier est différente d'un fichier Excel au fichier. suivant. Dans certains cas, cette entrée sera de 137 octets et dans d'autres, de 143 octets. La longueur de 137 octets est celle qui est impaire. Si cela se produit lorsque vous créez votre fichier avec le mot de passe '1234', créez simplement un autre fichier. Il devrait passer à la longueur de 143 octets.
Si vous essayez de coller un nombre incorrect d'octets dans le fichier, vous perdrez votre projet VBA lorsque vous essayez d'ouvrir le fichier avec Excel.
EDIT
Ceci n'est pas valable pour les fichiers Excel 2007/2010. Le format de fichier standard .xlsx est en fait un fichier .Zip contenant de nombreux sous-dossiers avec le formatage, la mise en page, le contenu, etc. stockés sous forme de données xml. Pour un fichier Excel 2007 non protégé, vous pouvez simplement changer l'extension .xlsx en .Zip, puis ouvrir le fichier Zip et parcourir toutes les données xml. C'est très simple.
Toutefois, lorsque vous protégez un fichier Excel 2007 avec un mot de passe, l'intégralité du fichier .Zip (.xlsx) est réellement cryptée à l'aide du cryptage RSA. Il n'est plus possible de changer l'extension en .Zip et de parcourir le contenu du fichier.
Pour un type de fichier .xlsm
ou .dotm
, vous devez procéder de manière légèrement différente.
.xlsm
en .Zip
.vbaProject.bin
et ouvrez-le dans un éditeur hexadécimal (j'utilise HxD , il est totalement gratuit et léger.)DPB
et remplacez-le par DPx
, puis enregistrez le fichier.vbaProject.bin
par ce nouveau dans le fichier zippé..xlsm
..xlsm
.Il convient de noter que si vous avez un fichier Excel 2007 (xlsm), vous pouvez simplement l'enregistrer en tant que fichier Excel 2003 (xls) et utiliser les méthodes décrites dans d'autres réponses.
Avez-vous essayé simplement de les ouvrir dans OpenOffice.org?
J'ai eu un problème similaire il y a quelque temps et j'ai constaté qu'Excel et Calc ne comprenaient pas le cryptage l'un de l'autre et permettaient ainsi un accès direct à peu près à tout.
C’était il ya quelque temps, donc si ce n’était pas un simple coup d’œil de ma part, il aurait peut-être aussi été corrigé.
Pour Excel 2007, vous devez modifier votre extension de fichier en .Zip. Dans l'archive, il y a un sous-dossier xl. Vous y trouverez vbaProject.bin. Suivez l'étape ci-dessus avec vbaProject.bin, puis enregistrez-le dans l'archive. Modifiez votre extension et le tour est joué! (ce qui signifie suivre les étapes ci-dessus)
À mon tour, ceci est construit sur l'excellente réponse de kaybee99 qui est construite sur la fantastique réponse de Thanc Thanh Nguyễn pour permettre à cette méthode de fonctionner avec les versions x86 et AMD64 d'Office.
Un aperçu de ce qui est changé, nous évitons Push/ret qui est limité aux adresses 32 bits et le remplaçons par mov/jmp reg.
Testé et fonctionne sur
Word/Excel 2016 - version 32 bits.
Word/Excel 2016 - version 64 bits.
comment ça marche
Créez un nouveau fichier avec le même type que ci-dessus et stockez ce code dans Module1
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare PtrSafe Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As LongPtr, Source As LongPtr, ByVal Length As LongPtr)
Private Declare PtrSafe Function VirtualProtect Lib "kernel32" (lpAddress As LongPtr, _
ByVal dwSize As LongPtr, ByVal flNewProtect As LongPtr, lpflOldProtect As LongPtr) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" (ByVal hModule As LongPtr, _
ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
Dim HookBytes(0 To 11) As Byte
Dim OriginBytes(0 To 11) As Byte
Dim pFunc As LongPtr
Dim Flag As Boolean
Private Function GetPtr(ByVal Value As LongPtr) As LongPtr
GetPtr = Value
End Function
Public Sub RecoverBytes()
If Flag Then MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 12
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 11) As Byte
Dim p As LongPtr, osi As Byte
Dim OriginProtect As LongPtr
Hook = False
#If Win64 Then
osi = 1
#Else
osi = 0
#End If
pFunc = GetProcAddress(GetModuleHandleA("user32.dll"), "DialogBoxParamA")
If VirtualProtect(ByVal pFunc, 12, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, osi+1
If TmpBytes(osi) <> &HB8 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 12
p = GetPtr(AddressOf MyDialogBoxParam)
If osi Then HookBytes(0) = &H48
HookBytes(osi) = &HB8
osi = osi + 1
MoveMemory ByVal VarPtr(HookBytes(osi)), ByVal VarPtr(p), 4 * osi
HookBytes(osi + 4 * osi) = &HFF
HookBytes(osi + 4 * osi + 1) = &HE0
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 12
Flag = True
Hook = True
End If
End If
End Function
Private Function MyDialogBoxParam(ByVal hInstance As LongPtr, _
ByVal pTemplateName As LongPtr, ByVal hWndParent As LongPtr, _
ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer
If pTemplateName = 4070 Then
MyDialogBoxParam = 1
Else
RecoverBytes
MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
hWndParent, lpDialogFunc, dwInitParam)
Hook
End If
End Function
Collez ce code dans Module2 et exécutez-le.
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Au cas où votre bloc de CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
dans votre fichier 'mot de passe connu' est plus court que le bloc existant dans le fichier 'mot de passe inconnu', ajoutez des zéros à la fin de votre chaîne hexagonale pour atteindre la longueur correcte.
par exemple.
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
dans le fichier de mot de passe inconnu, doit être réglé sur
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000"
pour préserver la longueur du fichier.
J'ai également eu ce travail avec les fichiers .XLA (format 97/2003) dans Office 2007.
Les mots de passe de projet VBA sur les documents Access, Excel, PowerPoint ou Word (2007, 2010, 2013 or 2016
versions avec extensions .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM
) peuvent être facilement enlevé =.
Il suffit simplement de changer l'extension du nom de fichier en .Zip
, de décompresser le fichier et d'utiliser n'importe quel éditeur Hex de base (comme XVI32 ) pour "rompre" le mot de passe existant, ce qui "confond" Office il demande donc un nouveau mot de passe à la prochaine ouverture du fichier.
.Zip
.Zip
et allez dans le dossier XL
.vbaProject.bin
et l'ouvrir avec un éditeur hexadécimalDPB
en DPX
..bin
dans le zip, remettez-le dans son extension normale et ouvrez le fichier normalement.VBA Project Properties
.Protection
, définissez un nouveau mot de passe.OK
, fermez le fichier, rouvrez-le, appuyez sur ALT + F11.À ce stade, vous pouvez supprimer complètement le mot de passe si vous le souhaitez.
Instructions complètes avec une vidéo étape par étape que j'ai réalisée "retourne quand" sont sur YouTube ici = .
Il est assez choquant que cette solution de contournement existe depuis des années et Microsoft n'a pas résolu le problème.
La morale de l'histoire?
Microsoft Office Les mots de passe du projet VBA sont ne doit pas être invoqué == pour la sécurité de any informations sensibles. Si la sécurité est importante, utilisez un logiciel de cryptage tiers.
Colin Pickard est la plupart du temps correct, mais ne confondez pas la protection du "mot de passe à ouvrir" pour l'ensemble du fichier avec la protection par mot de passe VBA, qui est complètement différente de la précédente et identique pour Office 2003 et 2007 (pour Office 2007, renommer le fichier à .Zip et recherchez le vbaProject.bin dans le fichier Zip). Et techniquement, la bonne façon d’éditer le fichier est d’utiliser un visualiseur de documents composés OLE comme CFX pour ouvrir le flux correct. Bien sûr, si vous remplacez simplement des octets, le vieil éditeur binaire peut fonctionner.
En passant, si vous vous interrogez sur le format exact de ces champs, ils l'ont maintenant documenté:
http://msdn.Microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
Si le fichier est un fichier Zip valide (les premiers octets sont 50 4B
- utilisé dans des formats tels que .xlsm
), décompressez le fichier et recherchez le sous-fichier xl/vbaProject.bin
. Il s’agit d’un fichier CFB exactement comme les fichiers .xls
. Suivez les instructions pour le format XLS (appliqué au sous-fichier), puis décompressez simplement le contenu.
Pour le format XLS, vous pouvez suivre certaines des méthodes décrites dans cet article. Personnellement, je préfère chercher le bloc DPB=
et remplacer le texte
CMG="..."
DPB="..."
GC="..."
avec des espaces vides. Cela évite les problèmes de taille des conteneurs de la BFC.
J'ai essayé certaines des solutions ci-dessus et aucune d'entre elles ne fonctionne pour moi (fichier Excel 2007 xlsm). Ensuite, j'ai trouvé une autre solution qui récupère même le mot de passe, pas seulement le casser.
Insérez ce code dans le module, lancez-le et donnez-lui un peu de temps. Il va récupérer votre mot de passe par force brute.
Sub PasswordBreaker()
'Breaks worksheet password protection.
Dim i As Integer, j As Integer, k As Integer
Dim l As Integer, m As Integer, n As Integer
Dim i1 As Integer, i2 As Integer, i3 As Integer
Dim i4 As Integer, i5 As Integer, i6 As Integer
On Error Resume Next
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If ActiveSheet.ProtectContents = False Then
MsgBox "One usable password is " & Chr(i) & Chr(j) & _
Chr(k) & Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
Exit Sub
End If
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
End Sub
ElcomSoft fait Advanced Office Password Breaker et Récupération avancée du mot de passe Office produits pouvant s'appliquer à ce cas, à condition que le document ait été créé dans Office 2007 ou une version antérieure.
Tom - J'ai commis une erreur d'écolier au début, car je n'ai pas regardé la taille en octets. J'ai plutôt copié et collé à partir de la "GMA" configurée pour l'entrée suivante. Cependant, il s’agissait de deux tailles de texte différentes entre les deux fichiers et j’ai perdu le projet VBA, comme l’avait prévenu Stewbob.
En utilisant HxD, il existe un compteur qui indique combien de fichiers vous sélectionnez. Copier à partir de CMG jusqu'à ce que le compteur indique 8F (hex pour 143) et de même lors du collage dans le fichier verrouillé - je me suis retrouvé avec deux fois le nombre de "..." à la fin de la pâte, ce qui semblait étrange et semblait presque contre nature, mais cela a fonctionné.
Je ne sais pas si c'est crucial, mais je me suis assuré de fermer l'éditeur hexadécimal et Excel avant de rouvrir le fichier dans Excel. J'ai ensuite dû passer par les menus pour ouvrir l'éditeur VB, dans VBProject Properties et entrer le nouveau mot de passe pour déverrouiller le code.
J'espère que ça aide.
Mon outil, VbaDiff , lit VBA directement à partir du fichier. Vous pouvez donc l'utiliser pour récupérer le code VBA protégé de la plupart des documents bureautiques sans recourir à un éditeur hexadécimal.
La protection est une simple comparaison de texte dans Excel. Chargez Excel dans votre débogueur préféré ( Ollydbg étant mon outil de choix), trouvez le code qui effectue la comparaison et corrigez-le pour qu'il renvoie toujours la valeur true. Cela devrait vous permettre d'accéder aux macros.
Pour Excel 2016 64 bits sur une machine Windows 10, j'ai utilisé un éditeur hexadécimal pour pouvoir changer le mot de passe d'un xla protégé (je ne l'ai pas testé pour d'autres extensions). Astuce: créez une sauvegarde avant de le faire.
Les pas que j'ai faits:
J'espère que cela a aidé certains d'entre vous!
l’extension de votre fichier Excel devient XML. Et ouvrez-le dans le bloc-notes. mot de passe trouver dans le fichier xml.
vous voyez comme en dessous de la ligne;
Sheets("Sheet1").Unprotect Password:="blabla"
(Désolé pour mon mauvais anglais)
Si vous travaillez dans Java
, vous pouvez essayer VBAMacroExtractor
. Après avoir extrait les scripts VBA de .xlsm
, j'ai trouvé le mot de passe en clair.