CAFE

♣ EXCEL실무활용

[Excel VBA(엑셀 매크로) 암호 제거하는 방법

작성자EYEDI|작성시간18.06.23|조회수7,335 목록 댓글 0

http://cafe.daum.net/MHjudge/DnoB/6?q=%EC%97%91%EC%85%80%20%EB%A7%A4%ED%81%AC%EB%A1%9C%20%EC%95%94%ED%98%B8


출처 : http://ddart.net/xe/board/5187

 

 

1. 암호가 걸린 VBA(.xlsm) 엑셀매크로 파일을 연다.

2. 연 상태에서 바로 새로운 엑셀파일을 열어준다.

3. Alt+F11을 눌러 VBA를 실행하여, 새롭게 만든 프로젝트에서 아래 그림과 같이 새로운 프로젝트에서

마우스 오른쪽 버튼을 눌러 삽입->모듈을 클릭하여, 모듈을 생성한다.



 

4. 생성한 모듈에 다음의 소스코드를 입력한다.




Module1의 소스코드내용


32비트 버전용

Option Explicit
 
Private Const PAGE_EXECUTE_READWRITE = &H40
 
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
        (Destination As Long, Source As LongByVal Length As Long)
 
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, _
        ByVal dwSize As LongByVal flNewProtect As Long, lpflOldProtect As LongAs Long
 
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As StringAs Long
 
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
        ByVal lpProcName As StringAs Long
 
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, _
        ByVal pTemplateName As LongByVal hWndParent As Long, _
        ByVal lpDialogFunc As LongByVal dwInitParam As LongAs 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 LongAs 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 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 LongByVal hWndParent As Long, _
        ByVal lpDialogFunc As LongByVal dwInitParam As LongAs Integer
    If pTemplateName = 4070 Then
        MyDialogBoxParam = 1
    Else
        RecoverBytes
        MyDialogBoxParam = DialogBoxParam(hInstance, pTemplateName, _
                           hWndParent, lpDialogFunc, dwInitParam)
        Hook
    End If
End Function


64비트 버전용

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


5. 위의 모듈 추가 방법과 같이 Module2도 생성하여, 다음과 같이 소스코드를 입력한다.

 

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


6. 입력 후에, F5번 키를 눌러 다음과 같은 창이 뜨면, unprotected를 실행하고 나서, 원본프로젝트의 VBA 프로젝트를 열면, 암호를 묻지 않는다.




[출처] [Excel]VBA(엑셀 매크로) 암호 제거하는 방법|작성자 browniz1004


오피스 2007 엑셀에서는 암호가 걸려있는 매크로 통합문서는 실행이 안되도록 되어있습니다.

 

(암호가 걸려있으면 매크로 문서의 바이러스/악성코드 검사를 하지 못하기 때문에 암호걸린 매크로 통합문서의 매크로 실행을 금지한다고 하던가... -_-;)

 

그런데 레지스트리 값을 편집하면 가능합니다.

(HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Security\ExcelBypassEncryptedMacroScan 의

Dword 값을 1 로 세팅해 주면 암호걸린 매크로 통합문서도 실행가능)

 

주의할 점!

이걸 항상 1 값으로 세팅해 두면 악성코드 또는 바이러스 가 들어있는 암호걸린 매크로 파일이 언제라도 실행될 수 있으므로

각별한 주의가 요구됩니다.

 

해결할 수 있는 편법

신뢰할 수 있는 '암호걸린 매크로 통합문서'를 실행하기 전에

1. HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Security 내에

   ExcelBypassEncryptedMacroScan 을 만들어 값을 1 로 세팅해주고

2. xlsm 파일을 실행하고

3. 다시 레지스트리 값을 0으로 세팅 / ExcelBypassEncryptedMacroScan 를 아예 삭제한다

 

근디.. 너무 번거롭다. -_-;

 

그래서 간단한 프로그램을 하나 만들었습니다.

기능은 위에서 설명한 편법을 통해 xlsm을 실행해 주는 놈입니다.

 

한가지 주의할 점은 '신뢰할 수 있는 xlsm' 만을 실행하여야 한다는 점이지요.

출처를 알 수 없는 xlsm파일을 실행하여 발생하는 문제는 전적으로 본인 책임입니다.


다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼