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

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

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



답변

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 프로젝트로 돌아와서 즐기십시오.


답변

예, .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의 새로운 답변 을 보십시오 .


답변

이 방법을 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

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


답변

크기 문제없이 또 다른 (약간 쉬운) 솔루션이 있습니다. 나는 오늘 (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 문서를 다시 열면 잘 가야합니다!


답변

콜린 피커드 (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으로 변경하고 파일 내용을 찾아 볼 수 없습니다.


답변

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. 닫았다가 다시 열면 새 비밀번호가 작동합니다.

답변

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