/* // File: // vb.idc (for Visual Basic 5/6) // // Created by: // Reginald Wong (reginaldw[at]trendmicro[dot]com[dot]ph) // // Purpose: // This is my first idc that will // show the vb header in some detail // points out execute points of events from modules, forms, objects... // // Usage: // Run IDC script after initial autoanalysis. // // References: // DISASSEMBLING VISUAL BASIC APPLICATIONS by Sanchit Karve // Virus Bulletin January 2002 // Virus Bulletin June 2002 // Visual Basic Image Internal Structure Format by Alex Ionescu // VISUAL BASIC REVERSED - A decompiling approach by AndreaGeddon // // Notes: // This script still needs to be enhanced and I'll still continue updating. // Still buggy. // Mabuhay Pilipinas!!! // */ #include static SetNameComm(ea,varname,comment){ MakeName(ea,varname); MakeComm(ea,comment); } static FixByte(ea,varname,comment){ MakeByte(ea); SetNameComm(ea,varname,comment); } static FixWord(ea,varname,comment){ MakeWord(ea); SetNameComm(ea,varname,comment); } static FixDword(ea,varname,comment){ MakeDword(ea); SetNameComm(ea,varname,comment); } static FixUUID(ea,varname,comment){ MakeArray(ea,0x10); SetNameComm(ea,varname,comment); } static FixStr(ea,eea,varname,comment){ MakeStr(ea,eea); SetNameComm(ea,varname,comment); } static ClearUnknown(ea,size){ auto clearcounter; MakeUnknown(ea,size,0x02); for(clearcounter=0;clearcounter 32"); FixDword (ea + 0x3C, "dwThreadFlags" + "_" + catstring, "Threading Mode"); FixDword (ea + 0x40, "dwThreadCount" + "_" + catstring, "Threads to support in pool"); FixWord (ea + 0x44, "wFormCount" + "_" + catstring, "Number of forms present"); FixWord (ea + 0x46, "wExternalCount" + "_" + catstring, "Number of external controls"); FixDword (ea + 0x48, "dwThunkCount" + "_" + catstring, "Number of thunks to create"); FixDword (ea + 0x4C, "lpGuiTable" + "_" + catstring, "Pointer to GUI Table"); FixDword (ea + 0x50, "lpExternalTable" + "_" + catstring, "Pointer to External Table"); FixDword (ea + 0x54, "lpComRegisterData" + "_" + catstring, "Pointer to COM Information"); FixDword (ea + 0x58, "bSZProjectDescription" + "_" + catstring, "Offset to Project Description"); FixDword (ea + 0x5C, "bSZProjectExeName" + "_" + catstring, "Offset to Project EXE Name"); FixDword (ea + 0x60, "bSZProjectHelpFile" + "_" + catstring, "Offset to Project Help File"); FixDword (ea + 0x64, "bSZProjectName" + "_" + catstring, "Offset to Project Name"); if(Dword(ea+0x2c) != 0){ AddEntryPoint(Dword(ea+0x2c),Dword(ea+0x2c),"Sub_Main",1); } } static FixCOMRegistrationData(ea,catstring){ ClearUnknown(ea,0x30); FixDword (ea + 0x00, "bRegInfo" + "_" + catstring, "Offset to COM Interfaces Info"); FixDword (ea + 0x04, "bSZProjectName" + "_" + catstring, "Offset to Project/Typelib Name"); FixDword (ea + 0x08, "bSZHelpDirectory" + "_" + catstring, "Offset to Help Directory"); FixDword (ea + 0x0C, "bSZProjectDescription" + "_" + catstring, "Offset to Project Description"); FixUUID (ea + 0x10, "uuidProjectClsId" + "_" + catstring, "CLSID of Project/Typelib"); FixDword (ea + 0x20, "dwTlbLcid" + "_" + catstring, "LCID of Type Library"); FixWord (ea + 0x24, "wUnknown" + "_" + catstring, "Might be something. Must check"); FixWord (ea + 0x26, "wTlbVerMajor" + "_" + catstring, "Typelib Major Version"); FixWord (ea + 0x28, "wTlbVerMinor" + "_" + catstring, "Typelib Minor Version"); } static FixCOMRegistrationInfo(ea,catstring){ ClearUnknown(ea,0x44); FixDword (ea + 0x00, "bNextObject" + "_" + catstring, "Offset to COM Interfaces Info"); FixDword (ea + 0x04, "bObjectName" + "_" + catstring, "Offset to Object Name"); FixDword (ea + 0x08, "bObjectDescription" + "_" + catstring, "Offset to Object Description"); FixDword (ea + 0x0C, "dwInstancing" + "_" + catstring, "Instancing Mode"); FixDword (ea + 0x10, "dwObjectId" + "_" + catstring, "Current Object ID in the Project"); FixUUID (ea + 0x14, "uuidObject" + "_" + catstring, "CLSID of Object"); FixDword (ea + 0x24, "fIsInterface" + "_" + catstring, "Specifies if the next CLSID is valid"); FixDword (ea + 0x28, "bUuidObjectIFace" + "_" + catstring, "Offset to CLSID of Object Interface"); FixDword (ea + 0x2C, "bUuidEventsIFace" + "_" + catstring, "Offset to CLSID of Events Interface"); FixDword (ea + 0x30, "fHasEvents" + "_" + catstring, "Specifies if the CLSID above is valid"); FixDword (ea + 0x34, "dwMiscStatus" + "_" + catstring, "OLEMISC Flags (see MSDN docs)"); FixByte (ea + 0x38, "fClassType" + "_" + catstring, "Class Type"); FixByte (ea + 0x39, "fObjectType" + "_" + catstring, "Flag identifying the Object Type"); FixWord (ea + 0x3A, "wToolboxBitmap32" + "_" + catstring, "Control Bitmap ID in Toolbox"); FixWord (ea + 0x3C, "wDefaultIcon" + "_" + catstring, "Minimized Icon of Control Window"); FixWord (ea + 0x3E, "fIsDesigner" + "_" + catstring, "Specifies whether this is a Designer"); FixDword (ea + 0x40, "bDesignerData" + "_" + catstring, "Offset to Designer Data"); } static FixDesignerInfo(ea,catstring){ ClearUnknown (ea,Dword(ea+0x10)+0x14); FixUUID (ea + 0x00, "uuidDesigner" + "_" + catstring, "CLSID of the Addin/Designer"); FixDword (ea + 0x10, "cbStructSize" + "_" + catstring, "Total Size of the next fields."); ea = ea + 0x18; MakeDword (ea - 0x04); FixStr (ea, ea + Dword(ea - 0x04), "bstrAddinRegKey" + "_" + catstring, "Registry Key of the Addin"); ea = ea + 0x04 + Dword(ea - 0x04); MakeDword (ea - 0x04); FixStr (ea, ea + Dword(ea - 0x04), "bstrAddinName" + "_" + catstring, "Friendly Name of the Addin"); ea = ea + 0x04 + Dword(ea - 0x04); MakeDword (ea - 0x04); FixStr (ea, ea + Dword(ea - 0x04), "bstrAddinDescription" + "_" + catstring, "Description of Addin"); ea = ea + Dword(ea - 0x04); FixDword (ea, "dwLoadBehaviour" + "_" + catstring, "CLSID of Object"); ea = ea + 0x08; MakeDword (ea - 0x04); FixStr (ea, ea + Dword(ea - 0x04), "bstrSatelliteDll" + "_" + catstring, "Satellite DLL, if specified"); ea = ea + 0x04 + Dword(ea - 0x04); MakeDword (ea - 0x04); FixStr (ea, ea + Dword(ea - 0x04), "bstrAdditionalRegKey" + "_" + catstring, "Extra Registry Key, if specified"); ea = ea + Dword(ea - 0x04); FixDword (ea, "dwCommandLineSafe" + "_" + catstring, "Specifies a GUI-less Addin if 1."); } static FixProjectInformation(ea,catstring){ ClearUnknown(ea,0x23c); FixDword (ea + 0x00, "dwVersion" + "_" + catstring, "5.00 in Hex (0x1F4). Version."); FixDword (ea + 0x04, "lpObjectTable" + "_" + catstring, "Pointer to the Object Table"); FixDword (ea + 0x08, "dwNull" + "_" + catstring, "Unused value after compilation."); FixDword (ea + 0x0C, "lpCodeStart" + "_" + catstring, "Points to start of code. Unused."); FixDword (ea + 0x10, "lpCodeEnd" + "_" + catstring, "Points to end of code. Unused."); FixDword (ea + 0x14, "dwDataSize" + "_" + catstring, "Size of VB Object Structures. Unused."); FixDword (ea + 0x18, "lpThreadSpace" + "_" + catstring, "Pointer to Pointer to Thread Object."); FixDword (ea + 0x1C, "lpVbaSeh" + "_" + catstring, "Pointer to VBA Exception Handler"); FixDword (ea + 0x20, "lpNativeCode" + "_" + catstring, "Pointer to .DATA section."); FixStr (ea + 0x24, ea + 0x234, "szPathInformation" + "_" + catstring, "Contains Path and ID string. < SP6"); FixDword (ea + 0x234, "lpExternalTable" + "_" + catstring, "Pointer to External Table."); FixDword (ea + 0x238, "dwExternalCount" + "_" + catstring, "Objects in the External Table."); } static FixSecondaryProjectInformation(ea,catstring){ ClearUnknown(ea,0x28); FixDword (ea + 0x00, "lpHeapLink" + "_" + catstring, "Unused after compilation, always 0."); FixDword (ea + 0x04, "lpObjectTable" + "_" + catstring, "Back-Pointer to the Object Table."); FixDword (ea + 0x08, "dwReserved" + "_" + catstring, "Always set to -1 after compiling. Unused"); FixDword (ea + 0x0C, "dwUnused" + "_" + catstring, "Not written or read in any case."); FixDword (ea + 0x10, "lpObjectList" + "_" + catstring, "Pointer to Object Descriptor Pointers."); FixDword (ea + 0x14, "dwUnused2" + "_" + catstring, "Not written or read in any case."); FixDword (ea + 0x18, "szProjectDescription" + "_" + catstring, "Pointer to Project Description"); FixDword (ea + 0x1C, "szProjectHelpFile" + "_" + catstring, "Pointer to Project Help File"); FixDword (ea + 0x20, "dwReserved2" + "_" + catstring, "Always set to -1 after compiling. Unused"); FixDword (ea + 0x24, "dwHelpContextId" + "_" + catstring, "Help Context ID set in Project Settings."); } static FixObjectTable(ea,catstring){ ClearUnknown(ea,0x54); FixDword (ea + 0x00, "lpHeapLink" + "_" + catstring, "Unused after compilation, always 0."); FixDword (ea + 0x04, "lpExecProj" + "_" + catstring, "Pointer to VB Project Exec COM Object."); FixDword (ea + 0x08, "lpProjectInfo2" + "_" + catstring, "Secondary Project Information."); FixDword (ea + 0x0C, "dwReserved" + "_" + catstring, "Always set to -1 after compiling. Unused"); FixDword (ea + 0x10, "dwNull" + "_" + catstring, "Not used in compiled mode."); FixDword (ea + 0x14, "lpProjectObject" + "_" + catstring, "Pointer to in-memory Project Data."); FixUUID (ea + 0x18, "uuidObject" + "_" + catstring, "GUID of the Object Table."); FixWord (ea + 0x28, "fCompileState" + "_" + catstring, "Internal flag used during compilation."); FixWord (ea + 0x2A, "dwTotalObjects" + "_" + catstring, "Total objects present in Project."); FixWord (ea + 0x2C, "dwCompiledObjects" + "_" + catstring, "Equal to above after compiling."); FixWord (ea + 0x2E, "dwObjectsInUse" + "_" + catstring, "Usually equal to above after compile."); FixDword (ea + 0x30, "lpObjectArray" + "_" + catstring, "Pointer to Object Descriptors"); FixDword (ea + 0x34, "fIdeFlag" + "_" + catstring, "Flag/Pointer used in IDE only."); FixDword (ea + 0x38, "lpIdeData" + "_" + catstring, "Flag/Pointer used in IDE only."); FixDword (ea + 0x3C, "lpIdeData2" + "_" + catstring, "Flag/Pointer used in IDE only."); FixDword (ea + 0x40, "lpszProjectName" + "_" + catstring, "Pointer to Project Name."); FixDword (ea + 0x44, "dwLcid" + "_" + catstring, "LCID of Project."); FixDword (ea + 0x48, "dwLcid2" + "_" + catstring, "Alternate LCID of Project."); FixDword (ea + 0x4C, "lpIdeData3" + "_" + catstring, "Flag/Pointer used in IDE only."); FixDword (ea + 0x50, "dwIdentifier" + "_" + catstring, "Template Version of Structure."); } static FixPrivateObjectDescriptor(ea,catstring){ ClearUnknown(ea,0x40); FixDword (ea + 0x00, "lpHeapLink" + "_" + catstring, "Unused after compilation, always 0."); FixDword (ea + 0x04, "lpObjectInfo" + "_" + catstring, "Pointer to the Object Info for this Object."); FixDword (ea + 0x08, "dwReserved" + "_" + catstring, "Always set to -1 after compiling."); FixDword (ea + 0x0C, "dwIdeData" + "_" + catstring, "[3] Not valid after compilation."); MakeDword (ea + 0x10); MakeDword (ea + 0x14); FixDword (ea + 0x18, "lpObjectList" + "_" + catstring, "Points to the Parent Structure (Array)"); FixDword (ea + 0x1C, "dwIdeData2" + "_" + catstring, "Not valid after compilation."); FixDword (ea + 0x20, "lpObjectList2" + "_" + catstring, "[3] Points to the Parent Structure (Array)."); MakeDword (ea + 0x24); MakeDword (ea + 0x28); FixDword (ea + 0x2C, "dwIdeData3" + "_" + catstring, "[3] Not valid after compilation."); MakeDword (ea + 0x30); MakeDword (ea + 0x34); FixDword (ea + 0x38, "dwObjectType" + "_" + catstring, "Type of the Object described."); FixDword (ea + 0x3C, "dwIdentifier" + "_" + catstring, "Template Version of Structure."); } static FixPublicObjectDescriptor(ea,catstring){ ClearUnknown(ea,0x30); FixDword (ea + 0x00, "lpObjectInfo" + "_" + catstring, "Pointer to the Object Info for this Object."); FixDword (ea + 0x04, "dwReserved" + "_" + catstring, "Always set to -1 after compiling."); FixDword (ea + 0x08, "lpPublicBytes" + "_" + catstring, "Pointer to Public Variable Size integers."); FixDword (ea + 0x0C, "lpStaticBytes" + "_" + catstring, "Pointer to Static Variable Size integers."); FixDword (ea + 0x10, "lpModulePublic" + "_" + catstring, "Pointer to Public Variables in DATA section"); FixDword (ea + 0x14, "lpModuleStatic" + "_" + catstring, "Pointer to Static Variables in DATA section"); FixDword (ea + 0x18, "lpszObjectName" + "_" + catstring, "Name of the Object."); FixDword (ea + 0x1C, "dwMethodCount" + "_" + catstring, "Number of Methods in Object."); FixDword (ea + 0x20, "lpMethodNames" + "_" + catstring, "If present, pointer to Method names array."); FixDword (ea + 0x24, "bStaticVars" + "_" + catstring, "Offset to where to copy Static Variables."); FixDword (ea + 0x28, "fObjectType" + "_" + catstring, "Flags defining the Object Type."); FixDword (ea + 0x2C, "dwNull" + "_" + catstring, "Not valid after compilation."); } static FixObjectInformation(ea,catstring){ ClearUnknown(ea,0x38); FixWord (ea + 0x00, "wRefCount" + "_" + catstring, "Always 1 after compilation."); FixWord (ea + 0x02, "wObjectIndex" + "_" + catstring, "Index of this Object."); FixDword (ea + 0x04, "lpObjectTable" + "_" + catstring, "Pointer to the Object Table"); FixDword (ea + 0x08, "lpIdeData" + "_" + catstring, "Zero after compilation. Used in IDE only."); FixDword (ea + 0x0C, "lpPrivateObject" + "_" + catstring, "Pointer to Private Object Descriptor."); FixDword (ea + 0x10, "dwReserved" + "_" + catstring, "Always -1 after compilation."); FixDword (ea + 0x14, "dwNull" + "_" + catstring, "Unused."); FixDword (ea + 0x18, "lpObject" + "_" + catstring, "Back-Pointer to Public Object Descriptor."); FixDword (ea + 0x1C, "lpProjectData" + "_" + catstring, "Pointer to in-memory Project Object."); FixWord (ea + 0x20, "wMethodCount" + "_" + catstring, "Number of Methods"); FixWord (ea + 0x22, "wMethodCount2" + "_" + catstring, "Zeroed out after compilation. IDE only."); FixDword (ea + 0x24, "lpMethods" + "_" + catstring, "Pointer to Array of Methods."); FixWord (ea + 0x28, "wConstants" + "_" + catstring, "Number of Constants in Constant Pool."); FixWord (ea + 0x2A, "wMaxConstants" + "_" + catstring, "Constants to allocate in Constant Pool."); FixDword (ea + 0x2C, "lpIdeData2" + "_" + catstring, "Valid in IDE only."); FixDword (ea + 0x30, "lpIdeData3" + "_" + catstring, "Valid in IDE only."); FixDword (ea + 0x34, "lpConstants" + "_" + catstring, "Pointer to Constants Pool."); if(Dword(ea+0x34) != (ea+0x38)){ FixOptionalObjectInformation(ea+0x38,"O"+catstring); } } static FixOptionalObjectInformation(ea,catstring){ auto dwControlCount; auto counter; auto wEventCount; auto lpEvent; ClearUnknown(ea,0x40); FixDword (ea + 0x00, "dwObjectGuids" + "_" + catstring, "How many GUIDs to Register. 2 = Designer"); FixDword (ea + 0x04, "lpObjectGuid" + "_" + catstring, "Unique GUID of the Object *VERIFY*"); FixDword (ea + 0x08, "dwNull" + "_" + catstring, "Unused."); FixDword (ea + 0x0C, "lpuuidObjectTypes" + "_" + catstring, "Pointer to Array of Object Interface GUIDs"); FixDword (ea + 0x10, "dwObjectTypeGuids" + "_" + catstring, "How many GUIDs in the Array above."); FixDword (ea + 0x14, "lpControls2" + "_" + catstring, "Usually the same as lpControls."); FixDword (ea + 0x18, "dwNull2" + "_" + catstring, "Unused."); FixDword (ea + 0x1C, "lpObjectGuid2" + "_" + catstring, "Pointer to Array of Object GUIDs."); FixDword (ea + 0x20, "dwControlCount" + "_" + catstring, "Number of Controls in array below."); FixDword (ea + 0x24, "lpControls" + "_" + catstring, "Pointer to Controls Array."); FixWord (ea + 0x28, "wEventCount" + "_" + catstring, "Number of Events in Event Array."); FixWord (ea + 0x2A, "wPCodeCount" + "_" + catstring, "Number of P-Codes used by this Object."); FixWord (ea + 0x2C, "bWInitializeEvent" + "_" + catstring, "Offset to Initialize Event from Event Table."); FixWord (ea + 0x2E, "bWTerminateEvent" + "_" + catstring, "Offset to Terminate Event in Event Table."); FixDword (ea + 0x30, "lpEvents" + "_" + catstring, "Pointer to Events Array."); FixDword (ea + 0x34, "lpBasicClassObject" + "_" + catstring, "Pointer to in-memory Class Objects."); FixDword (ea + 0x38, "dwNull3" + "_" + catstring, "Unused."); FixDword (ea + 0x3C, "lpIdeData" + "_" + catstring, "Only valid in IDE."); dwControlCount = Dword(ea + 0x20); if(dwControlCount != 0){ for(counter=0;counterJump to Entry point..."); ExtLinA(reginaldwong+0x0a,4,";========================================================================"); reginaldwong = GetOperandValue(reginaldwong,0); Message("Thunder Runtime Main Parameter EXEPROJECTINFO at: %s\n",ltoa(reginaldwong,16)); if(Dword(reginaldwong) != 0x21354256) return 0; Message("\nRestructuring VB Header"); FixVBHeader(reginaldwong,""); // VB Header lpComRegisterData = Dword(reginaldwong+0x54); // COM Registraion Data if(lpComRegisterData != 0){ Message("\nRestructuring COM Registration Data"); FixCOMRegistrationData(lpComRegisterData,"CRD"); bRegInfo = Dword(lpComRegisterData); // COM Registration Info if(bRegInfo != 0){ Message("\nRestructuring COM Registration Info"); FixCOMRegistrationInfo(lpComRegisterData + bRegInfo, "CRI"); bDesignerData = lpComRegisterData + Dword(lpComRegisterData + bRegInfo + 0x40); if(Dword(bDesignerData) != 0){ Message("\nRestructuring Designer Information"); FixDesignerInfo(bDesignerData,"DI"); } } } lpProjectData = Dword(reginaldwong+0x30); if(lpProjectData != 0){ Message("\nRestructuring Project Information"); FixProjectInformation(lpProjectData, "PI"); // Project Information lpObjectTable = Dword(lpProjectData+0x04); if(lpObjectTable != 0){ dwCompiledObjects = Word(lpObjectTable+0x2c); Message("\nRestructuring Object Table"); FixObjectTable(lpObjectTable,"OT"); lpProjectInfo2 = Dword(lpObjectTable+0x08); if(lpProjectInfo2 != 0){ Message("\nRestructuring 2nd Project Information"); FixSecondaryProjectInformation(lpProjectInfo2,"PI2"); lpObjectList = Dword(lpProjectInfo2+0x10); if(lpObjectList != 0){ for(counter=0;counterJump to Entry point..."); Message("\n\nDone running VB IDC\nby Reginald Wong\nreginaldw[at]trendmicro[dot]com[dot]ph\n"); }