¿Hay alguna manera de descifrar la contraseña en un proyecto Excel VBA?

486

Me han pedido que actualice algunas macros de Excel 2003, pero los proyectos de VBA están protegidos con contraseña, y parece que falta documentación ... nadie sabe las contraseñas.

¿Hay alguna forma de eliminar o descifrar la contraseña en un proyecto de VBA?

Jonathan Sayce
fuente
¿Puede guardar como un .xls en lugar de un .xla como sugieren los ejemplos en su enlace? No estoy seguro si esto haría la diferencia.
B Hart
44
bueno a conocido: xlsb es robusto frente a trucos para descifrar contraseñas
Qbik
20
@ Fandango68 Esta pregunta se discutió hace años en meta . TLDR: Muchas (¿la mayoría?) De las preguntas sobre SO podrían ser maltratadas por actores malos, pero a menos que exista una evidencia clara de irregularidades, asumimos buena fe. Hay muchas razones legítimamente legales y éticas para descifrar una contraseña de VBA. Además, discutir las debilidades de los sistemas actuales en última instancia contribuye a una mejor seguridad en el futuro y desalienta a las personas a depender ciegamente de sistemas inseguros ahora.
jmbpiano

Respuestas:

701

Puede probar este VBAenfoque directo que no requiere edición HEX. Funcionará para cualquier archivo (* .xls, * .xlsm, * .xlam ...).

Probado y trabaja en:

Excel 2007
Excel 2010
Excel 2013 - versión de 32 bits
Excel 2016 - versión de 32 bits

¿Busca la versión de 64 bits? Ver esta respuesta

Cómo funciona

Haré todo lo posible para explicar cómo funciona. Disculpe mi inglés.

  1. El VBE llamará a una función del sistema para crear el cuadro de diálogo de contraseña.
  2. Si el usuario ingresa la contraseña correcta y hace clic en Aceptar, esta función devuelve 1. Si el usuario ingresa la contraseña incorrecta o hace clic en Cancelar, esta función devuelve 0.
  3. Después de cerrar el cuadro de diálogo, el VBE verifica el valor devuelto de la función del sistema
  4. si este valor es 1, el VBE "pensará" que la contraseña es correcta, por lo tanto, se abrirá el proyecto VBA bloqueado.
  5. El siguiente código intercambia la memoria de la función original utilizada para mostrar el diálogo de contraseña con una función definida por el usuario que siempre devolverá 1 cuando se le llame.

Usando el código

¡Haga una copia de seguridad de sus archivos primero!

  1. Abra los archivos que contienen sus proyectos VBA bloqueados
  2. Cree un nuevo archivo xlsm y almacene este código en el Módulo 1

    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. Pegue este código debajo del código anterior en el Módulo 1 y ejecútelo

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
    
  4. Regrese a sus proyectos VBA y disfrute.

Thanc Thanh Nguyễn
fuente
44
@ Chris, tienes toda la razón. Porque las funciones de la API de Windows están definidas para win 32 en este código.
Thanc Thanh Nguyễn
8
Alguna explicación sería buena de cómo está funcionando esto.
Dennis G
20
Ahora la única pregunta que queda (después de ver que este método impresionante funciona perfectamente), es cómo demonios puedo hacer que mi proyecto VBA esté protegido para evitar que otros usen este truco :)
EranG
66
Este código funciona perfectamente para desbloquear el código VBA, aunque cada vez que lo uso me impide volver a proteger el proyecto con una contraseña diferente, ¿alguien más ha tenido este problema?
Matthew Bond el
2
Descubrí que corrompe el proyecto VBA en el archivo de Excel, así que tuve que exportar todos los módulos / clases, luego guardar el archivo como xlsx (no macro), luego CERRAR el archivo (Excel estúpido), luego volver a abrir, luego importar módulos y copiar código de archivos de clase. En este punto, podría guardar el archivo como xlsm con mi propia contraseña en el proyecto VBA.
BH
217

Sí, siempre que esté utilizando una .xlshoja de cálculo de formato (el valor predeterminado para Excel hasta 2003). Para Excel 2007 en adelante, el valor predeterminado es .xlsx, que es un formato bastante seguro, y este método no funcionará.

Como dice Treb, es una comparación simple. Un método es simplemente intercambiar la entrada de contraseña en el archivo usando un editor hexadecimal (ver Editores hexadecimales para Windows ). Ejemplo paso a paso:

  1. Crea un nuevo archivo simple de Excel.
  2. En la parte de VBA, establezca una contraseña simple (digamos - 1234).
  3. Guarda el archivo y cierra. Luego verifique el tamaño del archivo - vea el truco de Stewbob
  4. Abra el archivo que acaba de crear con un editor hexadecimal.
  5. Copie las líneas que comienzan con las siguientes teclas:

    CMG=....
    DPB=...
    GC=...
    
  6. PRIMERO COPIA DE SEGURIDAD del archivo de Excel para el que no conoce la contraseña de VBA, luego ábralo con su editor hexadecimal y pegue las líneas copiadas anteriores del archivo ficticio.

  7. Guarde el archivo de Excel y salga.
  8. Ahora, abra el archivo de Excel en el que necesita ver el código VBA. La contraseña para el código VBA simplemente será 1234 (como en el ejemplo que estoy mostrando aquí).

Si necesita trabajar con Excel 2007 o 2010, hay algunas otras respuestas a continuación que pueden ayudar, particularmente estas: 1 , 2 , 3 .

EDITAR febrero de 2015: para otro método que parece muy prometedor, mire esta nueva respuesta de Đức Thanh Nguyễn.

Colin Pickard
fuente
¿Qué pasa si no hay líneas que comiencen con CMG = ...?
systemovich
1
¿En el archivo de Excel en blanco o en el bloqueado? Verifique el tamaño del archivo en blanco. Si es el archivo bloqueado, asegúrese de que su copia de seguridad esté segura, luego intente cambiar solo las otras dos líneas. ¿Estás seguro de que es un archivo cifrado?
Colin Pickard
66
La protección de contraseña de Excel 2007 (y el formato de archivo) es radicalmente diferente de Excel 2003. Incluí algunos detalles al respecto en mi respuesta a continuación. En mi opinión, la opción protegida por contraseña en un archivo de Excel 2007 es la primera vez en el historial de Microsoft Office que produce un archivo razonablemente seguro.
Stewbob
1
No pude establecer la contraseña de vba en un nuevo archivo de Excel 2016. ¿Podría alguien simplemente compartir el HEX para reemplazarlo con 1234? ¿O puede cambiar de máquina a máquina?
Mescalito
1
Este enfoque funcionó para mí en un archivo .xlsm. Lo guardé como .xls, hice esto y luego lo volví a convertir a .xlsm. Cabe señalar que puede aumentar de forma segura la longitud del archivo si la nueva CMG...cadena es más larga que la original.
Drew Chapin,
173

Me basé en la fantástica respuesta de Đức Thanh Nguyễn para permitir que este método funcione con versiones de Excel de 64 bits. Estoy ejecutando Excel 2010 de 64 bits en Windows 7 de 64 bits.

  1. Abra los archivos que contienen sus proyectos VBA bloqueados.
  2. Cree un nuevo archivo xlsm y almacene este código en el Módulo 1

    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. Pegue este código en el Módulo 2 y ejecútelo

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

DESCARGO DE RESPONSABILIDAD Esto funcionó para mí y lo he documentado aquí con la esperanza de que ayude a alguien. No lo he probado completamente . Asegúrese de guardar todos los archivos abiertos antes de continuar con esta opción.

kaybee99
fuente
1
No estoy seguro de por qué, pero cuando ejecuto esto en Excel para 365 MSP de 64 bits, Excel cierra los archivos y cuando lo reinicio, la contraseña sigue ahí.
Eborbath
Esto ya no se puede hacer en Excel, ya que las opciones en el menú contextual están atenuadas, por lo que no puede crear el módulo.
thanos.a
170

Hay otra solución (algo más fácil), sin los problemas de tamaño. Utilicé este enfoque hoy (en un archivo XLS 2003, usando Excel 2007) y tuve éxito.

  1. Copia de seguridad del archivo xls
  2. Abra el archivo en un editor HEX y ubique la DPB=...pieza
  3. Cambiar la DPB=...cadena aDPx=...
  4. Abra el archivo xls en Excel
  5. Abra el editor de VBA ( ALT+ F11)
  6. la magia: Excel descubre una clave no válida (DPx) y le pregunta si desea continuar cargando el proyecto (básicamente ignorando la protección)
  7. Podrá sobrescribir la contraseña, así que cámbiela por algo que pueda recordar
  8. Guarde el archivo xls *
  9. ¡Cierra y vuelve a abrir el documento y trabaja tu magia VBA!

* NOTA: Asegúrese de haber cambiado la contraseña a un nuevo valor, de lo contrario, la próxima vez que abra la hoja de cálculo, Excel informará de errores (Error inesperado), luego, cuando acceda a la lista de módulos VBA, verá los nombres de módulos de origen pero reciben otro error al intentar abrir formularios / código / etc. Para remediar esto, regrese a las Propiedades del proyecto VBA y configure la contraseña con un nuevo valor. ¡Guarde y vuelva a abrir el documento de Excel y debería estar listo!

Pieter
fuente
3
Desafortunadamente, esto no funcionó para mí con Excel para Mac 2011 v14.2.5. Obtuve la opción de reparar el archivo, no restablecer la contraseña, y el efecto fue perder todos los scripts de VBA.
Joe Carroll
Solución perfecta: hice esto con un archivo de 2003 usando HxD Hex Editor
Chris W
44
Lo acabo de probar (.xls, Excel 2007) y no funcionó. El resultado es: los módulos son visibles, el código parece funcionar, pero al abrir un módulo, indica un error inesperado (40230) .
KekuSemau
2
El mismo error aquí (Excel 2010), pero luego me di cuenta de que me había saltado 'configurar una nueva contraseña y guardar / volver a abrir' (pasos 7-9) de Pieter.
Owen B
+1 ¡Este método también funcionó en nuestro archivo de acceso (.mdb) poco desarrollado! Ahora podemos mejorar eso, ¡gracias por esto!
Er Gabriel Doronila
65

Colin Pickard tiene una excelente respuesta, pero hay un 'cuidado' con esto. Hay casos (aún no he descubierto la causa) en los que la longitud total de la entrada "CMG = ........ GC = ...." en el archivo es diferente de un archivo de Excel al siguiente. En algunos casos, esta entrada será de 137 bytes, y en otros será de 143 bytes. La longitud de 137 bytes es la impar, y si esto sucede cuando crea su archivo con la contraseña '1234', simplemente cree otro archivo, y debería saltar a la longitud de 143 bytes.

Si intenta pegar el número incorrecto de bytes en el archivo, perderá su proyecto VBA cuando intente abrir el archivo con Excel.

EDITAR

Esto no es válido para archivos Excel 2007/2010. El formato de archivo .xlsx estándar es en realidad un archivo .zip que contiene numerosas subcarpetas con el formato, el diseño, el contenido, etc., almacenados como datos xml. Para un archivo de Excel 2007 desprotegido, puede cambiar la extensión .xlsx a .zip, luego abrir el archivo zip y ver todos los datos xml. Es muy sencillo.

Sin embargo, cuando protege con contraseña un archivo de Excel 2007, todo el archivo .zip (.xlsx) en realidad se cifra mediante el cifrado RSA. Ya no es posible cambiar la extensión a .zip y examinar el contenido del archivo.

Stewbob
fuente
Entonces necesitas usar herramientas de hackeo zip estándar. Ya no es un problema de "¿cómo puedo hacer una copia de seguridad de un archivo de Excel".
Tipo anónimo
3
@ Tipo anónimo: creo que una herramienta de craqueo zip no ayudará. Según entiendo Stewbob, no son las entradas de archivo en el archivo zip las que están cifradas, sino todo el archivo zip en sí, que debe incluir el encabezado y el directorio central.
Treb
2
Solo curiosidad: ¿cómo podría ser RSA cuando solo ingreso una contraseña (simétrica)?
kizzx2
¿Qué tal cuando el archivo en el que desea ingresar tiene las teclas más cortas? ¿Sigue creando vba docs hasta que obtenga uno que tenga 137?
onlyone
1
¿Está seguro de que todo el archivo zip está cifrado cuando bloquea el proyecto VBA? Todavía puedo abrir el archivo zip y ver la estructura del archivo ... Y la subcarpeta xl \ contiene el archivo vbaProject.bin que tiene el conocido bloque de hashing "CMG = ... GC =".
Nigel Heffernan
63

Para un tipo de archivo .xlsmo .dotmdebe hacerlo de una manera ligeramente diferente.

  1. Cambia la extensión del .xlsmarchivo a .zip.
  2. Abra el archivo .zip (con WinZip o WinRar, etc.) y vaya a la carpeta xl.
  3. Extraiga el vbaProject.binarchivo y ábralo en un Editor Hex (uso HxD , es completamente gratuito y liviano).
  4. Busque DPBy reemplace con DPxy guarde el archivo.
  5. Reemplace el vbaProject.binarchivo antiguo con este nuevo en el archivo comprimido.
  6. Vuelva a cambiar la extensión del archivo a .xlsm.
  7. Abra el libro de trabajo para saltar los mensajes de advertencia.
  8. Abra Visual Basic dentro de Excel.
  9. Vaya a Herramientas> Propiedades del proyecto VBAP> Pestaña Protección.
  10. Ingrese una nueva contraseña y guarde el .xlsmarchivo.
  11. Cierra y vuelve a abrir y tu nueva contraseña funcionará.
Mate
fuente
8
Trabajó en Excel 2016, Windows 10 64bit. (archivos xlsm)
LimaNightHawk
3
Trabajó en Word 2016, Windows 10 64 bits (archivos dotm)
NBajanca
77
Gran solución, funcionó para mí en Excel 2013 de 64 bits. Puede omitir el cambio de extensiones de archivo .zipsi tiene instalado 7-Zip . En este caso, puede hacer clic derecho en el .xlsmarchivo y elegir "7-Zip -> Abrir archivo"
nkatsar
funciona con Word 2013, win7x64. (Es muy triste, ser engañado tan fácilmente para creer que el código es algo seguro).
Berry Tsakala
1
@ThierryMichel ¡Combinación de soluciones anteriores y prueba y error!
Matt
35

Vale la pena señalar que si tiene un archivo Excel 2007 (xlsm), simplemente puede guardarlo como un archivo Excel 2003 (xls) y utilizar los métodos descritos en otras respuestas.

Andy
fuente
44
eso no es cierto, he trabajado con archivos para los que la conversión a xls / xla de xlsm era imposible, Excel 2007 y 2010 fallaban cada vez, probé varias instancias, desde un mensaje de error - Kod wyjątku: c0000005 Przesunięcie wyjątku: 005d211d
Qbik
44
Sí, tú puedes hacerlo. Lo he hecho muchas veces. Si hay algo en las hojas que es necesario y que no se transfiere a la versión anterior, hago esto: 1.convertir .xlsm a .xls 2.descifrar el código de .xls 3.convertir .xlsm a .xlsx 4.Poner el código de los módulos en .xls a. xlsx y guárdelo como .xlsm
ZygD
Funciona después de convertir xlsm a xls como en la respuesta.
Purus
32

Con mi turno, esto se basa en la excelente respuesta de kaybee99 que se basa en la fantástica respuesta de Thanc Thanh Nguyễn para permitir que este método funcione con las versiones x86 y amd64 de Office.

Una descripción general de lo que ha cambiado, evitamos push / ret, que está limitado a direcciones de 32 bits y lo reemplazamos con mov / jmp reg.

Probado y trabaja en

Word / Excel 2016 - Versión de 32 bits .
Word / Excel 2016: versión de 64 bits .

cómo funciona

  1. Abra los archivos que contienen sus proyectos VBA bloqueados.
  2. Cree un nuevo archivo con el mismo tipo que el anterior y almacene este código en el Módulo 1

    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. Pegue este código en el Módulo 2 y ejecútelo

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
VePe
fuente
3
¡Perfecto! Trabajar con Windows Server 2016, Excel 2016 32 bit
Zin Min
Esto funcionó en un archivo .xlsm en Excel Office 365. ¡Gracias!
Ryan James el
Todavía funciona en 2019, las últimas versiones de Office 365 de 64 bits, ¡chicos increíbles!
XavierAM
Gracias por el código actualizado, me enfrentaba a fallas al ejecutar la versión anterior (64 bits), pero todo bien con su versión
emjaySX
Impresionante ...
Funcionó
17

¿Has intentado simplemente abrirlos en OpenOffice.org?

Tuve un problema similar hace algún tiempo y descubrí que Excel y Calc no entendían el cifrado del otro, por lo que permitieron el acceso directo a casi todo.

Esto fue hace un tiempo, así que si eso no fue solo una casualidad de mi parte, también podría haber sido reparado.

Greg
fuente
15

En el caso de que su bloque CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX" en su archivo de 'contraseña conocida' sea más corto que el bloque existente en el archivo de 'contraseña desconocida', rellene sus cadenas hexadecimales con ceros finales para alcanzar la longitud correcta.

p.ej

CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"

en el archivo de contraseña desconocido, debe establecerse en

CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" para preservar la longitud del archivo.

También he tenido esto trabajando con archivos .XLA (formato 97/2003) en Office 2007.

Spangen
fuente
1
Esto funciona, pero como he descubierto recientemente (comentado anteriormente) también puede simplemente agregar caracteres nulos después de la cita final de cierre en el bloque GC = "..." hasta que alcance la misma longitud.
tobriand
13

Para Excel 2007 en adelante, debe cambiar su extensión de archivo a .zip. En el archivo hay una subcarpeta xl, allí encontrará vbaProject.bin. Siga el paso anterior con vbaProject.bin y guárdelo nuevamente en el archivo. Modifique de nuevo su extensión y ¡voilà! (es decir, siga los pasos anteriores)

usuario3761175
fuente
1
Puedo confirmar que esto también funciona para archivos .xlam con Excel 2010. +1!
Gimelist
12

Las contraseñas de proyectos de VBA en documentos de Access, Excel, Powerpoint o Word ( 2007, 2010, 2013 or 2016versiones con extensiones .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM) se pueden eliminar fácilmente .

Es simplemente una cuestión de cambiar la extensión del nombre de archivo a .ZIP, descomprimir el archivo y usar cualquier editor hexadecimal básico (como XVI32 ) para "romper" la contraseña existente, lo que "confunde" a Office para que solicite una nueva contraseña la próxima vez que el archivo sea abrió.

Un resumen de los pasos:

  • cambie el nombre del archivo para que tenga una .ZIPextensión.
  • abre el ZIPy ve a la XLcarpeta.
  • extraer vbaProject.biny abrirlo con un editor hexadecimal
  • "Buscar y reemplazar" para "reemplazar todo" cambiando DPBa DPX.
  • Guarde los cambios, .binvuelva a colocar el archivo en el archivo zip, vuelva a su extensión normal y abra el archivo como siempre.
  • ALT + F11 para ingresar al Editor VB y hacer clic derecho en el Explorador de proyectos para elegir VBA Project Properties.
  • En la Protectionpestaña, establece una nueva contraseña.
  • Haga clic OK, cierre el archivo, vuelva a abrirlo, presione ALT + F11.
  • Ingrese la nueva contraseña que configuró.

En este punto, puede eliminar la contraseña por completo si lo desea.

Las instrucciones completas con un video paso a paso que hice "cuando" están en YouTube aquí .

Es sorprendente que esta solución haya estado disponible durante años, y Microsoft no ha solucionado el problema.


La moraleja de la historia?

No se debe confiar en las contraseñas de Microsoft Office VBA Project para la seguridad de ninguna información confidencial . Si la seguridad es importante, use un software de cifrado de terceros.

ashleedawg
fuente
9

Colin Pickard es en su mayoría correcto, pero no confunda la protección de "contraseña para abrir" para todo el archivo con la protección de contraseña de VBA, que es completamente diferente de la anterior y es la misma para Office 2003 y 2007 (para Office 2007, cambie el nombre el archivo a .zip y busque el vbaProject.bin dentro del zip). Y que técnicamente la forma correcta de editar el archivo es usar un visor de documentos compuestos OLE como CFX para abrir la secuencia correcta. Por supuesto, si solo está reemplazando bytes, el antiguo editor binario puede funcionar.

Por cierto, si se pregunta sobre el formato exacto de estos campos, ahora lo tienen documentado:

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

Yuhong Bao
fuente
2
El siguiente enlace proporciona detalles para los archivos de formato XSLM. gbanik.blogspot.co.uk/2010/08/… La solución es la misma que la descrita anteriormente por Yuhong Bao, pero es una lectura interesante e incluye capturas de pantalla.
JohnLBevan
7

Si el archivo es un archivo zip válido (los primeros bytes se 50 4Busan en formatos como .xlsm), descomprima el archivo y busque el subarchivo xl/vbaProject.bin. Este es un archivo CFB al igual que los .xlsarchivos. Siga las instrucciones para el formato XLS (aplicado al subarchivo) y luego simplemente comprima el contenido.

Para el formato XLS, puede seguir algunos de los otros métodos en esta publicación. Personalmente prefiero buscar el DPB=bloque y reemplazar el texto

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

con espacios en blanco Esto evita problemas de tamaño de contenedor CFB.

SheetJS
fuente
7

Probé algunas de las soluciones anteriores y ninguna de ellas funciona para mí (excel 2007 xlsm file). Luego encontré otra solución que incluso recupera la contraseña, no solo descifrarla.

Inserta este código en el módulo, ejecútalo y dale algo de tiempo. Recuperará su contraseña por la fuerza 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
Luboš Suk
fuente
1
¡Agradable! Creo que recibió un voto negativo porque su solución desbloquea la hoja de trabajo en lugar del módulo VBA. Sin embargo, lo encontré útil, ¡así que gracias!
PBD10017
1
Este es mi libro de trabajo personal. Los autores citaron a Bob McCormick como autor original modificado posteriormente por Norman Harker y JE McGimpsey 2002.
Charles Byrne
5

ElcomSoft fabrica los productos Advanced Office Password Breaker y Advanced Office Password Recovery que pueden aplicarse a este caso, siempre que el documento se haya creado en Office 2007 o anterior.

Charles Duffy
fuente
4

Tom - Inicialmente cometí un error de colegial ya que no vi el tamaño del byte y en su lugar copié y pegué desde el "CMG" configurado para la entrada posterior. Sin embargo, se trataba de dos tamaños de texto diferentes entre los dos archivos, y perdí el proyecto VBA tal como lo advirtió Stewbob.

Usando HxD, hay un contador que rastrea la cantidad de archivos que está seleccionando. Copie comenzando desde CMG hasta que el contador lea 8F (hexadecimal para 143) y del mismo modo al pegar en el archivo bloqueado - Terminé con el doble del número de "..." al final de la pasta, que parecía extraño de alguna manera y se sentía casi antinatural, pero funcionó.

No sé si es crucial, pero me aseguré de cerrar el editor hexadecimal y sobresalir antes de volver a abrir el archivo en Excel. Luego tuve que ir a través de los menús para abrir el Editor VB, a las Propiedades del Proyecto VB e ingresé la contraseña 'nueva' para desbloquear el código.

Espero que esto ayude.

Scoob
fuente
4

Mi herramienta, VbaDiff , lee VBA directamente del archivo, por lo que puede usarlo para recuperar el código VBA protegido de la mayoría de los documentos de Office sin recurrir a un editor hexadecimal.

Chris Spicer
fuente
He probado esta herramienta y funciona muy bien, sin embargo, la versión gratuita recupera las primeras 53 líneas. Para recuperar mi archivo, tuve que seguir las instrucciones de Andy para desbloquear la contraseña. Luego abrí mi xlsm con VbaDiff en ambos paneles y luego hice clic en la hoja con mi código. Lo obtuve con copiar y pegar y lo puse en mi archivo de Excel recuperado pero vacío vba.
thanos.a
2

La protección es una simple comparación de texto en Excel. Cargue Excel en su depurador favorito ( Ollydbg es mi herramienta de elección), encuentre el código que hace la comparación y corríjalo para que siempre sea verdadero, esto debería permitirle acceder a las macros.

Treb
fuente
1

Para Excel 2016 de 64 bits en una máquina con Windows 10, he usado un editor hexadecimal para poder cambiar la contraseña de un xla protegido (no he probado esto para ninguna otra extensión). Consejo: cree una copia de seguridad antes de hacer esto.

Los pasos que tomé:

  1. Abra el vba en el editor hexadecimal (por ejemplo XVI)
  2. Buscar en este DPB
  3. Cambiar DPB a otra cosa, como DPX
  4. Guárdalo!
  5. Vuelva a abrir el .xla, aparecerá un mensaje de error, simplemente continúe.
  6. Ahora puede cambiar la contraseña de .xla abriendo las propiedades y dirigiéndose a la pestaña de contraseña.

¡Espero que esto haya ayudado a algunos de ustedes!

Edwin van der V
fuente
Tuve éxito al abrir un .xls antiguo usando esto en Windows 10 en la última versión de Excel 365, mientras que la respuesta principal ya no funciona. Descargué HxD y cambié la última letra como se recomienda, y omití los errores. Todo bien ahora, gracias!
Estudiante de Starnes
0

la extensión de su archivo de Excel cambia a xml. Y ábralo en el bloc de notas. encontrar el texto de la contraseña en el archivo xml.

ves como debajo de la línea;

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

(Perdón por mi mal ingles)

Desarrollador33
fuente
¿Puede explicar cómo su respuesta es mejor que las muy buenas ya proporcionadas?
Noel Widmer
Mi solución no tiene un código. solución muy compacta que no sea.
Desarrollador33
1
Esta solución que ha proporcionado no funciona en 2019.
Daniel L. VanDenBosch
Tampoco funciona para mí en Office 365
thanos.a
0

Si trabaja en Javausted puede intentarlo VBAMacroExtractor. Después de extraer los scripts de VBA, .xlsmencontré la contraseña en texto sin formato.

Grez
fuente