Excel VBA 프로젝트에서 암호를 해독하는 방법이 있습니까?


485

Excel 2003 매크로를 업데이트하라는 요청을 받았지만 VBA 프로젝트는 암호로 보호되어 있으며 문서가 부족한 것 같습니다. 아무도 암호를 모른다.

VBA 프로젝트에서 암호를 제거하거나 해독하는 방법이 있습니까?


링크의 예에서 알 수 있듯이 .xla 대신 .xls를 다른 이름으로 저장 할 수 있습니까? 이것이 차이가 있는지 확실하지 않습니다.
B Hart


20
@ Fandango68이 질문은 몇 년 전에 메타 에서 논의 되었습니다 . TLDR : SO에 관한 많은 질문은 나쁜 행위자에 의해 학대 될 수 있지만, 불법 행위의 명백한 증거가 없다면, 우리는 선의로 간주합니다. VBA 암호를 해독해야하는 합법적이고 윤리적 인 이유가 많이 있습니다. 또한 현재 시스템의 약점에 대한 논의는 궁극적으로 미래의 보안 향상에 기여하고 사람들이 안전하지 않은 시스템에 맹목적으로 의존하지 못하게합니다.
jmbpiano

답변:


699

VBAHEX 편집이 필요없는 이 직접 접근 방식을 시도 할 수 있습니다 . 모든 파일 (* .xls, * .xlsm, * .xlam ...)에서 작동합니다.

테스트 및 작동 :

Excel 2007
Excel 2010
Excel 2013-32 비트 버전
Excel 2016-32 비트 버전

64 비트 버전을 찾고 계십니까? 이 답변을 참조하십시오

작동 원리

나는 그것이 어떻게 작동하는지 설명하기 위해 최선을 다할 것입니다-영어 실례합니다.

  1. VBE는 시스템 기능을 호출하여 암호 대화 상자를 만듭니다.
  2. 사용자가 올바른 비밀번호를 입력하고 확인을 클릭하면이 함수는 1을 리턴합니다. 사용자가 잘못된 비밀번호를 입력하거나 취소를 클릭하면이 함수는 0을 리턴합니다.
  3. 대화 상자가 닫히면 VBE는 시스템 기능의 반환 값을 확인합니다
  4. 이 값이 1이면 VBE는 암호가 올바른 것으로 "생각"하므로 잠긴 VBA 프로젝트가 열립니다.
  5. 아래 코드는 암호 대화 상자를 표시하는 데 사용 된 원래 함수의 메모리를 호출시 항상 1을 반환하는 사용자 정의 함수로 교체합니다.

코드 사용

먼저 파일을 백업하십시오!

  1. 잠긴 VBA 프로젝트가 포함 된 파일을 엽니 다
  2. 새 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
  3. 이 코드를 Module1 의 위 코드 아래에 붙여 넣고 실행하십시오.

    Sub unprotected()
        If Hook Then
            MsgBox "VBA Project is unprotected!", vbInformation, "*****"
        End If
    End Sub
  4. VBA 프로젝트로 돌아와서 즐기십시오.


4
@Chris 당신은 절대적으로 맞습니다. Windows API 함수는이 코드에서 win 32에 대해 정의되어 있기 때문입니다.
Đức Thanh Nguyễn

8
이것이 어떻게 작동하는지에 대한 설명이 좋을 것입니다.
Dennis G

20
이제 남은 유일한 질문은 (이 인상적인 방법이 완벽하게 작동하는 것을 본 후) 어떻게 다른 사람들이이 핵을 사용하지 못하도록 VBA 프로젝트를 더 강력하게 보호 할 수 있는지입니다. :
EranG

6
이 코드는 VBA 코드를 잠금 해제하는 데 완벽하게 작동하지만 매번 다른 암호로 프로젝트를 다시 보호하지 못합니다. 다른 사람 이이 문제를 겪고 있습니까?
Matthew Bond

2
Excel 파일에서 VBA 프로젝트가 손상되어 모든 모듈 / 클래스를 내보내고 파일을 xlsx (매크로가 아닌)로 저장 한 다음 파일을 닫고 (멍청한 Excel) 다시 열어야했습니다. 클래스 파일에서 모듈을 가져오고 코드를 복사합니다. 이 시점에서 VBA 프로젝트에서 내 비밀번호를 사용하여 파일을 xlsm으로 저장할 수 있습니다.
BH

217

예, .xls형식 스프레드 시트 (2003 년까지 Excel의 기본값)를 사용하는 한 있습니다. Excel 2007 이후의 경우 기본값은 .xlsx매우 안전한 형식이며이 방법은 작동하지 않습니다.

Treb가 말했듯이 간단한 비교입니다. 한 가지 방법은 16 진 편집기를 사용하여 파일에서 비밀번호 항목을 간단히 바꾸는 것 입니다 (Windows 용 16 진 편집기 참조 ). 단계별 예 :

  1. 간단한 새 Excel 파일을 만듭니다.
  2. VBA 파트에서 간단한 비밀번호 (예 : 1234)를 설정하십시오.
  3. 파일을 저장하고 종료하십시오. 그런 다음 파일 크기를 확인하십시오 -Stewbob 's gotcha 참조
  4. 16 진 편집기로 방금 작성한 파일을여십시오.
  5. 다음 키로 시작하는 행을 복사하십시오.

    CMG=....
    DPB=...
    GC=...
  6. 첫 번째 백업 VBA 암호를 모르는 Excel 파일을 16 진수 편집기로 연 다음 더미 파일에서 위의 복사 된 행을 붙여 넣습니다.

  7. Excel 파일을 저장하고 종료하십시오.
  8. 이제 VBA 코드를 보려면 Excel 파일을여십시오. VBA 코드의 비밀번호는 1234입니다 (여기에서 보여주는 예와 같이).

Excel 2007 또는 2010으로 작업해야하는 경우 아래에 도움이 될만한 다른 답변이 있습니다. 1 , 2 , 3 .

2015 년 2 월 편집 : 매우 유망 해 보이는 또 다른 방법은 Đức Thanh Nguyễn의 새로운 답변 을 보십시오 .


CMG = ...로 시작하는 줄이 없으면 어떻게합니까?
systemovich

1
빈 Excel 파일 또는 잠긴 파일에서? 빈 파일의 파일 크기를 확인하십시오. 파일이 잠겨 있으면 백업이 안전한지 확인한 다음 다른 두 줄만 변경해보십시오. 파일이 암호화되어 있습니까?
Colin Pickard

6
Excel 2007 암호 보호 (및 파일 형식)는 Excel 2003과 근본적으로 다릅니다. 아래 답변에 이에 대한 몇 가지 세부 사항이 포함되어 있습니다. 제 생각에는 Excel 2007 파일의 암호로 보호되는 옵션은 Microsoft Office 기록에서 처음으로 합리적으로 안전한 파일을 생성 한 것입니다.
Stewbob

1
Excel 2016 새 파일에서 vba 비밀번호를 설정할 수 없습니다. 누군가 HEX를 공유하여 1234로 바꿀 수 있습니까? 아니면 기계에서 기계로 바꿀 수 있습니까?
Mescalito

1
이 방법은 .xlsm 파일에서 효과적이었습니다. 파일을 .xls로 저장 한 다음 다시 .xlsm으로 변환했습니다. 새 CMG...문자열이 원본보다 길면 파일 길이를 안전하게 늘릴 수 있습니다 .
Drew Chapin

173

이 방법을 64 비트 버전의 Excel에서 사용할 수 있도록 Đức Thanh Nguyễn의 환상적인 답변을 바탕으로 작성했습니다. 64 비트 Windows 7에서 Excel 2010 64 비트를 실행하고 있습니다.

  1. 잠긴 VBA 프로젝트가 포함 된 파일을 엽니 다.
  2. 새 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
  3. 이 코드를 Module2에 붙여 넣고 실행하십시오.

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

면책 조항 이것은 저에게 효과적 이며 누군가를 도울 수 있도록 여기에 문서화했습니다. 나는 그것을 완전히 테스트하지 않았습니다 . 이 옵션을 진행하기 전에 열려있는 모든 파일을 저장하십시오.


1
왜 그런지 잘 모르겠지만 365 MSP 64 비트 Excel 용 Excel에서 이것을 실행하면 파일이 닫히고 다시 시작할 때 암호가 여전히 있습니다.
eborbath

상황에 맞는 메뉴의 옵션이 회색으로 표시되어 모듈을 만들 수 없으므로 더 이상 Excel에서 수행 할 수 없습니다.
thanos.a

170

크기 문제없이 또 다른 (약간 쉬운) 솔루션이 있습니다. 나는 오늘 (2003 Excel 2007을 사용하여 2003 XLS 파일에서)이 접근법을 사용했으며 성공했습니다.

  1. xls 파일 백업
  2. HEX 편집기에서 파일을 열고 DPB=...부품을 찾습니다
  3. 변화 DPB=...에 문자열을DPx=...
  4. Excel에서 xls 파일을 엽니 다
  5. VBA 편집기를 엽니 다 ( ALT+ F11)
  6. 마술 : Excel은 유효하지 않은 키 (DPx)를 발견하고 프로젝트를 계속로드 할 것인지 묻습니다 (기본적으로 보호는 무시).
  7. 비밀번호를 덮어 쓸 수 있으므로 기억할 수있는 비밀번호로 변경하십시오.
  8. xls 파일 저장 *
  9. 문서를 닫았다가 다시 열고 VBA 매직을 사용하십시오!

* 참고 : 비밀번호를 새 값으로 변경했는지 확인하십시오. 그렇지 않으면 다음에 스프레드 시트를 열면 Excel에서 오류 (예기치 않은 오류)가보고 된 다음 VBA 모듈 목록에 액세스하면 이제 이름이 표시됩니다. 소스 모듈이지만 양식 / 코드 등을 열려고하면 다른 오류가 발생합니다. 이 문제를 해결하려면 VBA 프로젝트 속성으로 돌아가서 암호를 새 값으로 설정하십시오. 저장하고 Excel 문서를 다시 열면 잘 가야합니다!


3
불행히도 Mac 2011 v14.2.5 용 Excel에서는이 기능이 작동하지 않습니다. 암호를 재설정하지 않고 파일을 복구하는 옵션이 있었고 그 결과 모든 VBA 스크립트가 손실되었습니다.
Joe Carroll

완벽한 솔루션 - 나는 HxD 16 진수 편집기를 사용하여 2003 파일로 이런 짓을
크리스 W

4
방금 시도했지만 (.xls, Excel 2007) 작동하지 않았습니다. 결과 : 모듈이 표시되고 코드가 실제로 작동하는 것처럼 보이지만 모듈을 열면 예기치 않은 오류 (40230)가 표시 됩니다.
KekuSemau 2016 년

2
여기 동일한 오류 (Excel 2010)-그러나 Pieter에서 '새 비밀번호 설정 및 저장 / 다시 열기'(7-9 단계)를 건너 뛰었다는 것을 깨달았습니다.
Owen B

+1이 방법은 잘못 개발 된 액세스 (.mdb) 파일에서도 작동했습니다! 이제 우리는 그 점을 개선 할 수 있습니다. 감사합니다!
Er Gabriel Doronila

65

콜린 피커드 (Colin Pickard)는 훌륭한 해답을 가지고 있지만 이것에 대한 '감시'가 있습니다. 파일의 "CMG = ........ GC = ...."항목의 전체 길이가 Excel 파일마다 다르고 (아직 원인을 찾지 못했음) 인스턴스가 있습니다. 다음. 어떤 경우에는이 항목이 137 바이트이고 다른 경우에는 143 바이트입니다. 137 바이트 길이는 홀수이며, '1234'암호로 파일을 만들 때 이런 일이 발생하면 다른 파일을 만들면 143 바이트 길이로 이동합니다.

파일에 잘못된 수의 바이트를 붙여 넣으려고하면 Excel에서 파일을 열려고하면 VBA 프로젝트가 손실됩니다.

편집하다

Excel 2007/2010 파일에는 유효하지 않습니다. 표준 .xlsx 파일 형식은 실제로는 서식, 레이아웃, 내용 등이 XML 데이터로 저장된 수많은 하위 폴더가 포함 된 .zip 파일입니다. 보호되지 않은 Excel 2007 파일의 경우 .xlsx 확장자를 .zip으로 변경 한 다음 zip 파일을 열고 모든 xml 데이터를 살펴볼 수 있습니다. 매우 간단합니다.

그러나 Excel 2007 파일을 암호로 보호하면 전체 .zip (.xlsx) 파일이 실제로 RSA 암호화를 사용하여 암호화됩니다. 더 이상 확장자를 .zip으로 변경하고 파일 내용을 찾아 볼 수 없습니다.


그런 다음 표준 우편 해킹 도구를 사용해야합니다. 더 이상 "어떻게 Excel 파일을 백업합니까"문제가 아닙니다.
익명 유형

3
@Anonymous Type : 우편 크래킹 도구가 도움이되지 않는다고 생각합니다. Stewbob을 이해하는 것은 암호화 된 zip 파일의 파일 항목이 아니라 헤더와 중앙 디렉토리를 포함하는 전체 zip 파일 자체입니다.
Treb

2
궁금한 점은 하나의 암호 (대칭) 만 입력하면 어떻게 RSA가 될 수 있습니까?
kizzx2

들어 가고자하는 파일에 짧은 키가있는 경우는 어떻습니까? 137이있는 vba 문서를 만들 때까지 계속하십시오.
only

1
VBA 프로젝트를 잠글 때 전체 zip 파일이 암호화되어 있습니까? 여전히 zip 파일을 열고 파일 구조를 볼 수 있습니다 ... 하위 폴더 xl \에는 익숙한 "CMG = ... GC ="해싱 블록이있는 vbaProject.bin 파일이 포함되어 있습니다 .
Nigel Heffernan

63

A에 대한 .xlsm또는 .dotm파일 형식 당신은 그것을 약간 다른 방식으로 할 필요가있다.

  1. .xlsm파일 확장자를로 변경하십시오 .zip.
  2. .zip 파일 (WinZip 또는 WinRar 등)을 열고 xl 폴더로 이동하십시오.
  3. vbaProject.bin파일을 추출하고 16 진수 편집기에서 엽니 다 ( 완전히 무료이며 가벼운 HxD 사용 합니다.)
  4. 파일을 검색하여 DPB바꾸고 DPx파일을 저장하십시오.
  5. vbaProject.bin압축 파일에서 이전 파일을 새 파일로 바꿉니다 .
  6. 파일 확장자를 다시로 변경하십시오 .xlsm.
  7. 통합 문서 열기 경고 메시지를 건너 뜁니다.
  8. Excel에서 Visual Basic을 엽니 다.
  9. 도구> VBAProject 속성> 보호 탭으로 이동하십시오.
  10. 새 비밀번호를 입력하고 .xlsm파일을 저장 하십시오.
  11. 닫았다가 다시 열면 새 비밀번호가 작동합니다.

8
Excel 2016, Windows 10 64 비트에서 작동했습니다. (xlsm 파일)
LimaNightHawk

3
Word 2016, Windows 10 64 비트 (dotm 파일)에서 작업
NBajanca

7
훌륭한 솔루션, Excel 2013 64 비트에서 나를 위해 일했습니다. 7-Zip이 설치된 .zip경우 파일 확장자 변경을 건너 뛸 수 있습니다 . 이 경우 파일을 마우스 오른쪽 버튼으로 클릭 하고 "7-.xlsm
Zip-

Word 2013, win7x64와 호환됩니다. (코드가 다소 안전하다고 믿기 쉽도록 속임수는 매우 슬프다).
Berry Tsakala

1
@ThierryMichel 이전 솔루션과 시행 착오의 조합!
Matt

35

Excel 2007 (xlsm) 파일이있는 경우 해당 파일을 Excel 2003 (xls) 파일로 저장하고 다른 답변에 설명 된 방법을 사용할 수 있습니다.


4
사실이 아닙니다 .xlsm에서 xls / xla 로의 변환이 불가능한 파일로 작업했으며 Excel 2007 및 2010이 매번 중단되었으며 하나의 오류 메시지에서 다양한 인스턴스를 시도했습니다-Kod wyjątku : c0000005 Przesunięcie wyjątku : 005d211d
Qbik

4
그렇습니다 당신은 그것을 할 수 있습니다. 나는 여러 번 해냈다. : 필요하고 무엇을 이전 버전으로 전송되지 않습니다 나는이 할 시트에 뭔가가 있다면 1..XLS로 변환 .xlsm을 2..XLS의의 코드 균열 3.변환 .xlsm을 .XLSX하기 4.에 .XLS에서 모듈의 코드를 넣어은. xlsx로 저장하고 .xlsm으로 저장
ZygD

답변 에서처럼 xlsm을 xls로 변환 한 후에 작동합니다.
Purus

32

내 차례에 이것은 kaybee99의 탁월한 답변을 기반으로 하며이 방법은 x86 및 amd64 버전의 Office 모두에서 작동 할 수있는 Đức Thanh Nguyễn의 환상적인 답변을 기반으로합니다.

변경된 사항에 대한 개요, 우리는 32 비트 주소로 제한되는 푸시 / 레트를 피하고 mov / jmp reg로 대체합니다.

테스트 및 작동

Word / Excel 2016-32 비트 버전 .
Word / Excel 2016-64 비트 버전 .

작동 원리

  1. 잠긴 VBA 프로젝트가 포함 된 파일을 엽니 다.
  2. 위와 동일한 유형의 새 파일을 작성하고이 코드를 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. 이 코드를 Module2에 붙여 넣고 실행하십시오.

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

3
완전한! 32 비트 윈도우 서버 2016, 엑셀 2016과 협력
진 최소

이것은 Excel Office 365의 .xlsm 파일에서 작동했습니다. 감사합니다!
Ryan James

2019 년에도 여전히 작동하며 Office 365 64 비트 최신 빌드, 멋진 사람들!
XavierAM

업데이트 된 코드에 감사드립니다. 이전 버전 (64 비트)을 실행하면 충돌이 발생했지만 사용중인 버전에 적합합니다.
emjaySX

굉장 ... 완벽하게 일했다
마흐디

17

OpenOffice.org에서 간단히 열어 보셨습니까?

나는 얼마 전에 비슷한 문제가 있었고 Excel과 Calc가 서로의 암호화를 이해하지 못하여 거의 모든 것에 직접 액세스 할 수 있음을 발견했습니다.

이것은 얼마 전의 일이므로, 만약 그것이 내 부분의 우연이 아니라면 패치되었을 수도 있습니다.


15

당신의 블록의 경우 CMG="XXXX"\r\nDPB="XXXXX"\r\nGC="XXXXXX" 당신 '알려진 비밀'파일이 올바른 길이에 도달하기 위해 0을 후행과의 진수 문자열 '알 수없는 비밀'파일의 기존 블록, 패드보다 짧습니다.

예 :

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

알 수없는 비밀번호 파일에서

CMG="XXXX00"\r\nDPB="XXXXX000"\r\nGC="XXXXXX0000" 파일 길이를 유지합니다.

또한 office 2007에서 .XLA (97/2003 형식) 파일로 작업했습니다.


1
이것은 작동하지만 최근에 발견 한 것처럼 (위의 주석 처리) 동일한 길이에 도달 할 때까지 GC = "..."블록의 마지막 따옴표 뒤에 null 문자를 추가 할 수도 있습니다.
tobriand

13

Excel 2007 이후에는 파일 확장자를 .zip으로 변경해야합니다. 아카이브에는 하위 폴더 xl이 있으며 여기에는 vbaProject.bin이 있습니다. vbaProject.bin으로 위의 단계를 수행 한 후 다시 아카이브에 저장하십시오. 확장 기능을 다시 수정하십시오! (위의 단계를 따르십시오)


1
Excel 2010에서도 .xlam 파일에서 작동하는지 확인할 수 있습니다. +1!
Gimelist

12

Access, Excel, Powerpoint 또는 Word 문서 ( 2007, 2010, 2013 or 2016확장자가있는 버전 .ACCDB .XLSM .XLTM .DOCM .DOTM .POTM .PPSM)의 VBA 프로젝트 암호는 쉽게 제거 할 수 있습니다 .

파일 이름 확장명을로 변경하고 파일의 .ZIP압축을 풀고 기본 16 진수 편집기 (예 : XVI32 )를 사용하여 기존 암호를 "중단"하면 Office가 "혼동"되므로 다음에 파일을 다시 시작할 때 새 암호를 입력하라는 메시지가 표시됩니다. 열었다.

단계 요약 :

  • .ZIP확장자를 갖도록 파일 이름을 바꿉니다 .
  • 를 열고 폴더 ZIP로 이동하십시오 XL.
  • vbaProject.bin16 진 편집기로 추출 하여여십시오
  • "검색 및 바꾸기"가 "모두 바꾸기"로 변경 DPB되었습니다 DPX.
  • 변경 사항을 저장하고 .bin파일을 zip에 다시 넣은 다음 일반 확장명으로 되돌리고 일반 파일처럼 엽니 다.
  • Alt + F11을 눌러 VB 편집기를 시작하고 프로젝트 탐색기에서 마우스 오른쪽 버튼을 클릭하여을 선택합니다 VBA Project Properties.
  • Protection탭, 새 비밀번호를 설정합니다.
  • 을 클릭 OK하고 파일을 닫은 후 다시 열고 ALT + F11을 누르십시오.
  • 설정 한 새 비밀번호를 입력하십시오.

이 시점에서 원하는 경우 비밀번호를 완전히 제거 할 수 있습니다.

전체 지침 단계별 비디오는 내가 만든 "때 방법은 다시" 에있는 유튜브 여기 .

이 해결 방법이 수년 동안 존재 해 왔으며 Microsoft가이 문제를 해결하지 않은 것은 충격적입니다.


이 이야기의 교훈?

마이크로 소프트 오피스 VBA 프로젝트 암호가 있습니다 에 의존 할 수 없습니다 의 보안을 위해 모든 민감한 정보 . 보안이 중요한 경우 타사 암호화 소프트웨어를 사용하십시오.


9

Colin Pickard는 대부분 정확하지만 전체 파일에 대한 "열기 암호"보호와 VBA 암호 보호를 혼동하지 마십시오. VBA 암호 보호는 전자와 완전히 다르며 Office 2003 및 2007과 동일합니다 (Office 2007의 경우 이름 바꾸기). .zip 파일을 찾고 zip 내부의 vbaProject.bin을 찾으십시오. 기술적으로 파일을 편집하는 올바른 방법은 CFX와 같은 OLE 복합 문서 뷰어를 사용하여 올바른 스트림을 여는 것입니다. 물론 바이트를 바꾸는 경우 일반 이진 편집기가 작동 할 수 있습니다.

BTW, 이러한 필드의 정확한 형식에 대해 궁금한 경우 지금 문서화되어 있습니다.

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


2
다음 링크는 XSLM 형식 파일에 대한 세부 사항을 제공합니다. gbanik.blogspot.co.uk/2010/08/… 이 솔루션은 위의 Yuhong Bao에서 설명한 것과 동일하지만 재미있는 독서와 스크린 샷을 포함합니다.
JohnLBevan

7

파일이 유효한 zip 파일 인 경우 (처음 몇 바이트는 50 4B형식과 같은 형식으로 사용됨 .xlsm) 파일의 압축을 풀고 서브 파일을 찾으십시오 xl/vbaProject.bin. 이것은 파일과 같은 CFB .xls파일입니다. 서브 파일에 적용되는 XLS 형식의 지시 사항을 따른 후 내용을 압축하십시오.

XLS 형식의 경우이 게시물의 다른 방법 중 일부를 따를 수 있습니다. 개인적으로 DPB=블록을 검색 하고 텍스트를 바꾸는 것을 선호 합니다.

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

빈 공간으로. 이것은 CFB 컨테이너 크기 문제를 방지합니다.


7

위의 솔루션 중 일부를 시도했지만 그중 어느 것도 나를 위해 작동하지 않습니다 (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

1
좋은! 솔루션이 VBA 모듈이 아닌 워크 시트의 잠금을 해제하기 때문에 하나의 하향 투표가 있다고 생각합니다. 그럼에도 불구하고 나는 그것이 도움이된다는 것을 알았습니다.
PBD10017

1
나는 이것을 내 개인 통합 문서로 가지고 있습니다. 원래 저자 이후 2002 년 노먼 하커와 JE McGimpsey에 의해 수정 된 저자는 밥 맥코믹을 인용
찰스 번

5

ElcomSoft 는 문서가 Office 2007 또는 그 이전 버전에서 작성된 경우이 사례에 적용될 수있는 Advanced Office Password BreakerAdvanced Office Password Recovery 제품을 만듭니다.


4

Tom-바이트 크기를 보지 않고 처음에는 남학생 오류가 발생했으며 대신 "CMG"설정에서 후속 항목으로 복사하여 붙여 넣었습니다. 이것은 두 파일 사이의 두 가지 다른 텍스트 크기였으며 Stewbob이 경고 한 것처럼 VBA 프로젝트를 잃었습니다.

HxD를 사용하면 선택한 파일의 양을 추적하는 카운터가 있습니다. 카운터가 8F (16 진수 16 진수)를 읽을 때까지 복사 한 파일을 붙여 넣을 때 CMG에서 복사-붙여 넣기가 끝날 때 "..."의 두 배로 끝났습니다. 어쨌든 이상하게 보였고 거의 느꼈습니다. 부자연 스럽지만 효과가있었습니다.

중요한지 모르겠지만 Excel에서 파일을 다시 열기 전에 16 진 편집기와 Excel을 모두 종료했는지 확인했습니다. 그런 다음 메뉴를 통해 VB 편집기를 열고 VBProject 속성으로 이동 한 다음 '새'비밀번호를 입력하여 코드 잠금을 해제해야했습니다.

이게 도움이 되길 바란다.


4

내 도구 VbaDiff 는 파일에서 직접 VBA를 읽으므로 16 진 편집기를 사용하지 않고도 대부분의 사무실 문서에서 보호 된 VBA 코드를 복구하는 데 사용할 수 있습니다.


나는이 도구를 테스트하고 실제로 잘 작동하지만 무료 버전은 처음 53 줄을 검색합니다. 내 파일을 복구하려면 암호를 잠금 해제하기 위해 Andy의 지시를 따라야했습니다. 그런 다음 두 창에서 VbaDiff로 xlsm을 연 다음 코드가있는 시트를 클릭했습니다. 복사하여 붙여 넣기하여 복구되었지만 vba-empty Excel 파일에 넣습니다.
thanos.a

2

보호는 Excel에서 간단한 텍스트 비교입니다. 좋아하는 디버거에 Excel을로드하고 ( Olydbg 가 선택한 도구 임) 비교를 수행하는 코드를 찾아서 항상 true를 반환하도록 수정하면 매크로에 액세스 할 수 있습니다.


1

Windows 10 컴퓨터의 Excel 2016 64 비트의 경우 16 진수 편집기를 사용하여 보호 된 xla의 암호를 변경할 수 있습니다 (다른 확장 프로그램에서는 테스트하지 않았습니다). 팁: 이 작업을 수행하기 전에 백업을 만드십시오.

내가 취한 단계 :

  1. 16 진수 편집기에서 VBA를 엽니 다 (예 : XVI).
  2. 이 DPB에서 검색
  3. DPB를 DPX와 같은 다른 것으로 변경
  4. 저장해!
  5. .xla를 다시 열면 오류 메시지가 나타납니다. 계속하십시오.
  6. 이제 등록 정보를 열고 비밀번호 탭으로 이동하여 .xla의 비밀번호를 변경할 수 있습니다.

이것이 여러분의 도움이 되었기를 바랍니다!


최신 버전의 Excel 365에서 Windows 10에서이를 사용하여 이전 .xls를 성공적으로 여는 동안 가장 좋은 대답은 더 이상 작동하지 않습니다. HxD를 다운로드하고 마지막 글자를 권장대로 변경하고 오류를 건너 뛰었습니다. 감사합니다!
Starnes 학생

0

Excel 파일의 확장자가 xml로 변경되었습니다. 메모장에서여십시오. xml 파일에서 비밀번호 텍스트를 찾습니다.

아래 줄처럼 보입니다.

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

(내 하찮은 영어 실력에 죄송하다는 말씀을 드리고 싶습니다)


이미 제공된 훌륭한 답변보다 답변이 더 나은 방법을 설명 할 수 있습니까?
Noel Widmer

내 솔루션에는 코드가 없습니다. 이외의 매우 컴팩트 한 솔루션.
개발자

1
제공
한이

Office 365
thanos.a

0

당신이 일하는 경우 Java시도 할 수 있습니다 VBAMacroExtractor. VBA 스크립트를 추출한 후 .xlsm일반 텍스트의 비밀번호를 찾았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.