Мене попросили оновити деякі макроси 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
формат, який є досить захищеним форматом, і цей метод не працюватиме.
Як каже Треб, це просте порівняння. Один із способів - просто поміняти введення пароля у файл за допомогою шестигранного редактора (див. Hex редактори для Windows ). Покроковий приклад:
Скопіюйте рядки, починаючи з таких клавіш:
CMG=....
DPB=...
GC=...
ПЕРШИЙ РОЗВИТКУ файл excel, для якого ви не знаєте пароль VBA, потім відкрийте його в своєму шестигранному редакторі та вставте вище скопійовані рядки з фіктивного файлу.
Якщо вам потрібно працювати з Excel 2007 або 2010, нижче є кілька інших відповідей, які можуть допомогти, зокрема такі: 1 , 2 , 3 .
РЕДАКЦІЯ Лют 2015: для іншого способу, який виглядає дуже перспективно, погляньте на цю нову відповідь Джуча Тхана Нгуйона.
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
ВІДМОВА ВІДПОВІДАЛЬНІСТЬ Це спрацювало для мене, і я задокументував це тут, сподіваючись, що це комусь допоможе. Я не повністю його перевірив . Будь ласка, не забудьте зберегти всі відкриті файли, перш ніж продовжувати цю опцію.
Є ще одне (дещо простіше) рішення, без проблем із розмірами. Я сьогодні використовував такий підхід (у файлі XLS 2003 року, використовуючи Excel 2007) і мав успіх.
DPB=...
частинуDPB=...
рядок наDPx=...
* ПРИМІТКА. Переконайтеся, що ви змінили пароль на нове значення, інакше наступного разу, коли ви відкриєте електронну таблицю, Excel повідомить про помилки (Несподівана помилка), тоді, коли ви отримаєте доступ до списку модулів VBA, ви побачите імена вихідні модулі, але отримують ще одну помилку при спробі відкрити форми / код / тощо. Щоб виправити це, поверніться до властивостей проекту VBA та встановіть пароль на нове значення. Збережіть і повторно відкрийте документ Excel, і вам слід бути готовим!
У Коліна Пікарда є відмінна відповідь, але з цим є один "слідкувати". Є випадки (я ще не з'ясував причину), коли загальна довжина запису "CMG = ........ GC = ...." у файлі відрізняється від одного файлу excel до наступний. В одних випадках цей запис становитиме 137 байт, а в інших - 143 байти. Довжина довжиною 137 байт є непарною, і якщо це трапляється, коли ви створюєте свій файл із паролем '1234', просто створіть інший файл, і він повинен перейти до довжини 143 байти.
Якщо ви спробуєте вставити неправильну кількість байтів у файл, ви втратите свій проект VBA при спробі відкрити файл за допомогою Excel.
EDIT
Це не вірно для файлів 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) в офісі 2007 року.
Для Excel 2007 потрібно змінити розширення файлу на .zip В архіві є підпапка xl, там ви знайдете vbaProject.bin. Виконайте крок вище за допомогою vbaProject.bin, а потім збережіть його назад в архіві. Змініть назад своє розширення та voilà! (тобто дотримуйтесь кроків вище)
Паролі проекту VBA на документи Access, Excel, Powerpoint або Word ( 2007, 2010, 2013 or 2016
версії з розширеннями .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM
) можна легко видалити .
Це просто питання зміни розширення імені файлу на .ZIP
, розпакування файлу та використання будь-якого базового Hex Editor (наприклад, XVI32 ) для " зламання " існуючого пароля, який "плутає" Office, щоб він запросив новий пароль наступного разу, коли файл буде відкрили.
.ZIP
розширення.ZIP
та перейдіть до XL
папки.vbaProject.bin
і відкрийте його за допомогою шестигранного редактораDPB
на DPX
..bin
файл назад у zip, поверніть його до нормального розширення та відкрийте файл як звичайний.VBA Project Properties
.Protection
вкладці Встановіть новий пароль.OK
, закрийте файл, повторно відкрийте його, натисніть ALT + F11.У цей момент ви можете повністю видалити пароль, якщо захочете.
Повні інструкції з покроковим відео, яке я зробив «шлях назад , коли" знаходяться на YouTube тут .
Це шокує те, що цей шлях існує вже багато років, і Microsoft не вирішила проблеми.
Мораль історії?
Паролі Microsoft Office VBA Project не повинні покладатися на безпеку будь-якої конфіденційної інформації . Якщо безпека важлива, використовуйте сторонне програмне забезпечення для шифрування.
Колін Пікард здебільшого правильний, але не плутайте захист "пароль для відкриття" для всього файлу із захистом паролем VBA, який повністю відрізняється від попереднього та є однаковим для Office 2003 та 2007 (для Office 2007, перейменуйте файл у .zip та шукайте vbaProject.bin всередині zip). І технічно правильним способом редагування файлу є використання переглядача складених документів OLE типу CFX для відкриття правильного потоку. Звичайно, якщо ви просто замінюєте байти, звичайний старий бінарний редактор може працювати.
BTW, якщо вам цікаво точний формат цих полів, вони зараз це задокументували:
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.
Я спробував деякі рішення вище, і жодне з них не працює на мене (відмітний файл xlsm 2007). Тоді я знайшов ще одне рішення, яке навіть отримує пароль, а не просто його зламає.
Вставте цей код в модуль, запустіть його і дайте йому деякий час. Він відновить ваш пароль грубою силою.
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 Breaker Password і Advanced Office Password Recovery, які можуть застосовуватися до цього випадку, якщо документ створений в Office 2007 або раніше.
Том - Я спочатку допустив помилку школяра, оскільки не спостерігав за розміром байтів, а замість цього скопіював та вставив з "CMG", налаштованого на наступний запис. Це було два різних розміри тексту між двома файлами, і я втратив проект VBA так само, як попередив Stewbob.
Використовуючи HxD, є лічильник, який відстежує кількість файлів, які ви вибираєте. Скопіюйте, починаючи з CMG, поки лічильник не прочитає 8F (шістнадцятковий на 143), а також, коли вставляєте у заблокований файл - я в кінці пасти вдвічі перевищив число "...", яке виглядало дивним чином і майже відчувалося неприродно, але це спрацювало.
Я не знаю, чи це важливо, але я переконався, що закрив і шестигранний редактор, і вдосконалююсь, перш ніж знову відкрити файл у Excel. Тоді мені довелося пройти через меню, щоб відкрити редактор VB, в VBProject Properties і ввести "новий" пароль, щоб розблокувати код.
Я сподіваюся, що це допомагає.
Мій інструмент VbaDiff читає VBA безпосередньо з файлу, тому ви можете використовувати його для відновлення захищеного коду VBA з більшості офісних документів, не вдаючись до шестигранного редактора.
Для 64-розрядної версії Excel 2016 на машині Windows 10 я скористався шестигранним редактором, щоб можна було змінити пароль захищеного xla (не перевіряли цього для будь-яких інших розширень). Порада: створіть резервну копію, перш ніж це зробити.
Кроки, які я вжив:
Я сподіваюся, що це допомогло комусь із вас!
змінення розширення файлу Excel на xml. І відкрийте його в блокноті. текст пароля знайти у файлі xml
ви бачите, як нижче рядка;
Sheets("Sheet1").Unprotect Password:="blabla"
(вибачте за мою погану англійську)
Якщо ви працюєте, Java
ви можете спробувати VBAMacroExtractor
. Після вилучення сценаріїв VBA .xlsm
я знайшов там пароль у простому тексті.