Mi è stato chiesto di aggiornare alcune macro di Excel 2003, ma i progetti VBA sono protetti da password e sembra che manchi la documentazione ... nessuno conosce le password.
Esiste un modo per rimuovere o decifrare la password in un progetto VBA?
Mi è stato chiesto di aggiornare alcune macro di Excel 2003, ma i progetti VBA sono protetti da password e sembra che manchi la documentazione ... nessuno conosce le password.
Esiste un modo per rimuovere o decifrare la password in un progetto VBA?
Risposte:
Puoi provare questo VBA
approccio diretto che non richiede l'editing HEX. Funzionerà con qualsiasi file (* .xls, * .xlsm, * .xlam ...).
Testato e funziona su:
Excel 2007
Excel 2010
Excel 2013 - Versione a 32 bit
Excel 2016 - Versione a 32 bit
Cerchi una versione a 64 bit? Vedi questa risposta
Farò del mio meglio per spiegare come funziona - per favore, scusa il mio inglese.
Per favore, prima esegui il backup dei tuoi file!
Crea un nuovo file xlsm e archivia questo codice in 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
Incollare questo codice con il codice sopra in Module1 ed eseguirlo
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Torna ai tuoi progetti VBA e divertiti.
Sì, a condizione che tu stia utilizzando un .xls
foglio di calcolo formato (impostazione predefinita per Excel fino al 2003). Per Excel 2007 in poi, il valore predefinito è.xlsx
, che è un formato abbastanza sicuro, e questo metodo non funzionerà.
Come dice Treb, è un semplice confronto. Un metodo consiste nello scambiare semplicemente la voce della password nel file utilizzando un editor esadecimale (consultare Editor esadecimali per Windows ). Esempio passo passo:
Copia le righe che iniziano con i seguenti tasti:
CMG=....
DPB=...
GC=...
PRIMO BACKUP del file Excel per il quale non si conosce la password VBA, quindi aprirlo con l'editor esadecimale e incollare le righe sopra copiate dal file fittizio.
Se devi lavorare con Excel 2007 o 2010, ci sono alcune altre risposte che potrebbero esserti utili, in particolare queste: 1 , 2 , 3 .
MODIFICA Febbraio 2015: per un altro metodo che sembra molto promettente, guarda questa nuova risposta di Thanc Thanh Nguyễn.
CMG...
stringa è più lunga dell'originale.
Ho sviluppato la fantastica risposta di Thanc Thanh Nguyễn per consentire a questo metodo di funzionare con le versioni a 64 bit di Excel. Sto eseguendo Excel 2010 a 64 bit su Windows 7 a 64 bit.
Crea un nuovo file xlsm e archivia questo codice in 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
Incolla questo codice in Module2 ed eseguilo
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
DISCLAIMER Questo ha funzionato per me e l'ho documentato qui nella speranza che possa aiutare qualcuno. Non l'ho provato completamente . Assicurati di salvare tutti i file aperti prima di procedere con questa opzione.
Esiste un'altra soluzione (un po 'più semplice), senza problemi di dimensioni. Ho usato questo approccio oggi (su un file XLS del 2003, usando Excel 2007) e ho avuto successo.
DPB=...
parteDPB=...
stringa inDPx=...
* NOTA: assicurati di aver modificato la password con un nuovo valore, altrimenti la prossima volta che aprirai il foglio di calcolo Excel segnalerà errori (errore imprevisto), quindi quando accedi all'elenco dei moduli VBA ora vedrai i nomi dei moduli di origine ma ricevono un altro errore quando si tenta di aprire moduli / codice / ecc. Per ovviare a questo, tornare alle proprietà del progetto VBA e impostare la password su un nuovo valore. Salva e riapri il documento Excel e dovresti essere pronto!
Colin Pickard ha una risposta eccellente, ma c'è un 'attenzione' con questo. Ci sono casi (non ho ancora capito la causa) in cui la lunghezza totale della voce "CMG = ........ GC = ...." nel file è diversa da un file Excel al Il prossimo. In alcuni casi, questa voce sarà 137 byte e in altri sarà 143 byte. La lunghezza di 137 byte è quella dispari e se ciò accade quando si crea il file con la password '1234', basta creare un altro file e dovrebbe passare alla lunghezza di 143 byte.
Se si tenta di incollare il numero errato di byte nel file, si perderà il progetto VBA quando si tenta di aprire il file con Excel.
MODIFICARE
Questo non è valido per i file Excel 2007/2010. Il formato di file standard .xlsx è in realtà un file .zip contenente numerose sottocartelle con formattazione, layout, contenuto, ecc., Archiviate come dati XML. Per un file Excel 2007 non protetto, puoi semplicemente modificare l'estensione .xlsx in .zip, quindi aprire il file zip e esaminare tutti i dati XML. È molto semplice.
Tuttavia, quando si protegge con password un file Excel 2007, l'intero file .zip (.xlsx) viene effettivamente crittografato utilizzando la crittografia RSA. Non è più possibile modificare l'estensione in .zip e sfogliare il contenuto del file.
Per un tipo di file .xlsm
o .dotm
è necessario farlo in un modo leggermente diverso.
.xlsm
file in .zip
.vbaProject.bin
file e aprilo in un editor esadecimale (uso HxD , è completamente gratuito e leggero).DPB
e sostituisci con DPx
e salva il file.vbaProject.bin
file con questo nuovo nel file zippato..xlsm
..xlsm
file.Vale la pena sottolineare che se si dispone di un file Excel 2007 (xlsm), è possibile semplicemente salvarlo come file Excel 2003 (xls) e utilizzare i metodi descritti in altre risposte.
1.
converto .xlsm in .xls 2.
crack il codice di .xls 3.
converti .xlsm in .xlsx 4.
Metti il codice dai moduli in .xls in. xlsx e salvalo come .xlsm
Con il mio turno, questo è basato sull'eccellente risposta di Kaybee99 che si basa sulla fantastica risposta di Thanc Thanh Nguyễn per consentire a questo metodo di funzionare con entrambe le versioni x86 e amd64 di Office.
Una panoramica di ciò che è cambiato, evitiamo push / ret che è limitato a indirizzi a 32 bit e lo sostituiamo con mov / jmp reg.
Testato e funzionante
Word / Excel 2016 - Versione a 32 bit .
Word / Excel 2016 - Versione a 64 bit .
come funziona
Crea un nuovo file con lo stesso tipo di quello sopra e archivia questo codice in 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
Incolla questo codice in Module2 ed eseguilo
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Hai provato semplicemente aprendoli in OpenOffice.org?
Qualche tempo fa ho avuto un problema simile e ho scoperto che Excel e Calc non capivano la crittografia reciproca e quindi permettevo l'accesso diretto a tutto.
Questo era un po 'di tempo fa, quindi se non fosse stato solo un colpo di fortuna da parte mia, potrebbe anche essere stato corretto.
Nel caso in cui il blocco di
CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
nel file "password nota" sia più corto del blocco esistente nel file "password sconosciuta", riempire le stringhe esadecimali con zeri finali per raggiungere la lunghezza corretta.
per esempio
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
nel file di password sconosciuta, dovrebbe essere impostato su
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000"
per preservare la lunghezza del file.
Ho anche avuto questo lavoro con i file .XLA (formato 97/2003) in Office 2007.
Per Excel 2007 in poi è necessario modificare l'estensione del file in .zip Nell'archivio è presente una sottocartella xl, in cui troverai vbaProject.bin. Seguire il passaggio sopra con vbaProject.bin quindi salvarlo nuovamente nell'archivio. Modifica la tua estensione e voilà! (intendendo seguire i passaggi precedenti)
Le password del progetto VBA su documenti Access, Excel, Powerpoint o Word ( 2007, 2010, 2013 or 2016
versioni con estensioni .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM
) possono essere facilmente rimosse .
Si tratta semplicemente di modificare l'estensione del nome file .ZIP
, decomprimere il file e utilizzare qualsiasi editor esadecimale di base (come XVI32 ) per "rompere" la password esistente, il che "confonde" Office in modo da richiedere una nuova password la prossima volta che il file è ha aperto.
.ZIP
un'estensione.ZIP
e vai alXL
cartella.vbaProject.bin
e aprirlo con un editor esadecimaleDPB
a DPX
..bin
file nella zip, riportalo alla sua normale estensione e apri il file come al solito.VBA Project Properties
.Protection
scheda, imposta una nuova password.OK
, Chiudi il file, riaprirlo, ALT + F11.A questo punto puoi rimuovere completamente la password se lo desideri.
Istruzioni complete con un video dettagliato che ho fatto "molto tempo fa" quando sono su YouTube qui .
È un po 'scioccante che questa soluzione alternativa sia disponibile da anni e Microsoft non abbia risolto il problema.
La morale della storia?
Microsoft Office password progetto VBA sono di non essere invocata per la sicurezza di tutte le informazioni sensibili . Se la sicurezza è importante, utilizzare software di crittografia di terze parti.
Colin Pickard è per lo più corretto, ma non confondere la protezione "password per aprire" per l'intero file con la protezione password VBA, che è completamente diversa dalla prima ed è la stessa per Office 2003 e 2007 (per Office 2007, rinominare il file in .zip e cerca vbaProject.bin all'interno dello zip). E tecnicamente il modo corretto per modificare il file è utilizzare un visualizzatore di documenti composti OLE come CFX per aprire il flusso corretto. Naturalmente, se stai solo sostituendo i byte, il semplice vecchio editor binario potrebbe funzionare.
A proposito, se ti stai chiedendo il formato esatto di questi campi, ora lo hanno documentato:
http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
Se il file è un file zip valido (vengono 50 4B
utilizzati i primi byte - utilizzati in formati come .xlsm
), quindi decomprimere il file e cercare il file secondario xl/vbaProject.bin
. Questo è un file CFB proprio come i .xls
file. Seguire le istruzioni per il formato XLS (applicato al file secondario) e quindi comprimere il contenuto.
Per il formato XLS, puoi seguire alcuni degli altri metodi in questo post. Personalmente preferisco cercare il DPB=
blocco e sostituire il testo
CMG="..."
DPB="..."
GC="..."
con spazi vuoti. Ciò risolve i problemi relativi alle dimensioni del contenitore CFB.
Ho provato alcune delle soluzioni sopra e nessuna di esse funziona per me (file xlsm di Excel 2007). Poi ho trovato un'altra soluzione che ha persino recuperato la password, non solo per decifrarla.
Inserisci questo codice nel modulo, eseguilo e dagli un po 'di tempo. Recupererà la tua password con la forza bruta.
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 realizza prodotti Advanced Office Password Breaker e Advanced Office Password Recovery che possono applicarsi a questo caso, purché il documento sia stato creato in Office 2007 o precedente.
Tom - Inizialmente ho fatto un errore da scolaro perché non guardavo la dimensione dei byte e invece ho copiato e incollato dal "CMG" impostato alla voce successiva. Si trattava di due dimensioni di testo diverse tra i due file, e ho perso il progetto VBA proprio come Stewbob ha avvertito.
Usando HxD, c'è un contatore che traccia la quantità di file che stai selezionando. Copia a partire da CMG fino a quando il contatore non legge 8F (esadecimale per 143) e allo stesso modo quando si incolla nel file bloccato - Ho finito con il doppio del numero di "..." alla fine della pasta, che in qualche modo sembrava strano e sembrava quasi innaturale, ma ha funzionato.
Non so se sia cruciale, ma mi sono assicurato di chiudere sia l'editor esadecimale sia di eccellere prima di riaprire il file in Excel. Ho dovuto quindi scorrere i menu per aprire l'editor VB, accedere a Proprietà VBProject e inserire la "nuova" password per sbloccare il codice.
Spero che questo possa essere d'aiuto.
Il mio strumento, VbaDiff , legge VBA direttamente dal file, quindi puoi usarlo per recuperare il codice VBA protetto dalla maggior parte dei documenti di Office senza ricorrere a un editor esadecimale.
Per Excel 2016 a 64 bit su un computer Windows 10, ho usato un editor esadecimale per poter cambiare la password di un xla protetto (non l'ho testato per altre estensioni). Mancia: crea un backup prima di procedere.
I passi che ho preso:
Spero che questo abbia aiutato alcuni di voi!
l'estensione del file Excel cambia in xml. E aprilo nel blocco note. testo della password trova nel file xml.
vedi come sotto la linea;
Sheets("Sheet1").Unprotect Password:="blabla"
(scusa per il mio cattivo inglese)
Se lavori, Java
potresti provare VBAMacroExtractor
. Dopo aver estratto gli script VBA da .xlsm
ho trovato la password in testo normale.