Apakah ada cara untuk memecahkan kata sandi pada Proyek Excel VBA?


486

Saya diminta untuk memperbarui beberapa makro Excel 2003, tetapi proyek-proyek VBA dilindungi kata sandi, dan sepertinya ada kekurangan dokumentasi ... tidak ada yang tahu kata sandinya.

Apakah ada cara untuk menghapus atau memecahkan kata sandi pada proyek VBA?


Apakah Anda dapat Menyimpan-Sebagai .xls alih-alih .xla seperti yang disarankan oleh contoh di tautan Anda? Tidak yakin apakah ini akan membuat perbedaan.
B Hart

4
baik diketahui: xlsb kuat terhadap trik pemecahan kata sandi
Qbik

20
@ Fandango68 Pertanyaan ini dibahas bertahun-tahun yang lalu di meta . TLDR: Banyak (sebagian besar?) Pertanyaan tentang SO dapat disalahgunakan oleh aktor jahat, tetapi kecuali ada bukti yang jelas tentang kesalahan, kami menganggap itikad baik. Ada banyak alasan hukum dan etika yang sah untuk memecahkan kata sandi VBA. Selain itu, membahas kelemahan sistem saat ini pada akhirnya berkontribusi pada keamanan yang lebih baik di masa depan dan mencegah orang dari mengandalkan secara membuta pada sistem yang tidak aman sekarang.
jmbpiano

Jawaban:


701

Anda dapat mencoba VBApendekatan langsung ini yang tidak memerlukan pengeditan HEX. Ini akan berfungsi untuk semua file (* .xls, * .xlsm, * .xlam ...).

Diuji dan bekerja pada:

Excel 2007
Excel 2010
Excel 2013 - versi 32 bit
Excel 2016 - versi 32 bit

Mencari versi 64 bit? Lihat jawaban ini

Bagaimana itu bekerja

Saya akan mencoba yang terbaik untuk menjelaskan cara kerjanya - mohon permisi Bahasa Inggris saya.

  1. VBE akan memanggil fungsi sistem untuk membuat kotak dialog kata sandi.
  2. Jika pengguna memasukkan kata sandi yang benar dan klik OK, fungsi ini mengembalikan 1. Jika pengguna memasukkan kata sandi yang salah atau klik Batalkan, fungsi ini mengembalikan 0.
  3. Setelah kotak dialog ditutup, VBE memeriksa nilai yang dikembalikan dari fungsi sistem
  4. jika nilai ini 1, VBE akan "berpikir" bahwa kata sandi itu benar, maka proyek VBA yang dikunci akan dibuka.
  5. Kode di bawah ini menukar memori dari fungsi asli yang digunakan untuk menampilkan dialog kata sandi dengan fungsi yang ditentukan pengguna yang akan selalu mengembalikan 1 ketika dipanggil.

Menggunakan kodenya

Harap buat cadangan file Anda terlebih dahulu!

  1. Buka file yang berisi Proyek VBA Anda yang dikunci
  2. Buat file xlsm baru dan simpan kode ini di 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. Rekatkan kode ini di bawah kode di atas di Module1 dan jalankan

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
  4. Kembalilah ke Proyek VBA Anda dan nikmatilah.


4
@ Chris kamu benar sekali. Karena fungsi Windows API didefinisikan untuk win 32 dalam kode ini.
Thanc Thanh Nguyễn

8
Beberapa penjelasan akan menyenangkan tentang cara kerjanya.
Dennis G

20
Sekarang satu-satunya pertanyaan yang tersisa (setelah melihat metode yang mengesankan ini bekerja dengan sempurna), adalah bagaimana saya bisa membuat proyek VBA saya terlindungi lebih kuat untuk mencegah orang lain menggunakan peretasan ini :)
EranG

6
Kode ini berfungsi dengan baik dalam membuka kunci kode VBA walaupun setiap kali saya menggunakan ini mencegah saya dari melindungi kembali proyek dengan kata sandi yang berbeda, adakah orang lain yang memiliki masalah ini?
Matthew Bond

2
Saya menemukan itu merusak proyek VBA dalam file Excel jadi saya harus mengekspor semua modul / kelas, kemudian menyimpan file sebagai xlsx (non-makro), lalu TUTUP file (bodoh Excel), kemudian buka kembali, lalu mengimpor modul dan menyalin kode dari file kelas. Pada titik ini, saya dapat menyimpan file sebagai xlsm dengan kata sandi saya sendiri di proyek VBA.
BH

217

Ya ada, selama Anda menggunakan .xlsspreadsheet format (default untuk Excel hingga 2003). Untuk Excel 2007 dan seterusnya, defaultnya adalah .xlsx, yang merupakan format yang cukup aman, dan metode ini tidak akan berfungsi.

Seperti kata Treb, ini perbandingan sederhana. Salah satu metode adalah dengan hanya menukar entri kata sandi dalam file menggunakan hex editor (lihat Hex editor untuk Windows ). Contoh langkah demi langkah:

  1. Buat file excel sederhana baru.
  2. Di bagian VBA, setel kata sandi sederhana (katakan - 1234).
  3. Simpan file dan keluar. Kemudian periksa ukuran file - lihat Gotcha Stewbob
  4. Buka file yang baru saja Anda buat dengan hex editor.
  5. Salin garis yang dimulai dengan kunci berikut:

    CMG=....
    DPB=...
    GC=...
  6. CADANGAN PERTAMA untuk file excel yang Anda tidak tahu kata sandi VBA, lalu buka dengan hex editor Anda, dan tempelkan baris yang disalin di atas dari file dummy.

  7. Simpan file excel dan keluar.
  8. Sekarang, buka file excel Anda perlu melihat kode VBA masuk. Kata sandi untuk kode VBA hanya akan menjadi 1234 (seperti pada contoh saya tunjukkan di sini).

Jika Anda perlu bekerja dengan Excel 2007 atau 2010, ada beberapa jawaban lain di bawah ini yang mungkin membantu, terutama yang ini: 1 , 2 , 3 .

EDIT Feb 2015: untuk metode lain yang terlihat sangat menjanjikan, lihat jawaban baru ini oleh Đức Thanh Nguyễn.


Bagaimana jika tidak ada garis yang dimulai dengan CMG = ...?
systemovich

1
Di file excel kosong, atau yang terkunci? Periksa ukuran file dari file kosong. Jika ini file yang dikunci, pastikan cadangan Anda aman, lalu coba ubah hanya dua baris lainnya. Anda yakin itu file terenkripsi?
Colin Pickard

6
Perlindungan kata sandi Excel 2007 (dan format file) secara radikal berbeda dari Excel 2003. Saya menyertakan beberapa spesifik tentang hal itu dalam jawaban saya di bawah ini. Menurut pendapat saya, opsi kata sandi yang dilindungi pada file Excel 2007 adalah pertama kalinya dalam sejarah Microsoft Office bahwa mereka telah menghasilkan file yang cukup aman.
Stewbob

1
Saya tidak dapat menetapkan kata sandi vba pada file baru excel 2016. Bisakah seseorang dengan mudah berbagi HEX untuk menggantikan dengan 1234? Atau bisakah itu berubah dari mesin ke mesin?
Mescalito

1
Pendekatan ini berhasil bagi saya pada file .xlsm. Saya menyimpannya sebagai .xls, melakukan ini, dan kemudian mengubahnya kembali menjadi .xlsm. Perlu dicatat bahwa Anda dapat dengan aman menambah panjang file jika CMG...string baru lebih panjang dari aslinya.
Drew Chapin

173

Saya telah membangun atas jawaban fantastis Đức Thanh Nguyễn untuk memungkinkan metode ini bekerja dengan versi 64-bit Excel. Saya menjalankan Excel 2010 64-Bit pada 64-Bit Windows 7.

  1. Buka file yang berisi Proyek VBA Anda yang dikunci.
  2. Buat file xlsm baru dan simpan kode ini di 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. Tempel kode ini di Module2 dan jalankan

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

PENOLAKAN Ini bekerja untuk saya dan saya telah mendokumentasikannya di sini dengan harapan itu akan membantu seseorang. Saya belum sepenuhnya mengujinya . Pastikan untuk menyimpan semua file yang terbuka sebelum melanjutkan dengan opsi ini.


1
Saya tidak yakin mengapa tetapi ketika saya menjalankan ini di Excel untuk 365 MSP 64-bit excel crash, itu menutup file dan ketika saya me-restart, kata sandinya masih ada.
eborbath

Ini tidak dapat dilakukan di excel lagi karena opsi dalam menu konteks berwarna abu-abu sehingga Anda tidak dapat membuat modul.
thanos.a

170

Ada solusi lain (agak lebih mudah), tanpa masalah ukuran. Saya menggunakan pendekatan ini hari ini (pada file XLS 2003, menggunakan Excel 2007) dan berhasil.

  1. Cadangkan file xls
  2. Buka file dalam editor HEX dan temukan DPB=...bagian itu
  3. Ubah DPB=...string keDPx=...
  4. Buka file xls di Excel
  5. Buka editor VBA ( ALT+ F11)
  6. keajaiban: Excel menemukan kunci yang tidak valid (DPx) dan bertanya apakah Anda ingin melanjutkan memuat proyek (pada dasarnya mengabaikan perlindungan)
  7. Anda dapat menimpa kata sandi, jadi ubahlah menjadi sesuatu yang dapat Anda ingat
  8. Simpan file xls *
  9. Tutup dan buka kembali dokumen dan kerjakan sihir VBA Anda!

* CATATAN: Pastikan Anda telah mengubah kata sandi ke nilai baru, jika tidak saat berikutnya Anda membuka spreadsheet, Excel akan melaporkan kesalahan (Kesalahan Tidak Terduga), maka ketika Anda mengakses daftar modul VBA Anda sekarang akan melihat nama-nama modul sumber tetapi menerima kesalahan lain ketika mencoba membuka formulir / kode / dll. Untuk memperbaiki ini, kembali ke Properti Proyek VBA dan atur kata sandi ke nilai baru. Simpan dan buka kembali dokumen Excel dan Anda harus siap!


3
Sayangnya, ini tidak berfungsi untuk saya dengan Excel untuk Mac 2011 v14.2.5. Saya mendapat opsi untuk memperbaiki file, bukan untuk mengatur ulang kata sandi, dan efeknya kehilangan semua skrip VBA.
Joe Carroll

Solusi sempurna - Saya melakukan ini dengan file 2003 menggunakan HxD Hex Editor
Chris W

4
Saya baru saja mencobanya (.xls, Excel 2007) dan tidak berhasil. Hasilnya adalah: Modul terlihat, kode memang tampaknya berfungsi, tetapi ketika membuka modul, ia mengatakan kesalahan tak terduga (40230) .
KekuSemau

2
Kesalahan yang sama di sini (Excel 2010) - tetapi kemudian saya menyadari bahwa saya akan melewatkan 'setel kata sandi baru dan simpan / buka kembali' (langkah 7-9) dari Pieter.
Owen B

+1 Metode ini juga berfungsi pada file akses (.mdb) kami yang kurang berkembang! Sekarang kita bisa menjadikannya lebih baik, terima kasih untuk ini!
Er Gabriel Doronila

65

Colin Pickard memiliki jawaban yang sangat baik, tetapi ada satu 'hati-hati' dengan ini. Ada beberapa contoh (saya belum menemukan penyebabnya) di mana total panjang entri "CMG = ........ GC = ...." dalam file berbeda dari satu file excel ke file lanjut. Dalam beberapa kasus, entri ini akan menjadi 137 byte, dan dalam kasus lain akan menjadi 143 byte. Panjang 137 byte adalah yang aneh, dan jika ini terjadi ketika Anda membuat file Anda dengan kata sandi '1234', buat saja file lain, dan itu harus melompat ke panjang 143 byte.

Jika Anda mencoba menempelkan jumlah byte yang salah ke dalam file, Anda akan kehilangan proyek VBA Anda ketika Anda mencoba untuk membuka file dengan Excel.

EDIT

Ini tidak berlaku untuk file Excel 2007/2010. Format file .xlsx standar sebenarnya adalah file .zip yang berisi banyak sub-folder dengan pemformatan, tata letak, konten, dll., Disimpan sebagai data xml. Untuk file Excel 2007 yang tidak dilindungi, Anda bisa mengubah ekstensi .xlsx menjadi .zip, lalu buka file zip dan lihat semua data xml. Ini sangat mudah.

Namun, ketika kata sandi Anda melindungi file Excel 2007, seluruh file .zip (.xlsx) sebenarnya dienkripsi menggunakan enkripsi RSA. Ekstensi tidak dapat lagi diubah menjadi .zip dan ramban konten file.


Maka Anda perlu menggunakan alat hacking zip standar. Ini bukan lagi masalah "bagaimana saya mengembalikan file excel".
Jenis Anonim

3
@Anonim Type: Saya pikir alat cracking zip tidak akan membantu. Seperti yang saya mengerti Stewbob, itu bukan entri file dalam file zip yang dienkripsi, tetapi seluruh file zip itu sendiri, yang harus menyertakan header dan direktori pusat.
Treb

2
Hanya ingin tahu: bagaimana mungkin RSA ketika saya hanya memasukkan satu kata sandi (simetris)?
kizzx2

Bagaimana bila file yang ingin Anda masuki memiliki kunci yang lebih pendek? Terus buat vba docs sampai Anda mendapatkan yang memiliki 137?
onlynone

1
Apakah Anda yakin bahwa seluruh zipfile dienkripsi ketika Anda mengunci proyek VBA? Saya masih dapat membuka zipfile dan melihat struktur file .... Dan subfolder xl \ berisi file vbaProject.bin yang memiliki blok hashing "CMG = ... GC =".
Nigel Heffernan

63

Untuk jenis .xlsmatau .dotmfile Anda perlu melakukannya dengan cara yang sedikit berbeda.

  1. Ubah ekstensi .xlsmfile menjadi .zip.
  2. Buka file .zip (dengan WinZip atau WinRar dll) dan buka folder xl.
  3. Ekstrak vbaProject.binfile dan buka di Hex Editor (saya menggunakan HxD , benar-benar gratis dan ringan.)
  4. Cari DPBdan ganti dengan DPxdan simpan file.
  5. Ganti vbaProject.binfile lama dengan yang baru ini di file zip.
  6. Ubah kembali ekstensi file menjadi .xlsm.
  7. Buka buku kerja, lewati pesan peringatan.
  8. Buka Visual Basic di dalam Excel.
  9. Pergi ke Alat> Properti VBAProyek> Tab Perlindungan.
  10. Masukkan kata sandi baru dan simpan .xlsmfile.
  11. Tutup dan buka kembali dan kata sandi baru Anda akan berfungsi.

8
Bekerja di Excel 2016, Windows 10 64bit. (file xlsm)
LimaNightHawk

3
Bekerja di Word 2016, Windows 10 64bit (file
dotm

7
Solusi hebat, bekerja untuk saya di Excel 2013 64 bit. Anda dapat melewati perubahan ekstensi file .zipjika Anda telah menginstal 7-Zip . Dalam hal ini, Anda bisa mengklik kanan pada .xlsmfile dan memilih "7-Zip -> Open Archive"
nkatsar

bekerja dengan Word 2013, win7x64. (Ini sangat menyedihkan, begitu mudah ditipu untuk percaya bahwa kode ini agak aman).
Berry Tsakala

1
@ThierryMichel Kombinasi solusi sebelumnya dan coba-coba!
Matt

35

Perlu ditunjukkan bahwa jika Anda memiliki file Excel 2007 (xlsm), maka Anda dapat menyimpannya sebagai file Excel 2003 (xls) dan menggunakan metode yang diuraikan dalam jawaban lain.


4
itu tidak benar, saya sudah bekerja dengan file yang konversi ke xls / xla dari xlsm tidak mungkin, Excel 2007 dan 2010 macet setiap kali, saya sudah mencoba berbagai contoh, dari satu pesan erro - Kod wyjątku: c0000005 Przesunięcie wyjątku: 005d211d
Qbik

4
Ya kamu bisa melakukannya. Saya sudah melakukannya berkali-kali. Jika ada sesuatu pada lembar yang diperlukan dan apa yang tidak ditransfer ke versi yang lebih lama saya melakukan ini: 1.convert .xlsm ke .xls 2.memecahkan kode .xl 3.mengkonversi .xlsm ke .xlsx 4.Masukkan kode dari modul dalam .xls ke. xlsx dan simpan itu sebagai
.xlsm

Ia bekerja setelah mengkonversi xlsm ke xls seperti pada jawabannya.
Purus

32

Dengan giliran saya, ini dibangun di atas jawaban kaybee99 yang luar biasa yang dibangun di atas jawaban fantastis Thanc Thanh Nguyễn untuk memungkinkan metode ini bekerja dengan versi Office x86 dan amd64.

Gambaran umum tentang apa yang diubah, kami menghindari push / ret yang terbatas pada alamat 32bit dan menggantinya dengan mov / jmp reg.

Diuji dan bekerja

Word / Excel 2016 - versi 32 bit .
Word / Excel 2016 - versi 64 bit .

bagaimana itu bekerja

  1. Buka file yang berisi Proyek VBA Anda yang dikunci.
  2. Buat file baru dengan tipe yang sama seperti di atas dan simpan kode ini di 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. Tempel kode ini di Module2 dan jalankan

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

3
Sempurna! Bekerja dengan Windows Server 2016, Excel 2016 32 bit
Zin Min

Ini berfungsi pada file .xlsm di Excel Office 365. Terima kasih!
Ryan James

Masih berfungsi di 2019, versi terbaru Office 365 64bits dibuat, kawan!
XavierAM

Terima kasih untuk kode yang diperbarui, saya menghadapi crash menjalankan versi sebelumnya (64-bit), tetapi semua baik dengan versi Anda
emjaySX

Luar biasa ... Bekerja dengan Sempurna
Mahhdy

17

Sudahkah Anda mencoba membukanya di OpenOffice.org?

Saya memiliki masalah yang sama beberapa waktu lalu dan menemukan bahwa Excel dan Calc tidak memahami enkripsi masing-masing, sehingga memungkinkan akses langsung ke hampir semuanya.

Ini beberapa waktu yang lalu, jadi jika itu bukan hanya kebetulan pada bagian saya itu juga mungkin telah ditambal.


15

Jika blok Anda CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX" dalam file 'kata sandi yang dikenal' lebih pendek dari blok yang ada di file 'kata sandi tidak dikenal', pad string hex Anda dengan nol trailing untuk mencapai panjang yang benar.

misalnya

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

dalam file kata sandi yang tidak dikenal, harus diatur ke

CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" untuk mempertahankan panjang file.

Saya juga punya ini bekerja dengan file .XLA (format 97/2003) di kantor 2007.


1
Ini berfungsi, tetapi seperti yang baru-baru ini saya temukan (berkomentar di atas), Anda juga dapat menambahkan karakter nol setelah kutipan penutupan akhir di blok GC = "..." hingga Anda mencapai panjang yang sama.
tobriand

13

Untuk Excel 2007 dan seterusnya, Anda perlu mengubah ekstensi file Anda menjadi .zip. Di dalam arsip terdapat subfolder xl, di sana Anda akan menemukan vbaProject.bin. Ikuti langkah di atas dengan vbaProject.bin lalu simpan kembali di arsip. Ubah kembali ekstensi Anda dan voila! (artinya ikuti langkah-langkah di atas)


1
Saya dapat mengkonfirmasi ini berfungsi untuk file .xlam dengan Excel 2010 juga. +1!
Gimelist

12

Sandi Proyek VBA pada Access, Excel, Powerpoint, atau dokumen Word ( 2007, 2010, 2013 or 2016versi dengan ekstensi .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM) dapat dengan mudah dihapus .

Ini hanya masalah mengubah ekstensi nama file menjadi .ZIP, membuka ritsleting file, dan menggunakan Hex Editor dasar (seperti XVI32 ) untuk "memecah" kata sandi yang ada, yang "membingungkan" Kantor sehingga meminta kata sandi baru saat file berikutnya adalah dibuka.

Ringkasan langkah-langkahnya:

  • ganti nama file sehingga memiliki .ZIPekstensi.
  • buka ZIPdan buka XLfolder.
  • ekstrak vbaProject.bindan buka dengan Hex Editor
  • "Cari & Ganti" untuk "ganti semua" berubah DPBmenjadi DPX.
  • Simpan perubahan, tempatkan .binfile kembali ke zip, kembalikan ke ekstensi normal dan buka file seperti biasa.
  • ALT + F11 untuk masuk ke Editor VB dan klik kanan di Project Explorer untuk memilih VBA Project Properties.
  • Pada Protectiontab, Tetapkan kata sandi baru.
  • Klik OK, Tutup file, Buka kembali, tekan ALT + F11.
  • Masukkan kata sandi baru yang Anda atur.

Pada titik ini Anda dapat menghapus kata sandi sepenuhnya jika Anda mau.

Petunjuk lengkap dengan video selangkah demi selangkah yang saya buat "jalan saat" ada di YouTube di sini .

Agak mengejutkan bahwa solusi ini telah ada di sana selama bertahun-tahun, dan Microsoft belum memperbaiki masalah ini.


Moral dari cerita ini?

Kata sandi Proyek Microsoft Office VBA tidak dapat diandalkan untuk keamanan informasi sensitif apa pun . Jika keamanan penting, gunakan perangkat lunak enkripsi pihak ketiga.


9

Colin Pickard sebagian besar benar, tetapi jangan mengacaukan perlindungan "kata sandi untuk membuka" untuk seluruh file dengan perlindungan kata sandi VBA, yang sama sekali berbeda dari yang sebelumnya dan sama untuk Office 2003 dan 2007 (untuk Office 2007, ganti nama file ke .zip dan cari vbaProject.bin di dalam zip). Dan itu secara teknis cara yang benar untuk mengedit file adalah dengan menggunakan penampil dokumen gabungan OLE seperti CFX untuk membuka aliran yang benar. Tentu saja, jika Anda hanya mengganti byte, editor biner biasa dapat berfungsi.

BTW, jika Anda bertanya-tanya tentang format persis bidang ini, mereka mendokumentasikannya sekarang:

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


2
Tautan berikut memberikan detail untuk file format XSLM. gbanik.blogspot.co.uk/2010/08/... Solusinya sama dengan yang diuraikan oleh Yuhong Bao di atas, tetapi membuatnya menjadi bacaan yang menarik dan menyertakan tangkapan layar.
JohnLBevan

7

Jika file tersebut adalah file zip yang valid (beberapa byte pertama 50 4B- digunakan dalam format seperti .xlsm), maka unzip file tersebut dan cari subfile xl/vbaProject.bin. Ini adalah file CFB seperti halnya .xlsfile. Ikuti instruksi untuk format XLS (diterapkan ke subfile) dan kemudian hanya zip isinya.

Untuk format XLS, Anda dapat mengikuti beberapa metode lain dalam posting ini. Saya pribadi lebih suka mencari DPB=blok dan mengganti teks

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

dengan ruang kosong. Ini meniadakan masalah ukuran wadah CFB.


7

Saya mencoba beberapa solusi di atas dan tidak ada satupun yang berfungsi untuk saya (excel 2007 xlsm file). Lalu saya menemukan solusi lain yang bahkan mengambil kata sandi, bukan hanya memecahkannya.

Masukkan kode ini ke dalam modul, jalankan dan berikan waktu. Ini akan memulihkan kata sandi Anda dengan kekerasan.

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

1
Bagus! Saya pikir Anda punya satu downvote karena solusi Anda membuka lembar kerja daripada modul VBA. Namun demikian saya merasa sangat membantu - jadi terima kasih!
PBD10017

1
Saya memilikinya di Buku Kerja Pribadi saya. Penulis mengutip Bob McCormick sebagai penulis asli yang kemudian dimodifikasi oleh Norman Harker dan JE McGimpsey 2002.
Charles Byrne

5

ElcomSoft membuat produk Advanced Password Password Breaker dan Advanced Office Password Recovery yang mungkin berlaku untuk kasus ini, selama dokumen itu dibuat di Office 2007 atau sebelumnya.


4

Tom - Saya membuat kesalahan anak sekolah pada awalnya karena saya tidak melihat ukuran byte dan sebaliknya saya menyalin dan menempel dari "CMG" yang diatur ke entri berikutnya. Ini adalah dua ukuran teks yang berbeda antara kedua file, dan saya kehilangan proyek VBA seperti yang diperingatkan Stewbob.

Menggunakan HxD, ada penghitung pelacakan berapa banyak file yang Anda pilih. Salin mulai dari CMG hingga penghitung bertuliskan 8F (hex for 143) dan juga ketika menempelkan ke file yang terkunci - Saya berakhir dengan dua kali jumlah "..." di akhir pasta, yang entah bagaimana terlihat aneh dan terasa hampir tidak wajar, tetapi berhasil.

Saya tidak tahu apakah ini penting, tapi saya memastikan saya menutup hex editor dan unggul sebelum membuka kembali file di Excel. Saya kemudian harus pergi melalui menu untuk membuka VB Editor, ke dalam VBProject Properties dan memasukkan kata sandi 'baru' untuk membuka kunci kode.

Saya harap ini membantu.


4

Alat saya, VbaDiff , membaca VBA langsung dari file, sehingga Anda dapat menggunakannya untuk memulihkan kode VBA yang dilindungi dari sebagian besar dokumen kantor tanpa menggunakan hex editor.


Saya memiliki testes alat ini dan bekerja dengan sangat baik namun versi gratisnya mengambil 53 baris pertama. Untuk memulihkan file saya, saya harus mengikuti instruksi Andy untuk membuka kunci kata sandi. Kemudian saya membuka xlsm saya dengan VbaDiff di kedua panel dan kemudian saya mengklik lembar itu dengan kode saya. Saya mendapatkannya dengan copy-paste dan memasukkannya ke file excel saya yang sudah pulih tetapi kosong.
thanos.a

2

Perlindungan adalah perbandingan teks sederhana di Excel. Muatkan Excel di debugger favorit Anda ( Ollydbg menjadi alat pilihan saya), cari kode yang melakukan perbandingan dan perbaiki untuk selalu mengembalikan true, ini seharusnya memungkinkan Anda mengakses makro.


1

Untuk Excel 2016 64-bit pada mesin Windows 10, saya telah menggunakan hex editor untuk dapat mengubah kata sandi xla yang dilindungi (belum menguji ini untuk ekstensi lain). Kiat: buat cadangan sebelum Anda melakukan ini.

Langkah-langkah yang saya ambil:

  1. Buka vba di hex editor (misalnya XVI)
  2. Cari di DPB ini
  3. Ubah DPB ke yang lain, seperti DPX
  4. Simpan itu!
  5. Buka kembali .xla, pesan kesalahan akan muncul, lanjutkan saja.
  6. Anda sekarang dapat mengubah kata sandi .xla dengan membuka properti dan pergi ke tab kata sandi.

Saya harap ini membantu beberapa dari Anda!


Saya berhasil membuka .xls lama menggunakan ini pada Windows 10 di versi terbaru Excel 365, sementara sayangnya jawaban teratas tidak berfungsi lagi. Saya mengunduh HxD dan mengubah huruf terakhir seperti yang disarankan, dan melewatkan kesalahan. Semuanya baik sekarang, terima kasih!
Mahasiswa Starnes

0

ekstensi file excel Anda berubah menjadi xml. Dan buka di notepad. kata sandi teks ditemukan dalam file xml.

Anda melihat seperti di bawah garis;

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

(maaf untuk bahasa Inggris saya yang buruk)


Bisakah Anda menjelaskan bagaimana jawaban Anda lebih baik daripada jawaban yang sangat baik yang sudah disediakan?
Noel Widmer

solusi saya belum punya kode. jadi solusi yang sangat kompak selain.
Developer33

1
Solusi yang Anda berikan ini tidak berfungsi pada 2019.
Daniel L. VanDenBosch

Tidak berfungsi untuk saya baik di kantor 365
thanos.a

0

Jika Anda bekerja di dalam JavaAnda dapat mencoba VBAMacroExtractor. Setelah mengekstrak skrip VBA dari .xlsmsaya telah menemukan kata sandi di plaintext.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.