Czy istnieje sposób na złamanie hasła w projekcie Excel VBA?

485

Poproszono mnie o aktualizację niektórych makr programu Excel 2003, ale projekty VBA są chronione hasłem i wygląda na to, że brakuje dokumentacji ... nikt nie zna haseł.

Czy istnieje sposób na usunięcie lub złamanie hasła w projekcie VBA?

Jonathan Sayce
źródło
Czy możesz zapisać jako .xls zamiast .xla, jak sugerują to przykłady w twoim linku? Nie jestem pewien, czy to by miało znaczenie.
B Hart
4
dobrze wiadomo: xlsb jest odporny na sztuczki polegające na łamaniu haseł
Qbik
20
@ Fandango68 To pytanie zostało omówione wiele lat temu na stronie meta . TLDR: Wiele (większość?) Pytań dotyczących SO może być nadużywanych przez złych aktorów, ale chyba że istnieją wyraźne dowody złego postępowania, zakładamy dobrą wiarę. Istnieje wiele uzasadnionych prawnych i etycznych powodów złamania hasła VBA. Ponadto omawianie słabości obecnych systemów ostatecznie przyczynia się do lepszego bezpieczeństwa w przyszłości i zniechęca ludzi do ślepego polegania na niepewnych systemach teraz.
jmbpiano

Odpowiedzi:

699

Możesz wypróbować to bezpośrednie VBApodejście, które nie wymaga edycji HEX. Będzie działać dla wszystkich plików (* .xls, * .xlsm, * .xlam ...).

Testowany i działa na:

Excel 2007
Excel 2010
Excel 2013 - wersja 32-bitowa
Excel 2016 - wersja 32-bitowa

Szukasz wersji 64-bitowej? Zobacz tę odpowiedź

Jak to działa

Postaram się jak najlepiej wyjaśnić, jak to działa - proszę wybaczyć mój angielski.

  1. VBE wywoła funkcję systemową, aby utworzyć okno dialogowe hasła.
  2. Jeśli użytkownik wprowadzi prawidłowe hasło i kliknie OK, funkcja zwróci 1. Jeśli użytkownik wprowadzi nieprawidłowe hasło lub kliknie Anuluj, funkcja zwróci 0.
  3. Po zamknięciu okna dialogowego VBE sprawdza zwracaną wartość funkcji systemowej
  4. jeśli ta wartość wynosi 1, VBE „pomyśli”, że hasło jest prawidłowe, a zatem zablokowany projekt VBA zostanie otwarty.
  5. Poniższy kod zamienia pamięć oryginalnej funkcji używanej do wyświetlania okna dialogowego hasła z funkcją zdefiniowaną przez użytkownika, która zawsze zwraca 1 po wywołaniu.

Korzystanie z kodu

Najpierw wykonaj kopię zapasową plików!

  1. Otwórz plik (i), które zawierają twoje zablokowane projekty VBA
  2. Utwórz nowy plik xlsm i zapisz ten kod w 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
    
  3. Wklej ten kod pod powyższym kodem w Module1 i uruchom go

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
    
  4. Wróć do swoich projektów VBA i ciesz się.

Thc Thanh Nguyễn
źródło
4
@Chris masz absolutną rację. Ponieważ funkcje Windows API są zdefiniowane dla win 32 w tym kodzie.
Thc Thanh Nguyễn
8
Przyjemne byłoby wyjaśnienie, jak to działa.
Dennis G
20
Teraz pozostaje tylko jedno pytanie (po zobaczeniu, jak ta imponująca metoda działa idealnie), w jaki sposób, do diabła, mogę wzmocnić mój projekt VBA, aby uniemożliwić innym korzystanie z tego
hacka
6
Ten kod działa idealnie w odblokowywaniu kodu VBA, chociaż za każdym razem, gdy go używam, uniemożliwia mi ponowne zabezpieczenie projektu innym hasłem, czy ktoś jeszcze miał ten problem?
Matthew Bond
2
Odkryłem, że powoduje to uszkodzenie projektu VBA w pliku Excel, więc musiałem wyeksportować wszystkie moduły / klasy, następnie zapisać plik jako xlsx (bez makr), następnie ZAMKNĄĆ plik (głupi Excel), a następnie ponownie otworzyć, a następnie importuj moduły i kopiuj kod z plików klas. W tym momencie mogłem zapisać plik jako xlsm z własnym hasłem w projekcie VBA.
BH
217

Tak, pod warunkiem, że używasz .xlsarkusza kalkulacyjnego formatu (ustawienie domyślne dla programu Excel do 2003 r.). W programie Excel 2007 i późniejszym ustawieniem domyślnym jest .xlsxdość bezpieczny format i ta metoda nie będzie działać.

Jak mówi Treb, jest to proste porównanie. Jedną z metod jest po prostu zamiana hasła w pliku za pomocą edytora szesnastkowego (patrz Edytory szesnastkowe dla systemu Windows ). Przykład krok po kroku:

  1. Utwórz nowy prosty plik programu Excel.
  2. W części VBA ustaw proste hasło (powiedzmy - 1234).
  3. Zapisz plik i wyjdź. Następnie sprawdź rozmiar pliku - patrz gotcha Stewboba
  4. Otwórz właśnie utworzony plik za pomocą edytora szesnastkowego.
  5. Skopiuj linie zaczynając od następujących kluczy:

    CMG=....
    DPB=...
    GC=...
  6. PIERWSZA KOPIA plik Excel, dla którego nie znasz hasła VBA, a następnie otwórz go za pomocą edytora szesnastkowego i wklej powyższe skopiowane linie z pliku fikcyjnego.

  7. Zapisz plik programu Excel i wyjdź.
  8. Teraz otwórz plik programu Excel, w którym chcesz zobaczyć kod VBA. Hasło dla kodu VBA będzie po prostu 1234 (jak w przykładzie, który pokazuję tutaj).

Jeśli potrzebujesz pracować z programem Excel 2007 lub 2010, poniżej znajdziesz kilka innych odpowiedzi, w szczególności: 1 , 2 , 3 .

EDYCJA Luty 2015: dla innej metody, która wygląda bardzo obiecująco, spójrz na nową odpowiedź Đức Thanh Nguyguna.

Colin Pickard
źródło
Co jeśli nie ma linii zaczynających się od CMG = ...?
systemovich,
1
W pustym pliku Excela, czy w zablokowanym? Sprawdź rozmiar pustego pliku. Jeśli jest to zablokowany plik, upewnij się, że kopia zapasowa jest bezpieczna, a następnie spróbuj zmienić tylko pozostałe dwie linie. Jesteś pewien, że to zaszyfrowany plik?
Colin Pickard,
6
Ochrona hasłem programu Excel 2007 (i format pliku) jest zupełnie inna niż ochrona programu Excel 2003. W odpowiedzi poniżej zamieściłem kilka szczegółów na ten temat. Moim zdaniem opcja chroniona hasłem w pliku programu Excel 2007 po raz pierwszy w historii pakietu Microsoft Office utworzyła dość bezpieczny plik.
Stewbob,
1
Nie byłem w stanie ustawić hasła VBA na nowym pliku programu Excel 2016. Czy ktoś może po prostu udostępnić HEX, aby zastąpić 1234? Czy może zmieniać się z maszyny na maszynę?
Mescalito
1
To podejście zadziałało w przypadku pliku .xlsm. Zapisałem go jako .xls, zrobiłem to, a następnie przekonwertowałem z powrotem na .xlsm. Należy zauważyć, że możesz bezpiecznie zwiększyć długość pliku, jeśli nowy CMG...ciąg jest dłuższy niż oryginał.
Drew Chapin,
173

Zbudowałem na podstawie fantastycznej odpowiedzi Đức Thanh Nguyễna, aby umożliwić tej metodzie działanie z 64-bitowymi wersjami programu Excel. Korzystam z programu Excel 2010 64-bit na 64-bitowym systemie Windows 7.

  1. Otwórz plik (i), które zawierają twoje zablokowane projekty VBA.
  2. Utwórz nowy plik xlsm i zapisz ten kod w 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
  3. Wklej ten kod w Module2 i uruchom go

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

WYŁĄCZENIE ODPOWIEDZIALNOŚCI To zadziałało dla mnie i udokumentowałem to tutaj w nadziei, że pomoże komuś pomóc. Nie w pełni go przetestowałem . Przed kontynuowaniem tej opcji należy zapisać wszystkie otwarte pliki.

kaybee99
źródło
1
Nie jestem pewien dlaczego, ale kiedy uruchamiam to w programie Excel for 365 MSP 64-bitowy program Excel ulega awarii, zamyka pliki, a po ponownym uruchomieniu hasło nadal tam jest.
eborbath
Nie można tego już robić w programie Excel, ponieważ opcje w menu kontekstowym są wyszarzone, więc nie można utworzyć modułu.
thanos.a
170

Istnieje inne (nieco łatwiejsze) rozwiązanie bez problemów z rozmiarem. Zastosowałem to podejście dzisiaj (w pliku XLS 2003, używając programu Excel 2007) i odniosłem sukces.

  1. Utwórz kopię zapasową pliku xls
  2. Otwórz plik w edytorze HEX i zlokalizuj DPB=...część
  3. Zmień DPB=...ciąg naDPx=...
  4. Otwórz plik xls w programie Excel
  5. Otwórz edytor VBA ( ALT+ F11)
  6. magia: Excel odkrywa nieprawidłowy klucz (DPx) i pyta, czy chcesz kontynuować ładowanie projektu (w zasadzie ignorując ochronę)
  7. Będziesz mógł zastąpić hasło, więc zmień je na coś, co pamiętasz
  8. Zapisz plik xls *
  9. Zamknij i ponownie otwórz dokument i uruchom magię VBA!

* UWAGA: Upewnij się, że zmieniłeś hasło na nową wartość, w przeciwnym razie przy następnym otwarciu arkusza kalkulacyjnego Excel zgłosi błędy (nieoczekiwany błąd), a następnie, gdy uzyskasz dostęp do listy modułów VBA, zobaczysz teraz nazwy moduły źródłowe, ale pojawia się kolejny błąd podczas próby otwarcia formularzy / kodu / itp. Aby temu zaradzić, wróć do właściwości projektu VBA i ustaw hasło na nową wartość. Zapisz i ponownie otwórz dokument Excel i powinieneś już iść!

Pieter
źródło
3
Niestety nie działało to dla mnie w programie Excel 2011 dla komputerów Mac w wersji 14.2.5. Mam opcję naprawy pliku, a nie resetowania hasła, a efektem jest utrata wszystkich skryptów VBA.
Joe Carroll
Idealne rozwiązanie - zrobiłem to z plikiem z 2003 roku używając HxD Hex Editor
Chris W
4
Właśnie próbowałem (.xls, Excel 2007) i to nie działało. Rezultat: Moduły są widoczne, kod rzeczywiście wydaje się działać, ale podczas otwierania modułu wyświetla się nieoczekiwany błąd (40230) .
KekuSemau
2
Ten sam błąd tutaj (Excel 2010) - ale potem zdałem sobie sprawę, że pominąłem „ustaw nowe hasło i zapisz / otwórz ponownie” (kroki 7-9) z Pietera.
Owen B,
+1 Ta metoda działała również na naszym słabo opracowanym pliku dostępu (.mdb)! Teraz możemy to poprawić, dzięki za to!
Er Gabriel Doronila
65

Colin Pickard ma doskonałą odpowiedź, ale jest jedno „uważaj”. Istnieją przypadki (jeszcze nie ustaliłem przyczyny), w których całkowita długość pozycji „CMG = ........ GC = ....” w pliku różni się od jednego pliku programu Excel do pliku Kolejny. W niektórych przypadkach ten wpis będzie miał 137 bajtów, a w innych 143 bajtów. Długość 137 bajtów jest nieparzysta, a jeśli tak się stanie, gdy utworzysz plik z hasłem „1234”, po prostu utwórz inny plik, który powinien przeskoczyć do długości 143 bajtów.

Jeśli spróbujesz wkleić niewłaściwą liczbę bajtów do pliku, stracisz swój projekt VBA podczas próby otwarcia pliku za pomocą programu Excel.

EDYTOWAĆ

Nie dotyczy to plików Excel 2007/2010. Standardowy format pliku .xlsx to tak naprawdę plik .zip zawierający liczne podfoldery z formatowaniem, układem, zawartością itp., Przechowywane jako dane xml. W przypadku niechronionego pliku Excel 2007 możesz po prostu zmienić rozszerzenie .xlsx na .zip, a następnie otworzyć plik zip i przejrzeć wszystkie dane xml. To bardzo proste.

Jednak po zabezpieczeniu hasłem pliku Excel 2007 cały plik .zip (.xlsx) jest w rzeczywistości szyfrowany przy użyciu szyfrowania RSA. Nie można już zmienić rozszerzenia na .zip i przeglądać zawartości pliku.

Stewbob
źródło
Następnie musisz użyć standardowych narzędzi do hakowania zip. Nie jest to już problem „jak utworzyć kopię zapasową pliku Excel”.
Anonimowy typ
3
@Anonimowy typ: Myślę, że narzędzie do łamania zip nie pomoże. Jak rozumiem Stewbob, to nie wpisy w pliku zip są zaszyfrowane, ale sam plik zip, który powinien zawierać nagłówek i katalog centralny.
Treb
2
Ciekawe: jak to może być RSA, gdy wprowadzę tylko jedno hasło (symetryczne)?
kizzx2
A może plik, do którego chcesz się dostać, ma krótsze klucze? Po prostu twórz dokumenty vba, dopóki nie uzyskasz takiego, który ma 137?
brak
1
Czy jesteś pewien, że cały plik zip jest szyfrowany po zablokowaniu projektu VBA? Nadal mogę otworzyć plik zip i zobaczyć strukturę pliku .... A podfolder xl \ zawiera plik vbaProject.bin, który ma znany blok mieszania „CMG = ... GC =”.
Nigel Heffernan
63

W przypadku typu .xlsmlub .dotmpliku musisz to zrobić nieco inaczej.

  1. Zmień rozszerzenie .xlsmpliku na .zip.
  2. Otwórz plik .zip (z WinZip lub WinRar itp.) I przejdź do folderu xl.
  3. Wyodrębnij vbaProject.binplik i otwórz go w edytorze heksadecymalnym (używam HxD , jest całkowicie darmowy i lekki).
  4. Wyszukaj, DPBzamień DPxi zapisz plik.
  5. Zamień stary vbaProject.binplik na nowy w spakowanym pliku.
  6. Zmień rozszerzenie pliku z powrotem na .xlsm.
  7. Otwórz skoroszyt, pomiń komunikaty ostrzegawcze.
  8. Otwórz program Visual Basic w programie Excel.
  9. Przejdź do Narzędzia> Właściwości projektu VBAP> Karta Ochrona.
  10. Wprowadź nowe hasło i zapisz .xlsmplik.
  11. Zamknij i ponownie otwórz, a nowe hasło będzie działać.
Matt
źródło
8
Pracował w programie Excel 2016, Windows 10 64bit. (pliki
xlsm
3
Pracował w Word 2016, Windows 10 64bit (pliki dotm)
NBajanca
7
Świetne rozwiązanie, działało dla mnie w programie Excel 2013 64-bit. Możesz pominąć zmianę rozszerzeń plików, .zipjeśli masz zainstalowany 7-Zip . W takim przypadku możesz po prostu kliknąć .xlsmplik prawym przyciskiem myszy i wybrać „7-Zip -> Otwórz archiwum”
nkatsar
współpracuje z Word 2013, win7x64. (To bardzo smutne, że tak łatwo oszukać, że kod jest nieco bezpieczny).
Berry Tsakala
1
@ThierryMichel Połączenie wcześniejszych rozwiązań oraz prób i błędów!
Matt
35

Warto zauważyć, że jeśli masz plik Excel 2007 (xlsm), możesz po prostu zapisać go jako plik Excel 2003 (xls) i użyć metod opisanych w innych odpowiedziach.

Andy
źródło
4
to nieprawda, pracowałem z plikami, dla których konwersja do xls / xla z xlsm była niemożliwa, Excel 2007 i 2010 ulegał awarii za każdym razem, próbowałem różnych instancji, z jednej wiadomości o błędzie - Kod wyjątku: c0000005 Przesunięcie wyjątku: 005d211d
Qbik
4
Tak, możesz to zrobić. Zrobiłem to wiele razy. Jeśli jest coś na arkuszach, co jest konieczne, a co nie jest przeniesione do starszej wersji, robię to: 1.przekonwertować .xlsm na .xls 2.złamać kod .xls 3.przekonwertować .xlsm na .xlsx 4.Umieść kod z modułów w .xls na. xlsx i zapisz to jako .xlsm
ZygD
Działa po konwersji xlsm na xls jak w odpowiedzi.
Purus
31

Z moją koleją, jest to oparte na doskonałej odpowiedzi kaybee99, która jest oparta na fantastycznej odpowiedzi Đức Thanh Nguyễn, aby pozwolić tej metodzie działać zarówno z wersjami pakietu Office x86, jak i amd64.

Przegląd tego, co zostało zmienione, unikamy push / ret, który jest ograniczony do 32-bitowych adresów i zastępujemy go mov / jmp reg.

Testowane i działa na

Word / Excel 2016 - wersja 32-bitowa .
Word / Excel 2016 - wersja 64-bitowa .

jak to działa

  1. Otwórz plik (i), które zawierają twoje zablokowane projekty VBA.
  2. Utwórz nowy plik tego samego typu co powyżej i zapisz ten kod w 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
  3. Wklej ten kod w Module2 i uruchom go

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
VePe
źródło
3
Doskonały! Pracuj z Windows Server 2016, Excel 2016 32-bit
Zin Min
To działało na pliku .xlsm w Excel Office 365. Dziękujemy!
Ryan James,
Nadal działa w 2019 roku, najnowsze wersje Office 365 64bits, wspaniali faceci!
XavierAM
Dzięki za zaktualizowany kod, miałem do czynienia z awariami działającymi przy poprzedniej wersji (64-bitowej), ale wszystko w porządku z twoją wersją
emjaySX
Niesamowite ...
działało
17

Czy próbowałeś po prostu otworzyć je w OpenOffice.org?

Miałem podobny problem jakiś czas temu i okazało się, że Excel i Calc nie rozumieli się nawzajem w szyfrowaniu i dlatego umożliwili bezpośredni dostęp do prawie wszystkiego.

To było jakiś czas temu, więc jeśli nie byłby to zwykły przypadek z mojej strony, to również mógł zostać załatany.

greg
źródło
15

W przypadku, gdy Twój blok CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX" w pliku „znanego hasła” jest krótszy niż istniejący blok w pliku „nieznanego hasła”, uzupełnij ciąg szesnastkowy zerowymi końcami, aby osiągnąć prawidłową długość.

na przykład

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

w pliku nieznanego hasła należy ustawić na

CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" aby zachować długość pliku.

Miałem to również do pracy z plikami .XLA (format 97/2003) w pakiecie Office 2007.

Spangen
źródło
1
Działa to, ale jak niedawno odkryłem (skomentowałem powyżej), możesz po prostu dodać znaki puste po ostatnim cudzysłowie zamykającym w bloku GC = "...", dopóki nie osiągniesz tej samej długości.
tobriand
13

W przypadku programu Excel 2007 musisz zmienić rozszerzenie pliku na .zip W archiwum znajduje się podfolder xl, w którym znajduje się vbaProject.bin. Wykonaj powyższy krok za pomocą vbaProject.bin, a następnie zapisz go z powrotem w archiwum. Zmodyfikuj swoje rozszerzenie i voilà! (co oznacza wykonaj powyższe kroki)

użytkownik3761175
źródło
1
Mogę potwierdzić, że działa to również w przypadku plików .xlam w programie Excel 2010. +1!
Gimelist
12

Hasła projektu VBA do dokumentów Access, Excel, Powerpoint lub Word ( 2007, 2010, 2013 or 2016wersje z rozszerzeniami .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM) można łatwo usunąć .

Wystarczy zmienić rozszerzenie nazwy pliku .ZIP, rozpakować plik i użyć dowolnego podstawowego edytora heksadecymalnego (takiego jak XVI32 ), aby „złamać” istniejące hasło, co „myli” Office, więc monituje o nowe hasło przy następnym pliku otwierany.

Podsumowanie kroków:

  • zmień nazwę pliku, aby miał .ZIProzszerzenie.
  • otwórz ZIPi przejdź do XLfolderu.
  • rozpakuj vbaProject.bini otwórz go za pomocą edytora heksadecymalnego
  • „Wyszukaj i zamień”, aby „zamienić wszystko” zmienia się DPBna DPX.
  • Zapisz zmiany, umieść .binplik z powrotem w zipie, przywróć normalne rozszerzenie i otwórz plik jak zwykle.
  • ALT + F11, aby przejść do edytora VB i kliknij prawym przyciskiem myszy w Eksploratorze projektów, aby wybrać VBA Project Properties.
  • Na Protectionkarcie Ustaw nowe hasło.
  • Kliknij OK, zamknij plik, otwórz go ponownie, naciśnij ALT + F11.
  • Wprowadź nowe ustawione hasło.

W tym momencie możesz całkowicie usunąć hasło, jeśli chcesz.

Wykonaj instrukcje wraz z filmem krok po kroku, który zrobiłem „dawno temu, kiedy” jest na YouTube tutaj .

To trochę szokujące, że to obejście istniało od lat, a Microsoft nie naprawił tego problemu.


Morał tej historii?

Nie można powoływać się na hasła Microsoft Office VBA Project dla bezpieczeństwa jakichkolwiek poufnych informacji . Jeśli bezpieczeństwo jest ważne, użyj oprogramowania szyfrującego innej firmy.

ashleedawg
źródło
9

Colin Pickard jest w większości poprawny, ale nie mylić ochrony „hasłem, aby otworzyć” dla całego pliku z ochroną hasłem VBA, która jest zupełnie inna od poprzedniej i jest taka sama dla Office 2003 i 2007 (dla Office 2007, zmień nazwę plik do .zip i poszukaj vbaProject.bin wewnątrz zip). I technicznie poprawnym sposobem edycji pliku jest użycie złożonej przeglądarki dokumentów OLE, takiej jak CFX, aby otworzyć właściwy strumień. Oczywiście, jeśli zastępujesz bajty, zwykły stary edytor binarny może działać.

BTW, jeśli zastanawiasz się nad dokładnym formatem tych pól, mają je teraz udokumentowane:

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

Yuhong Bao
źródło
2
Poniższy link zawiera szczegółowe informacje na temat plików w formacie XSLM. gbanik.blogspot.co.uk/2010/08/… Rozwiązanie jest takie samo jak przedstawione powyżej przez Yuhong Bao, ale zapewnia ciekawą lekturę i zawiera zrzuty ekranu.
JohnLBevan,
7

Jeśli plik jest prawidłowym plikiem zip (kilka pierwszych bajtów jest 50 4Bużywanych w formatach takich jak .xlsm), rozpakuj plik i poszukaj podtekstu xl/vbaProject.bin. Jest to plik CFB, podobnie jak .xlspliki. Postępuj zgodnie z instrukcjami dla formatu XLS (zastosowanego do podtekstu), a następnie po prostu skompresuj zawartość.

W przypadku formatu XLS możesz zastosować inne metody opisane w tym poście. Osobiście wolę wyszukiwanie DPB=bloku i zastępowanie tekstu

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

z pustymi spacjami. Pozwala to uniknąć problemów z rozmiarem kontenera CFB.

SheetJS
źródło
7

Wypróbowałem niektóre z powyższych rozwiązań i żadne z nich nie działa dla mnie (plik Excel xlsm 2007). Potem znalazłem inne rozwiązanie, które nawet odzyskuje hasło, a nie tylko je łamie.

Włóż ten kod do modułu, uruchom go i daj mu trochę czasu. Odzyska twoje hasło brutalną siłą.

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
źródło
1
Miły! Myślę, że masz jedną opinię, ponieważ twoje rozwiązanie odblokowuje arkusz roboczy, a nie moduł VBA. Mimo to uważam, że było to pomocne - dziękuję!
PBD10017 16.04.16
1
Mam ten mój osobisty skoroszyt. Autorzy cytowali Boba McCormicka jako oryginalnego autora, później zmodyfikowanego przez Normana Harkera i JE McGimpseya 2002.
Charles Byrne
5

ElcomSoft tworzy produkty Advanced Office Password Breaker i Advanced Office Password Recovery , które mogą mieć zastosowanie w tym przypadku, o ile dokument został utworzony w pakiecie Office 2007 lub wcześniejszym.

Charles Duffy
źródło
4

Tom - początkowo popełniłem błąd ucznia, ponieważ nie oglądałem wielkości bajtu, a zamiast tego skopiowałem i wkleiłem z zestawu „CMG” do następnego wpisu. Były to jednak dwa różne rozmiary tekstu między tymi dwoma plikami i straciłem projekt VBA, tak jak ostrzegał Stewbob.

Używając HxD, istnieje licznik śledzący, ile plików wybierasz. Kopiuj, zaczynając od CMG, aż licznik odczyta 8F (hex dla 143) i podobnie podczas wklejania do zablokowanego pliku - skończyłem z podwójną liczbą „...” na końcu pasty, która wyglądała dziwnie i wydawała się prawie nienaturalne, ale zadziałało.

Nie wiem, czy jest to kluczowe, ale upewniłem się, że zamknąłem zarówno edytor szesnastkowy, jak i celowałem przed ponownym otwarciem pliku w Excelu. Następnie musiałem przejść przez menu, aby otworzyć edytor VB, przejść do właściwości VBProject i wprowadzić „nowe” hasło, aby odblokować kod.

Mam nadzieję, że to pomoże.

Scoob
źródło
4

Moje narzędzie, VbaDiff , odczytuje VBA bezpośrednio z pliku, dzięki czemu można go użyć do odzyskania chronionego kodu VBA z większości dokumentów biurowych bez uciekania się do edytora szesnastkowego.

Chris Spicer
źródło
Mam testes tego narzędzia i działa naprawdę dobrze, jednak darmowa wersja pobiera pierwsze 53 wiersze. Aby odzyskać mój plik, musiałem postępować zgodnie z instrukcjami Andy'ego, aby odblokować hasło. Następnie otworzyłem xlsm z VbaDiff w obu oknach, a następnie kliknąłem arkusz z moim kodem. Mam go z kopiuj-wklej i umieść go w moim odzyskanym, ale pustym pliku Excela.
thanos.a
2

Ochrona to proste porównanie tekstu w programie Excel. Załaduj program Excel do swojego ulubionego debugera ( moim wyborem jest Ollydbg ), znajdź kod, który dokonuje porównania i napraw go, aby zawsze zwracał wartość true, co powinno umożliwić dostęp do makr.

Treb
źródło
1

W przypadku programu Excel 2016 64-bitowego na komputerze z systemem Windows 10 użyłem edytora szesnastkowego, aby móc zmienić hasło chronionego pliku Xla (nie testowałem tego pod kątem żadnych innych rozszerzeń). Wskazówka: utwórz kopię zapasową, zanim to zrobisz.

Kroki, które podjąłem:

  1. Otwórz VBA w edytorze szesnastkowym (na przykład XVI)
  2. Wyszukaj w tym DPB
  3. Zmień DPB na coś innego, na przykład DPX
  4. Zapisz to!
  5. Ponownie otwórz plik .xla, pojawi się komunikat o błędzie, po prostu kontynuuj.
  6. Możesz teraz zmienić hasło .xla, otwierając właściwości i przejdź do zakładki hasła.

Mam nadzieję, że to pomogło niektórym z was!

Edwin van der V.
źródło
Udało mi się otworzyć stary plik .xls przy użyciu tego w systemie Windows 10 w najnowszej wersji programu Excel 365, podczas gdy pierwsza odpowiedź niestety już nie działa. Pobrałem HxD i zmieniłem ostatnią literę zgodnie z zaleceniami i pominąłem błędy. Wszystko dobrze teraz, dzięki!
Starnes Student
0

rozszerzenie pliku Excela zmienia się na xml. I otwórz go w notatniku. tekst hasła znajdź w pliku xml.

widzisz jak poniżej linii;

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

(Przepraszam za mój zły angielski)

Developer33
źródło
Czy potrafisz wyjaśnić, w jaki sposób twoja odpowiedź jest lepsza od tych już bardzo dobrych?
Noel Widmer
moje rozwiązanie nie ma kodu. więc bardzo kompaktowe rozwiązanie inne niż.
Developer33
1
Podane przez
Dla mnie to też nie działa w biurze 365
thanos.a
0

Jeśli pracujesz Java, możesz spróbować VBAMacroExtractor. Po wypakowaniu skryptów VBA .xlsmznalazłem tam hasło w postaci zwykłego tekstu.

Grez
źródło