Me pediram para atualizar algumas macros do Excel 2003, mas os projetos VBA são protegidos por senha e parece que há uma falta de documentação ... ninguém sabe as senhas.
Existe uma maneira de remover ou quebrar a senha em um projeto VBA?
Me pediram para atualizar algumas macros do Excel 2003, mas os projetos VBA são protegidos por senha e parece que há uma falta de documentação ... ninguém sabe as senhas.
Existe uma maneira de remover ou quebrar a senha em um projeto VBA?
Respostas:
Você pode tentar essa VBA
abordagem direta , que não requer edição HEX. Ele funcionará para qualquer arquivo (* .xls, * .xlsm, * .xlam ...).
Testado e trabalha em:
Excel 2007
Excel 2010
Excel 2013 - versão de 32 bits
Excel 2016 - versão de 32 bits
Procurando a versão de 64 bits? Veja esta resposta
Vou tentar o meu melhor para explicar como funciona - desculpe meu inglês.
Faça backup dos seus arquivos primeiro!
Crie um novo arquivo xlsm e armazene esse código no Módulo1
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
Cole esse código no código acima no Módulo1 e execute-o
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Volte para seus projetos VBA e aproveite.
Sim, desde que você esteja usando uma .xls
planilha de formato (o padrão para o Excel até 2003). Para o Excel 2007 em diante, o padrão é .xlsx
, que é um formato razoavelmente seguro, e esse método não funciona.
Como Treb diz, é uma comparação simples. Um método é simplesmente trocar a entrada da senha no arquivo usando um editor hexadecimal (consulte Editores hexadecimais para Windows ). Exemplo passo a passo:
Copie as linhas começando com as seguintes chaves:
CMG=....
DPB=...
GC=...
PRIMEIRO BACKUP do arquivo do Excel para o qual você não conhece a senha do VBA, abra-o com o seu editor hexadecimal e cole as linhas copiadas acima do arquivo fictício.
Se você precisar trabalhar com o Excel 2007 ou 2010, há outras respostas abaixo que podem ajudar, especialmente estas: 1 , 2 , 3 .
EDIT Fevereiro de 2015: para outro método que parece muito promissor, veja esta nova resposta de Thanc Thanh Nguyễn.
CMG...
sequência for maior que a original.
Eu construí a resposta fantástica de Thanc Thanh Nguyễn para permitir que esse método funcione com versões de 64 bits do Excel. Estou executando o Excel 2010 de 64 bits no Windows 7 de 64 bits.
Crie um novo arquivo xlsm e armazene esse código no Módulo1
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
Cole esse código no Módulo2 e execute-o
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
AVISO LEGAL Isso funcionou para mim e eu o documentei aqui na esperança de ajudar alguém. Ainda não testei completamente . Salve todos os arquivos abertos antes de continuar com esta opção.
Existe outra solução (um pouco mais fácil), sem os problemas de tamanho. Eu usei essa abordagem hoje (em um arquivo XLS de 2003, usando o Excel 2007) e tive êxito.
DPB=...
peçaDPB=...
string paraDPx=...
* NOTA: Certifique-se de alterar a senha para um novo valor; caso contrário, na próxima vez em que abrir a planilha, o Excel reportará erros (erro inesperado); em seguida, ao acessar a lista de módulos VBA, você verá os nomes dos módulos de origem, mas recebe outro erro ao tentar abrir forms / code / etc. Para remediar isso, volte às Propriedades do projeto VBA e defina a senha para um novo valor. Salve e reabra o documento do Excel e você deve estar pronto!
Colin Pickard tem uma resposta excelente, mas há um "cuidado" com isso. Há casos (ainda não descobri a causa) em que o comprimento total da entrada "CMG = ........ GC = ...." no arquivo é diferente de um arquivo do Excel para o arquivo Próximo. Em alguns casos, essa entrada terá 137 bytes e, em outros, 143 bytes. O comprimento de 137 bytes é ímpar e, se isso acontecer quando você criar seu arquivo com a senha '1234', basta criar outro arquivo e ele deverá saltar para o comprimento de 143 bytes.
Se você tentar colar o número incorreto de bytes no arquivo, você perderá o projeto do VBA ao tentar abrir o arquivo com o Excel.
EDITAR
Isso não é válido para arquivos do Excel 2007/2010. O formato de arquivo .xlsx padrão é, na verdade, um arquivo .zip que contém inúmeras subpastas com formatação, layout, conteúdo, etc., armazenados como dados xml. Para um arquivo do Excel 2007 desprotegido, basta alterar a extensão .xlsx para .zip, abrir o arquivo zip e verificar todos os dados xml. É muito simples.
No entanto, quando você protege um arquivo do Excel 2007 com senha, o arquivo .zip (.xlsx) inteiro é realmente criptografado usando a criptografia RSA. Não é mais possível alterar a extensão para .zip e navegar pelo conteúdo do arquivo.
Para um tipo de arquivo .xlsm
ou, .dotm
você precisa fazer isso de uma maneira um pouco diferente.
.xlsm
arquivo para .zip
.vbaProject.bin
arquivo e abra-o em um editor hexadecimal (eu uso o HxD , totalmente gratuito e leve.)DPB
e substitua porDPx
e salve o arquivo.vbaProject.bin
arquivo por este novo no arquivo compactado..xlsm
..xlsm
arquivo.Vale ressaltar que, se você tiver um arquivo do Excel 2007 (xlsm), poderá simplesmente salvá-lo como um arquivo do Excel 2003 (xls) e usar os métodos descritos em outras respostas.
1.
converter .xlsm em .xls 2.
decifrar o código de .xls 3.
converter .xlsm em .xlsx 4.
Coloque o código dos módulos em .xls em. xlsx e salve-o como .xlsm
Por minha vez, isso se baseia na excelente resposta de kaybee99, baseada na fantástica resposta de Thanc Thanh Nguyễn para permitir que esse método funcione com as versões x86 e amd64 do Office.
Uma visão geral do que foi alterado, evitamos push / ret, limitado a endereços de 32 bits, e substituí-lo por mov / jmp reg.
Testado e funciona em
Word / Excel 2016 - versão de 32 bits .
Word / Excel 2016 - versão de 64 bits .
como funciona
Crie um novo arquivo com o mesmo tipo que o acima e armazene esse código no Módulo1
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
Cole esse código no Módulo2 e execute-o
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Você já tentou simplesmente abri-los no OpenOffice.org?
Eu tive um problema semelhante há algum tempo e descobri que o Excel e o Calc não entendiam a criptografia um do outro e, portanto, permitiam acesso direto a praticamente tudo.
Isso foi há um tempo atrás, então, se isso não foi apenas um acaso da minha parte, também pode ter sido corrigido.
No caso de seu bloco de
CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
seu arquivo de 'senha conhecida' seja menor que o bloco existente no arquivo de 'senha desconhecida', preencha suas seqüências de caracteres hexadecimais com zeros à direita para atingir o comprimento correto.
por exemplo
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
no arquivo de senha desconhecida, deve ser definido como
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000"
para preservar o comprimento do arquivo.
Também trabalhei com arquivos .XLA (formato 97/2003) no Office 2007.
Para o Excel 2007 em diante, é necessário alterar a extensão do arquivo para .zip No arquivo morto, há uma subpasta xl, e você encontrará vbaProject.bin. Siga a etapa acima com vbaProject.bin e salve-o novamente no arquivo morto. Modifique de volta sua extensão e pronto! (ou seja, siga as etapas acima)
As senhas do projeto VBA em documentos do Access, Excel, Powerpoint ou Word ( 2007, 2010, 2013 or 2016
versões com extensões .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM
) podem ser facilmente removidas .
É simplesmente uma questão de alterar a extensão do nome do arquivo para .ZIP
, descompactar o arquivo e usar qualquer Editor Hex básico (como XVI32 ) para "quebrar" a senha existente, o que "confunde" o Office e solicita uma nova senha na próxima vez que o arquivo for aberto.
.ZIP
extensão.ZIP
e vá para a XL
pasta.vbaProject.bin
e abra-o com um editor hexadecimalDPB
para DPX
..bin
arquivo de volta no zip, retorne à sua extensão normal e abra o arquivo normalmente.VBA Project Properties
.Protection
guia, defina uma nova senha.OK
Fechar o arquivo, abra-o novamente e pressione ALT + F11.Nesse ponto, você pode remover a senha completamente, se desejar.
Instruções completas com um vídeo passo a passo que eu fiz "caminho de volta quando" estão no YouTube aqui .
É meio chocante que essa solução alternativa esteja disponível há anos, e a Microsoft não tenha corrigido o problema.
A moral da história?
Microsoft Office senhas projeto VBA são para não ser invocado para a segurança de qualquer informação sensível . Se a segurança for importante, use software de criptografia de terceiros.
Colin Pickard está mais correto, mas não confunda a proteção "senha para abrir" para o arquivo inteiro com a proteção por senha do VBA, que é completamente diferente da anterior e é a mesma para o Office 2003 e 2007 (para o Office 2007, renomeie o arquivo para .zip e procure o vbaProject.bin dentro do zip). E que tecnicamente a maneira correta de editar o arquivo é usar um visualizador de documentos compostos OLE como o CFX para abrir o fluxo correto. Obviamente, se você está apenas substituindo bytes, o editor binário antigo comum pode funcionar.
BTW, se você está se perguntando sobre o formato exato desses campos, eles o documentam agora:
http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
Se o arquivo for um arquivo zip válido (os primeiros bytes são 50 4B
usados em formatos como .xlsm
), descompacte o arquivo e procure o subarquivo xl/vbaProject.bin
. Este é um arquivo CFB, assim como os .xls
arquivos. Siga as instruções para o formato XLS (aplicado ao subarquivo) e, em seguida, basta compactar o conteúdo.
Para o formato XLS, você pode seguir alguns dos outros métodos nesta postagem. Pessoalmente, prefiro procurar o DPB=
bloco e substituir o texto
CMG="..."
DPB="..."
GC="..."
com espaços em branco. Isso evita problemas de tamanho de contêiner CFB.
Eu tentei algumas das soluções acima e nenhuma delas funciona para mim (arquivo xlsm do Excel 2007). Então eu encontrei outra solução que até recupera a senha, não apenas a quebra.
Insira este código no módulo, execute-o e aguarde algum tempo. Ele recuperará sua senha com força 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
A ElcomSoft fabrica os produtos Advanced Office Password Breaker e Advanced Office Password Recovery que podem ser aplicados a esse caso, desde que o documento tenha sido criado no Office 2007 ou anterior.
Tom - cometi um erro de estudante inicialmente porque não assisti ao tamanho dos bytes e, em vez disso, copiei e colei do "CMG" configurado para a entrada subsequente. Porém, havia dois tamanhos de texto diferentes entre os dois arquivos, e eu perdi o projeto VBA exatamente como Stewbob avisou.
Usando o HxD, há um contador que controla a quantidade de arquivo que você está selecionando. Copiar a partir de CMG até o contador exibir 8F (hex para 143) e da mesma forma ao colar no arquivo bloqueado - acabei com o dobro do número de "..." no final da pasta, que parecia estranho de alguma forma e parecia quase antinatural, mas funcionou.
Não sei se é crucial, mas certifiquei-me de desligar o editor hexadecimal e o excel antes de reabrir o arquivo no Excel. Eu tive que percorrer os menus para abrir o Editor do VB, acessar as Propriedades do VBProject e inserir a 'nova' senha para desbloquear o código.
Eu espero que isso ajude.
Minha ferramenta, VbaDiff , lê o VBA diretamente do arquivo, para que você possa usá-lo para recuperar o código VBA protegido da maioria dos documentos do escritório sem recorrer a um editor hexadecimal.
Para o Excel 2016 de 64 bits em uma máquina Windows 10, usei um editor hexadecimal para poder alterar a senha de um xla protegido (não testei isso para outras extensões). Gorjeta: crie um backup antes de fazer isso.
Os passos que tomei:
Espero que isso tenha ajudado alguns de vocês!
a extensão do seu arquivo excel mude para xml. E abra-o no bloco de notas. texto da senha localizado no arquivo xml.
você vê como abaixo da linha;
Sheets("Sheet1").Unprotect Password:="blabla"
(desculpe pelo meu inglês ruim)
Se você trabalha, Java
pode tentar VBAMacroExtractor
. Depois de extrair os scripts VBA, .xlsm
encontrei a senha em texto sem formatação.