Меня попросили обновить некоторые макросы Excel 2003, но проекты VBA защищены паролем, и, похоже, не хватает документации ... никто не знает пароли.
Есть ли способ удаления или взлома пароля в проекте VBA?
Меня попросили обновить некоторые макросы Excel 2003, но проекты VBA защищены паролем, и, похоже, не хватает документации ... никто не знает пароли.
Есть ли способ удаления или взлома пароля в проекте VBA?
Ответы:
Вы можете попробовать этот прямой VBA
подход, который не требует редактирования HEX. Это будет работать для любых файлов (* .xls, * .xlsm, * .xlam ...).
Протестировано и работает на:
Excel 2007
Excel 2010
Excel 2013 - 32-разрядная версия
Excel 2016 - 32-разрядная версия
Ищете 64-битную версию? Смотрите этот ответ
Я постараюсь объяснить, как это работает - извините, пожалуйста, за мой английский.
Пожалуйста, сделайте резервную копию ваших файлов в первую очередь!
Создайте новый файл xlsm и сохраните этот код в 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
Вставьте этот код под вышеуказанным кодом в Module1 и запустите его
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Возвращайтесь к своим проектам VBA и наслаждайтесь.
Да, если вы используете .xls
электронную таблицу формата (по умолчанию для Excel до 2003 года). Для Excel 2007 и более поздних версий по умолчанию .xlsx
используется довольно безопасный формат, и этот метод не будет работать.
Как говорит Треб, это простое сравнение. Один из способов - просто заменить запись пароля в файле с помощью шестнадцатеричного редактора (см. Шестнадцатеричные редакторы для Windows ). Пошаговый пример:
Скопируйте строки, начиная со следующих ключей:
CMG=....
DPB=...
GC=...
Первое резервное копирование копию файла Excel, для которого вы не знаете пароль VBA, затем откройте его в своем шестнадцатеричном редакторе и вставьте скопированные выше строки из фиктивного файла.
Если вам нужно работать с Excel 2007 или 2010, ниже могут быть полезны и другие ответы, в частности: 1 , 2 , 3 .
РЕДАКТИРОВАТЬ Февраль 2015: для другого метода, который выглядит очень многообещающим, посмотрите на этот новый ответ Đức Thanh Nguyễn.
CMG...
строка длиннее оригинальной.
Я основывался на фантастическом ответе Тхана Нгуйена, чтобы этот метод мог работать с 64-битными версиями Excel. Я использую 64-битную версию Excel 2010 на 64-битной Windows 7.
Создайте новый файл xlsm и сохраните этот код в 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
Вставьте этот код в Module2 и запустите его
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ Это сработало для меня, и я задокументировал это здесь в надежде, что это кому-нибудь поможет. Я не полностью проверил это . Пожалуйста, сохраните все открытые файлы, прежде чем продолжить с этой опцией.
Есть другое (несколько более простое) решение, без проблем с размером. Я использовал этот подход сегодня (в файле 2003 XLS, используя Excel 2007) и был успешным.
DPB=...
детальDPB=...
строку наDPx=...
* ПРИМЕЧАНИЕ. Убедитесь, что вы изменили пароль на новое значение, в противном случае при следующем открытии электронной таблицы Excel сообщит об ошибках (неожиданная ошибка), а затем при доступе к списку модулей VBA вы увидите имена исходные модули, но при попытке открыть формы / код / и т. д. появляется другая ошибка Чтобы исправить это, вернитесь в Свойства проекта VBA и установите новое значение пароля. Сохраните и снова откройте документ Excel, и все будет хорошо!
У Колина Пикарда отличный ответ, но есть один «настороже» с этим. Есть случаи (я еще не выяснил причину), где общая длина записи "CMG = ........ GC = ...." в файле отличается от одного файла Excel до следующий. В некоторых случаях эта запись будет 137 байтов, а в других - 143 байта. Длина 137 байт является нечетной, и если это происходит при создании файла с паролем «1234», просто создайте другой файл, и он должен перейти к длине 143 байта.
Если вы попытаетесь вставить в файл неправильное количество байтов, вы потеряете ваш проект VBA, когда попытаетесь открыть файл в Excel.
РЕДАКТИРОВАТЬ
Это недопустимо для файлов Excel 2007/2010. Стандартный формат файла .xlsx на самом деле представляет собой файл .zip, содержащий многочисленные подпапки с форматированием, макетом, содержимым и т. Д., Которые хранятся в виде данных XML. Для незащищенного файла Excel 2007 вы можете просто изменить расширение .xlsx на .zip, затем открыть файл zip и просмотреть все данные XML. Это очень просто.
Однако, когда вы защищаете файл Excel 2007 паролем, весь файл .zip (.xlsx) фактически шифруется с использованием шифрования RSA. Больше невозможно изменить расширение на .zip и просмотреть содержимое файла.
Для файла .xlsm
или .dotm
типа файла вам нужно сделать это немного по-другому.
.xlsm
файла на .zip
.vbaProject.bin
файл и откройте его в Hex Editor (я использую HxD , он совершенно бесплатный и легкий).DPB
и замените DPx
и сохраните файл.vbaProject.bin
файл на новый в архивном файле..xlsm
..xlsm
файл.Стоит отметить, что если у вас есть файл Excel 2007 (xlsm), вы можете просто сохранить его как файл Excel 2003 (xls) и использовать методы, описанные в других ответах.
1.
конвертирую .xlsm в .xls, взломаю 2.
код .xls, 3.
конвертирую .xlsm в .xlsx. 4.
Поместите код из модулей в .xls в. xlsx и сохраните его как .xlsm
С моей стороны, это основано на превосходном ответе kaybee99, который основан на фантастическом ответе Тхана Нгуйена, чтобы этот метод мог работать как с версиями Office для x86, так и для amd64.
Обзор того, что изменилось, мы избегаем push / ret, который ограничен 32-битными адресами, и заменяем его на mov / jmp reg.
Проверено и работает на
Word / Excel 2016 - 32-битная версия .
Word / Excel 2016 - 64-битная версия .
как это работает
Создайте новый файл того же типа, что и выше, и сохраните этот код в 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
Вставьте этот код в Module2 и запустите его
Sub unprotected()
If Hook Then
MsgBox "VBA Project is unprotected!", vbInformation, "*****"
End If
End Sub
Вы пытались просто открыть их в OpenOffice.org?
Некоторое время назад у меня была похожая проблема, и я обнаружил, что Excel и Calc не понимают шифрование друг друга и поэтому имеют прямой доступ практически ко всему.
Это было некоторое время назад, поэтому, если бы это была не просто случайность с моей стороны, это также могло быть исправлено.
В случае, если ваш блок
CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX"
в файле «известного пароля» короче, чем существующий блок в файле «неизвестного пароля», добавьте шестнадцатеричные строки с конечными нулями, чтобы получить правильную длину.
например
CMG="xxxxxx"\r\nDPB="xxxxxxxx"\r\nGC="xxxxxxxxxx"
в файле с неизвестным паролем, должно быть установлено
CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000"
сохранить длину файла.
У меня также была эта работа с файлами .XLA (формат 97/2003) в Office 2007.
Для Excel 2007 и более поздних вам необходимо изменить расширение файла на .zip. В архиве есть подпапка xl, в которой вы найдете vbaProject.bin. Выполните шаг выше с vbaProject.bin, затем сохраните его обратно в архиве. Измените свое расширение и вуаля! (то есть следуйте инструкциям выше)
Пароли проекта VBA для документов Access, Excel, Powerpoint или Word ( 2007, 2010, 2013 or 2016
версии с расширениями .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM
) могут быть легко удалить .
Это просто вопрос изменения расширения имени файла .ZIP
, разархивирования файла и использования любого простого шестнадцатеричного редактора (например, обычного XVI32 ), чтобы «сломать» существующий пароль, что «смущает» Office, поэтому он запрашивает новый пароль в следующий раз, когда файл открыт.
.ZIP
расширение.ZIP
и перейдите в XL
папку.vbaProject.bin
и открыть его с помощью Hex EditorDPB
наDPX
..bin
файл обратно в zip, верните его в нормальное расширение и откройте файл как обычно.VBA Project Properties
.Protection
вкладке Установить новый пароль.OK
, закройте файл, снова откройте его, нажмите ALT + F11.На этом этапе вы можете полностью удалить пароль, если захотите.
Полные инструкции с пошаговым видео, которое я сделал «когда-то», находятся на YouTube здесь .
Это шокирует, что этот обходной путь существует уже много лет, и Microsoft не устранила проблему.
Мораль этой истории?
Пароли проекта Microsoft Office VBA не должны использоваться для обеспечения безопасности любой конфиденциальной информации . Если важна безопасность, используйте стороннее программное обеспечение для шифрования.
Колин Пикард в основном прав, но не путайте защиту «пароль для открытия» для всего файла с защитой паролем VBA, которая полностью отличается от предыдущей и одинакова для Office 2003 и 2007 (для Office 2007 переименуйте файл в .zip и найдите vbaProject.bin внутри zip). И что технически правильный способ редактировать файл - это использовать средство просмотра составных документов OLE, такое как CFX, чтобы открыть правильный поток. Конечно, если вы просто заменяете байты, может работать обычный старый бинарный редактор.
Кстати, если вас интересует точный формат этих полей, они уже задокументированы:
http://msdn.microsoft.com/en-us/library/dd926151%28v=office.12%29.aspx
Если файл является допустимым zip-файлом (первые несколько байтов 50 4B
используются в таких форматах, как .xlsm
), то разархивируйте файл и найдите подфайл xl/vbaProject.bin
. Это файл CFB, как и .xls
файлы. Следуйте инструкциям для формата XLS (применяется к подфайлу), а затем просто заархивируйте содержимое.
Для формата XLS вы можете использовать некоторые другие методы в этом посте. Я лично предпочитаю искать DPB=
блок и заменять текст
CMG="..."
DPB="..."
GC="..."
с пробелами. Это устраняет проблемы с размером контейнера CFB.
Я попробовал некоторые из решений выше, и ни одно из них не работает для меня (файл Excel 2007 xlsm). Затем я нашел другое решение, которое даже восстанавливает пароль, а не просто взламывает его.
Вставьте этот код в модуль, запустите его и дайте ему немного времени. Он восстановит ваш пароль грубой силой.
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 производит Advanced Office Password Breaker и Advanced Office Password Recovery продукты, которые могут применяться в этом случае, если документ был создан в Office 2007 или более ранней версии.
Том - я сначала сделал ошибку для школьника, так как не смотрел размер байта, а вместо этого скопировал и вставил из «CMG», настроенного для последующей записи. Это были два разных размера текста между этими двумя файлами, и я потерял проект VBA, как и предупреждал Stewbob.
Используя HxD, есть счетчик, отслеживающий, сколько файлов вы выбираете. Скопируйте, начиная с CMG, пока счетчик не прочитает 8F (шестнадцатеричное для 143), а также при вставке в заблокированный файл - у меня получилось вдвое больше «...» в конце вставки, что выглядело как-то странно и ощущалось почти неестественно, но это сработало.
Я не знаю, насколько это важно, но я убедился, что закрыл и шестнадцатеричный редактор, и выключил Excel, прежде чем снова открыть файл в Excel. Затем мне пришлось пройти через меню, чтобы открыть VB Editor, в VBProject Properties и ввести «новый» пароль, чтобы разблокировать код.
Надеюсь, это поможет.
Мой инструмент, VbaDiff , считывает VBA непосредственно из файла, поэтому вы можете использовать его для восстановления защищенного кода VBA из большинства офисных документов без использования шестнадцатеричного редактора.
В 64-разрядной версии Excel 2016 на компьютере с Windows 10 я использовал шестнадцатеричный редактор, чтобы иметь возможность изменить пароль защищенной xla (не проверял это ни для каких других расширений). Подсказка: создайте резервную копию, прежде чем сделать это.
Шаги, которые я предпринял:
Я надеюсь, что это помогло некоторым из вас!
расширение вашего файла Excel изменилось на xml. И откройте его в блокноте. текст пароля найти в файле XML.
Вы видите как ниже линии;
Sheets("Sheet1").Unprotect Password:="blabla"
(Извините за мой плохой английский)
Если вы работаете в, Java
вы можете попробовать VBAMacroExtractor
. После извлечения сценариев VBA из .xlsm
я нашел там пароль в виде открытого текста.