Existe-t-il un moyen de casser le mot de passe sur un projet Excel VBA?


486

On m'a demandé de mettre à jour certaines macros Excel 2003, mais les projets VBA sont protégés par 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 casser le mot de passe sur un projet VBA?


Pouvez-vous enregistrer en tant que .xls au lieu d'un .xla comme le suggèrent les exemples de votre lien? Je ne sais pas si cela ferait une différence.
B Hart

4
bon à connu: xlsb est robuste contre les astuces de craquage de mot de passe
Qbik

20
@ Fandango68 Cette question a été discutée il y a des années sur meta . TLDR: Beaucoup (la plupart?) Des questions sur les SO pourraient être utilisées abusivement par de mauvais acteurs, mais à moins qu'il y ait des preuves claires d'actes répréhensibles, nous supposons la bonne foi. Il existe de nombreuses raisons légalement légales et éthiques pour casser un mot de passe VBA. De plus, discuter des faiblesses des systèmes actuels contribue en fin de compte à une meilleure sécurité à l'avenir et décourage les gens de s'appuyer aveuglément sur des systèmes non sécurisés maintenant.
jmbpiano

Réponses:


701

Vous pouvez essayer cette VBAapproche directe 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

Comment ça fonctionne

Je ferai de mon mieux pour expliquer comment cela fonctionne - veuillez excuser mon anglais.

  1. Le VBE appellera une fonction système pour créer la boîte de dialogue de mot de passe.
  2. Si l'utilisateur entre le bon mot de passe et cliquez sur OK, cette fonction renvoie 1. Si l'utilisateur entre le mauvais mot de passe ou cliquez sur Annuler, cette fonction renvoie 0.
  3. Une fois la boîte de dialogue fermée, le VBE vérifie la valeur renvoyée de la fonction système
  4. si cette valeur est 1, le VBE "pense" que le mot de passe est correct, donc le projet VBA verrouillé sera ouvert.
  5. Le code ci-dessous échange la mémoire de la fonction d'origine utilisée pour afficher la boîte de dialogue de mot de passe avec une fonction définie par l'utilisateur qui retournera toujours 1 lors de l'appel.

Utiliser le code

Veuillez d'abord sauvegarder vos fichiers!

  1. Ouvrez le (s) fichier (s) contenant vos projets VBA verrouillés
  2. 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
    
  3. 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
    
  4. Revenez à vos projets VBA et profitez-en.


4
@Chris, vous avez absolument raison. Parce que les fonctions de l'API Windows sont définies pour win 32 dans ce code.
Đức Thanh Nguyễn

8
Une explication serait bien de la façon dont cela fonctionne.
Dennis G

20
Maintenant, la seule question qui reste (après avoir vu cette méthode impressionnante fonctionne parfaitement), est de savoir comment diable puis-je renforcer mon projet VBA protégé pour empêcher les autres d'utiliser ce hack :) :)
EranG

6
Ce code fonctionne parfaitement pour déverrouiller le code VBA bien que chaque fois que je l'utilise, il m'empêche de re-protéger le projet avec un mot de passe différent, quelqu'un d'autre a-t-il eu ce problème?
Matthew Bond

2
J'ai trouvé que cela corrompt le projet VBA dans le fichier Excel, j'ai donc dû exporter tous les modules / classes, puis enregistrer le fichier sous xlsx (non-macro), puis FERMER le fichier (stupide Excel), puis rouvrir, puis importer des modules et copier du code à partir de fichiers de classe. À ce stade, j'ai pu enregistrer le fichier au format xlsm avec mon propre mot de passe sur le projet VBA.
BH

217

Oui, tant que vous utilisez une .xlsfeuille de calcul au format (par défaut pour Excel jusqu'à 2003). Pour Excel 2007 et versions ultérieures, la valeur par défaut est .xlsx, qui est un format assez sécurisé, et cette méthode ne fonctionnera pas.

Comme le dit Treb, c'est une comparaison simple. Une méthode consiste simplement à échanger l'entrée de mot de passe dans le fichier à l'aide d'un éditeur hexadécimal (voir Éditeurs hexadécimaux pour Windows ). Exemple étape par étape:

  1. Créez un nouveau fichier Excel simple.
  2. Dans la partie VBA, définissez un mot de passe simple (disons - 1234).
  3. Enregistrez le fichier et quittez. Vérifiez ensuite la taille du fichier - voir le gotcha de Stewbob
  4. Ouvrez le fichier que vous venez de créer avec un éditeur hexadécimal.
  5. Copiez les lignes commençant par les touches suivantes:

    CMG=....
    DPB=...
    GC=...
    
  6. PREMIÈRE SAUVEGARDE du fichier Excel dont vous ne connaissez pas le mot de passe VBA, puis ouvrez-le avec votre éditeur hexadécimal et collez les lignes copiées ci-dessus à partir du fichier factice.

  7. Enregistrez le fichier Excel et quittez.
  8. Maintenant, ouvrez le fichier Excel dont vous avez besoin pour voir le code VBA. Le mot de passe pour le code VBA sera simplement 1234 (comme dans l'exemple que je montre ici).

Si vous devez travailler avec Excel 2007 ou 2010, il existe d'autres réponses ci-dessous qui pourraient vous aider, en particulier celles-ci: 1 , 2 , 3 .

EDIT février 2015: pour une autre méthode qui semble très prometteuse, regardez cette nouvelle réponse de Đức Thanh Nguyễn.


Et s'il n'y a pas de lignes commençant par CMG = ...?
systemovich

1
Dans le fichier Excel vierge ou verrouillé? Vérifiez la taille du fichier vierge. Si c'est le fichier verrouillé, assurez-vous que votre sauvegarde est sûre, puis essayez de modifier uniquement les deux autres lignes. Vous êtes sûr que c'est un fichier crypté?
Colin Pickard, le

6
La protection par mot de passe (et le format de fichier) d'Excel 2007 est radicalement différente de celle d'Excel 2003. J'ai inclus quelques détails à ce sujet dans ma réponse ci-dessous. À mon avis, l'option protégée par mot de passe sur un fichier Excel 2007 est la première fois dans l'histoire de Microsoft Office qu'ils produisent un fichier raisonnablement sécurisé.
Stewbob

1
Je n'ai pas pu définir le mot de passe vba sur un nouveau fichier Excel 2016. Quelqu'un pourrait-il simplement partager le HEX pour le remplacer par le 1234? Ou peut-il changer d'une machine à l'autre?
Mescalito

1
Cette approche a fonctionné pour moi sur un fichier .xlsm. Je l'ai enregistré en tant que .xls, j'ai fait cela, puis l'ai reconverti en .xlsm. Il convient de noter que vous pouvez augmenter la longueur du fichier en toute sécurité si la nouvelle CMG...chaîne est plus longue que l'original.
Drew Chapin

173

J'ai construit sur la fantastique réponse de Đức Thanh Nguyễn pour permettre à cette méthode de fonctionner avec les versions 64 bits d'Excel. J'exécute Excel 2010 64 bits sur Windows 7 64 bits.

  1. Ouvrez le ou les fichiers contenant vos projets VBA verrouillés.
  2. 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
  3. Collez ce code dans Module2 et exécutez-le

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub

AVERTISSEMENT Cela a fonctionné pour moi et je l'ai documenté ici dans l'espoir que cela aidera quelqu'un. Je ne l'ai pas entièrement testé . Veillez à enregistrer tous les fichiers ouverts avant de continuer avec cette option.


1
Je ne sais pas pourquoi, mais lorsque j'exécute cela sur Excel pour 365, MSP 64 bits excelle, il ferme les fichiers et lorsque je le redémarre, le mot de passe est toujours là.
eborbath

Cela ne peut plus être fait dans Excel car les options du menu contextuel sont grisées, vous ne pouvez donc pas créer le module.
thanos.a

170

Il existe une autre solution (un peu plus simple), sans les problèmes de taille. J'ai utilisé cette approche aujourd'hui (sur un fichier XLS 2003, en utilisant Excel 2007) et j'ai réussi.

  1. Sauvegardez le fichier xls
  2. Ouvrez le fichier dans un éditeur HEX et localisez la DPB=...pièce
  3. Remplacez la DPB=...chaîne parDPx=...
  4. Ouvrez le fichier xls dans Excel
  5. Ouvrez l'éditeur VBA ( ALT+ F11)
  6. la magie: Excel découvre une clé invalide (DPx) et vous demande si vous souhaitez continuer à charger le projet (en ignorant fondamentalement la protection)
  7. Vous pourrez remplacer le mot de passe, alors changez-le en quelque chose dont vous vous souviendrez
  8. Enregistrez le fichier xls *
  9. Fermez et rouvrez le document et travaillez votre magie VBA!

* REMARQUE: assurez-vous que vous avez changé le mot de passe pour une nouvelle valeur, sinon la prochaine fois que vous ouvrirez la feuille de calcul, Excel signalera des erreurs (erreur inattendue), puis lorsque vous accéderez à la liste des modules VBA, vous verrez maintenant les noms des modules source mais reçoivent une autre erreur lors de la tentative d'ouverture de formulaires / code / etc. Pour y remédier, revenez aux 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!


3
Malheureusement, cela n'a pas fonctionné pour moi avec Excel pour Mac 2011 v14.2.5. J'ai eu la possibilité de réparer le fichier, pas de réinitialiser le mot de passe, et l'effet a été de perdre tous les scripts VBA.
Joe Carroll du

Solution parfaite - je l'ai fait avec un fichier 2003 en utilisant HxD Hex Editor
Chris W

4
Je viens de l'essayer (.xls, Excel 2007) et cela n'a pas fonctionné. Résultat: les modules sont visibles, le code semble bien fonctionner, mais lors de l'ouverture d'un module, il indique une erreur inattendue (40230) .
KekuSemau

2
Même erreur ici (Excel 2010) - mais j'ai réalisé que j'avais sauté le 'définir un nouveau mot de passe et enregistrer / rouvrir' (étapes 7-9) de Pieter.
Owen B

+1 Cette méthode a également fonctionné sur notre fichier d'accès (.mdb) mal développé! Maintenant, nous pouvons améliorer cette chose, merci pour cela!
Er Gabriel Doronila

65

Colin Pickard a une excellente réponse, mais il faut faire attention à cela. Il y a des cas (je n'ai pas encore trouvé la cause) où la longueur totale de l'entrée "CMG = ........ GC = ...." dans le fichier est différente d'un fichier Excel au suivant. Dans certains cas, cette entrée sera de 137 octets, et dans d'autres, elle sera de 143 octets. La longueur de 137 octets est étrange, et si cela se produit lorsque vous créez votre fichier avec le mot de passe '1234', créez simplement un autre fichier, et il devrait passer à la longueur de 143 octets.

Si vous essayez de coller le mauvais nombre d'octets dans le fichier, vous perdrez votre projet VBA lorsque vous essayez d'ouvrir le fichier avec Excel.

ÉDITER

Ce n'est pas valable pour les fichiers Excel 2007/2010. Le format de fichier .xlsx standard 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 par mot de passe un fichier Excel 2007, l'intégralité du fichier .zip (.xlsx) est réellement chiffrée à l'aide du chiffrement RSA. Il n'est plus possible de changer l'extension en .zip et de parcourir le contenu du fichier.


Ensuite, vous devez utiliser des outils de piratage zip standard. Ce n'est plus un problème "comment sauvegarder un fichier Excel".
Type anonyme

3
@Anonymous Type: Je pense qu'un outil de crackage n'aidera pas. Si je comprends bien Stewbob, ce ne sont pas les entrées de fichier dans le fichier zip qui sont cryptées, mais le fichier zip entier lui-même, qui devrait inclure l'en-tête et le répertoire central.
Treb

2
Juste curieux: comment pourrait-il être RSA quand je viens de saisir un mot de passe (symétrique)?
kizzx2

Qu'en est-il lorsque le fichier dans lequel vous souhaitez accéder a les clés les plus courtes? Continuez simplement à créer des documents vba jusqu'à ce que vous en obteniez un contenant 137?
seulement

1
Êtes-vous sûr que l'intégralité du fichier zip est chiffrée lorsque vous verrouillez le projet VBA? Je peux toujours ouvrir le fichier zip et voir la structure du fichier .... Et le sous-dossier xl \ contient le fichier vbaProject.bin qui a le bloc de hachage familier "CMG = ... GC =".
Nigel Heffernan

63

Pour un type de fichier .xlsmou .dotm, vous devez le faire d'une manière légèrement différente.

  1. Modifiez l'extension du .xlsmfichier en .zip.
  2. Ouvrez le fichier .zip (avec WinZip ou WinRar, etc.) et accédez au dossier xl.
  3. Extraire le vbaProject.binfichier et l'ouvrir dans un éditeur hexadécimal (j'utilise HxD , son entièrement gratuit et léger.)
  4. Recherchez DPB, remplacez DPxet enregistrez le fichier.
  5. Remplacez l'ancien vbaProject.binfichier par ce nouveau dans le fichier compressé.
  6. Remplacez l'extension de fichier par .xlsm.
  7. Ouvrir le classeur ignorer les messages d'avertissement.
  8. Ouvrez Visual Basic dans Excel.
  9. Accédez à Outils> Propriétés du projet VBAP> Onglet Protection.
  10. Saisissez un nouveau mot de passe et enregistrez le .xlsmfichier.
  11. Fermez et rouvrez et votre nouveau mot de passe fonctionnera.

8
Fonctionné dans Excel 2016, Windows 10 64 bits. (fichiers xlsm)
LimaNightHawk

3
Fonctionné dans Word 2016, Windows 10 64 bits (fichiers dotm)
NBajanca

7
Excellente solution, a fonctionné pour moi dans Excel 2013 64 bits. Vous pouvez ignorer la modification des extensions de fichier .zipsi vous avez installé 7-Zip . Dans ce cas, vous pouvez simplement cliquer avec le bouton droit sur le .xlsmfichier et choisir "7-Zip -> Open Archive"
nkatsar

fonctionne avec Word 2013, win7x64. (C'est très triste, étant si facilement trompé pour croire que le code est quelque peu sécurisé).
Berry Tsakala

1
@ThierryMichel Combinaison de solutions précédentes et essais et erreurs!
Matt

35

Il convient de souligner que si vous disposez d'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.


4
ce n'est pas vrai, j'ai travaillé avec des fichiers pour lesquels la conversion en xls / xla à partir de xlsm était impossible, Excel 2007 et 2010 se sont plantés à chaque fois, j'ai essayé plusieurs instances, à partir d'un message d'erreur - Kod wyjątku: c0000005 Przesunięcie wyjątku: 005d211d
Qbik

4
Oui, vous pouvez le faire. Je l'ai fait plusieurs fois. S'il y a quelque chose sur les feuilles qui est nécessaire et ce qui n'est pas transféré à l'ancienne version, je le fais: 1.convertir .xlsm en .xls 2.casser le code de .xls 3.convertir .xlsm en .xlsx 4.Mettre le code des modules en .xls vers. xlsx et enregistrez-le au format .xlsm
ZygD

Cela fonctionne après la conversion de xlsm en xls comme dans la réponse.
Purus

32

À mon tour, cela s'appuie sur l'excellente réponse de kaybee99 qui s'appuie sur la fantastique réponse de Đức Thanh Nguyễn pour permettre à cette méthode de fonctionner avec les versions x86 et amd64 d'Office.

Un aperçu de ce qui a 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 fonctionne

  1. Ouvrez le ou les fichiers contenant vos projets VBA verrouillés.
  2. 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
  3. Collez ce code dans Module2 et exécutez-le

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub

3
Parfait! Travailler avec Windows Server 2016, Excel 2016 32 bits
Zin Min

Cela a fonctionné sur un fichier .xlsm sur Excel Office 365. Merci!
Ryan James

Fonctionne toujours en 2019, les versions les plus récentes d'Office 365 64bits, les gars géniaux!
XavierAM

Merci pour le code mis à jour, je faisais face à des plantages exécutant la version précédente (64 bits), mais tout va bien avec votre version
emjaySX

Génial ...
Fonctionne

17

Avez-vous essayé de simplement 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 se comprenaient pas mutuellement, et permettaient donc un accès direct à à peu près tout.

C'était il y a un certain temps, donc si ce n'était pas seulement un coup de chance de ma part, cela pourrait aussi avoir été corrigé.


15

Dans le cas où votre bloc 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", remplissez vos chaînes hexadécimales avec des zéros de fin 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 défini sur

CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" pour conserver la longueur du fichier.

J'ai également eu ce travail avec des fichiers .XLA (format 97/2003) dans Office 2007.


1
Cela fonctionne, mais comme je l'ai récemment découvert (commenté ci-dessus), vous pouvez également simplement ajouter des caractères nuls après la citation finale dans le bloc GC = "..." jusqu'à ce que vous atteigniez la même longueur.
tobriand

13

Pour Excel 2007, vous devez changer votre extension de fichier en .zip Dans l'archive, il y a un sous-dossier xl, où vous trouverez vbaProject.bin. Suivez l'étape ci-dessus avec vbaProject.bin, puis enregistrez-le dans l'archive. Modifiez votre extension et voilà! (ce qui signifie suivre les étapes ci-dessus)


1
Je peux également confirmer que cela fonctionne pour les fichiers .xlam avec Excel 2010. +1!
Gimelist

12

Les mots de passe du projet VBA sur les documents Access, Excel, Powerpoint ou Word ( 2007, 2010, 2013 or 2016versions avec extensions .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM) peuvent être facilement supprimés .

Il s'agit simplement de changer l'extension du nom de fichier en .ZIP, de décompresser le fichier et d'utiliser n'importe quel éditeur hexadécimal de base (comme XVI32 ) pour "casser" le mot de passe existant, ce qui "confond" Office pour qu'il demande un nouveau mot de passe la prochaine fois que le fichier est ouvert.

Un résumé des étapes:

  • renommer le fichier pour qu'il ait une .ZIPextension.
  • ouvrez le ZIPet accédez au XLdossier.
  • extraire vbaProject.binet ouvrir avec un éditeur hexadécimal
  • « Rechercher et remplacer » à « remplacer tous » changer DPBà DPX.
  • Enregistrez les modifications, replacez le .binfichier dans le zip, retournez-le à son extension normale et ouvrez le fichier comme d'habitude.
  • ALT + F11 pour entrer dans l'éditeur VB et faites un clic droit dans l'Explorateur de projets pour choisir VBA Project Properties.
  • Dans l' Protectiononglet, définissez un nouveau mot de passe.
  • Cliquez sur OK, fermez le fichier, rouvrez-le, appuyez sur ALT + F11.
  • Saisissez le nouveau mot de passe que vous avez défini.

À ce stade, vous pouvez supprimer complètement le mot de passe si vous le souhaitez.

Des instructions complètes avec une vidéo étape par étape que j'ai faite "en arrière 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 des mots de passe projet VBA sont à ne pas compter sur la sécurité de toute information sensible . Si la sécurité est importante, utilisez un logiciel de cryptage tiers.


9

Colin Pickard est généralement correct, mais ne confondez pas la protection «mot de passe pour ouvrir» pour l'ensemble du fichier avec la protection par mot de passe VBA, qui est complètement différente de la première et identique pour Office 2003 et 2007 (pour Office 2007, renommez le fichier .zip et recherchez le vbaProject.bin à l'intérieur du zip). Et que techniquement la bonne façon d'éditer le fichier est d'utiliser une visionneuse de document composée OLE comme CFX pour ouvrir le flux correct. Bien sûr, si vous remplacez simplement des octets, l'ancien éditeur binaire simple peut fonctionner.

BTW, si vous vous interrogez sur le format exact de ces champs, ils l'ont documenté maintenant:

http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx


2
Le lien suivant donne des détails sur les fichiers au format XSLM. gbanik.blogspot.co.uk/2010/08/… La solution est la même que celle décrite par Yuhong Bao ci-dessus, mais rend la lecture intéressante et comprend des captures d'écran.
JohnLBevan

7

Si le fichier est un fichier zip valide (les premiers octets sont 50 4B- utilisés dans des formats comme .xlsm), décompressez le fichier et recherchez le sous-fichier xl/vbaProject.bin. Il s'agit d'un fichier CFB tout comme les .xlsfichiers. Suivez les instructions pour le format XLS (appliqué au sous-fichier), puis zippez simplement le contenu.

Pour le format XLS, vous pouvez suivre certaines des autres méthodes de cet article. Personnellement, je préfère rechercher le DPB=bloc et remplacer le texte

CMG="..."
DPB="..."
GC="..."

avec des espaces vides. Cela évite les problèmes de taille de conteneur CFB.


7

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 permet même de récupérer le mot de passe, pas seulement de le casser.

Insérez ce code dans le module, exécutez-le et donnez-lui du temps. Il récupérera 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

1
Agréable! Je pense que vous avez obtenu un downvote parce que votre solution déverrouille la feuille de calcul plutôt que le module VBA. Néanmoins, je l'ai trouvé utile - alors merci!
PBD10017

1
J'ai celui-ci dans mon cahier personnel. Les auteurs ont cité Bob McCormick comme auteur original modifié par la suite par Norman Harker et JE McGimpsey 2002.
Charles Byrne

5

ElcomSoft fabrique des produits Advanced Office Password Breaker et Advanced Office Password Recovery qui peuvent s'appliquer à ce cas, tant que le document a été créé dans Office 2007 ou antérieur.


4

Tom - J'ai fait une erreur d'écolier au départ car je n'ai pas regardé la taille des octets et à la place j'ai copié et collé de la configuration "CMG" à 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, tout comme l'avertissait Stewbob.

En utilisant HxD, il y a un compteur qui suit la quantité de fichier que vous sélectionnez. Copie à 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 en quelque sorte 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 d'exceller avant de rouvrir le fichier dans Excel. J'ai ensuite dû parcourir les menus pour ouvrir l'éditeur VB, dans les propriétés VBProject et saisir le «nouveau» mot de passe pour déverrouiller le code.

J'espère que ça aide.


4

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 de bureau sans avoir recours à un éditeur hexadécimal.


J'ai testé cet outil et fonctionne très bien mais la version gratuite récupère les 53 premières lignes. Pour récupérer mon fichier, j'ai dû suivre les instructions d'Andy pour déverrouiller le mot de passe. Puis j'ai ouvert mon xlsm avec VbaDiff dans les deux volets puis j'ai cliqué sur la feuille avec mon code. Je l'ai eu avec du copier-coller et l'ai mis dans mon fichier Excel récupéré mais vba-vide.
thanos.a

2

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 fait la comparaison et corrigez-le pour qu'il retourne toujours vrai, cela devrait vous permettre d'accéder aux macros.


1

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 n'ai testé cela pour aucune autre extension). Pointe: créez une sauvegarde avant de procéder.

Les étapes que j'ai prises:

  1. Ouvrez le vba dans l'éditeur hexadécimal (par exemple XVI)
  2. Recherche sur ce DPB
  3. Changez DPB en autre chose, comme DPX
  4. Sauvegarde le!
  5. Rouvrez le .xla, un message d'erreur apparaîtra, continuez simplement.
  6. Vous pouvez maintenant changer le mot de passe du .xla en ouvrant les propriétés et allez dans l'onglet mot de passe.

J'espère que cela a aidé certains d'entre vous!


J'ai réussi à ouvrir un ancien .xls en utilisant cela sur Windows 10 dans la dernière version d'Excel 365, alors que la réponse du haut ne fonctionne malheureusement plus. J'ai téléchargé HxD et changé la dernière lettre comme recommandé, et j'ai ignoré les erreurs. Tout va bien maintenant, merci!
Starnes Student

0

le changement d'extension de votre fichier Excel en xml. Et ouvrez-le dans le bloc-notes. mot de passe trouver dans le fichier xml.

vous voyez comme ci-dessous la ligne;

Sheets("Sheet1").Unprotect Password:="blabla"

(Désolé pour mon mauvais anglais)


Pouvez-vous expliquer en quoi votre réponse est meilleure que les très bonnes réponses déjà fournies?
Noel Widmer

ma solution n'a pas de code. donc solution très compacte autre que.
Developer33

1
Cette solution que vous avez fournie ne fonctionne pas en 2019.
Daniel L. VanDenBosch

Cela ne fonctionne pas non plus pour moi dans le bureau 365
thanos.a

0

Si vous travaillez, Javavous pouvez essayer VBAMacroExtractor. Après avoir extrait les scripts VBA, .xlsmj'ai trouvé le mot de passe en texte clair.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.