''' Copyright (c) 2008 Paolo Palumbo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' ''' Version 1.0: * Created the script Version 1.1: * Fix: could not create names if the name was already present in the db Version 1.2: * __vbaEnd does not return * Added some type information for common functions Version 1.2a: * Lots of bugfixes ''' import idaapi # Translated from original IDC script def SetNameComm(ea,varname,comment,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in SetNameComm!" return MakeName(ea,varname) MakeComm(ea,comment) return # Translated from original IDC script def FixByte(ea,varname,comment,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixByte!" return MakeByte(ea) SetNameComm(ea,varname,comment,Min,Max) return # Translated from original IDC script def FixWord(ea,varname,comment,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixWord!" return MakeWord(ea) SetNameComm(ea,varname,comment,Min,Max) return # Translated from original IDC script def FixDword(ea,varname,comment,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixDword!" return MakeDword(ea) SetNameComm(ea,varname,comment,Min,Max) return # Translated from original IDC script def FixUUID(ea,varname,comment,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixUUID!" return idaapi.do_data_ex(ea, FF_BYTE, 0x10, 0xFFFF) SetNameComm(ea,varname,comment,Min,Max); return # Translated from original IDC script def FixStr(ea,eea,varname,comment,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixStr!" return MakeStr(ea,eea) SetNameComm(ea,varname,comment,Min,Max) return # Translated from original IDC script def ClearUnknown(ea,size,Min,Max): if ea == BADADDR or size <= 0 or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in ClearUnknown!" return MakeUnkn(ea,0x03) counter = 0 while counter < size: MakeName(ea+counter,"") counter += 1 return # Translated from original IDC script def FixVBHeader(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixVBHeader" return ClearUnknown(ea,0x68,Min,Max) FixStr(ea + 0x00, ea + 0x04, "szVbMagic"+"_"+catstring,"+VB5!+ String",Min,Max) FixWord(ea + 0x04, "wRuntimeBuild"+ "_" + catstring,"Build of the VB6 Runtime",Min,Max) FixStr(ea + 0x06, ea + 0x14,"szLangDll"+"_" + catstring,"Language Extension DLL",Min,Max) FixStr(ea + 0x14, ea + 0x22,"szSecLangDll"+"_"+ catstring,"2nd Language Extension DLL",Min,Max) FixWord(ea + 0x22,"wRuntimeRevision"+"_"+ catstring,"Internal Runtime Revision",Min,Max) FixDword(ea + 0x24,"dwLCID"+"_"+catstring,"LCID of Language DLL",Min,Max) FixDword(ea + 0x28,"dwSecLCID"+ "_" + catstring,"LCID of 2nd Language DLL",Min,Max) FixDword(ea + 0x2C,"lpSubMain"+ "_" + catstring,"Pointer to Sub Main Code",Min,Max) FixDword(ea + 0x30,"lpProjectData"+ "_" + catstring,"Pointer to Project Data",Min,Max) FixDword(ea + 0x34,"fMdlIntCtls"+ "_" + catstring,"VB Control Flags for IDs < 32",Min,Max) FixDword(ea + 0x38,"fMdlIntCtls2"+ "_" + catstring,"VB Control Flags for IDs > 32",Min,Max) FixDword(ea + 0x3C,"dwThreadFlags"+ "_" + catstring,"Threading Mode",Min,Max) FixDword(ea + 0x40,"dwThreadCount"+ "_" + catstring,"Threads to support in pool",Min,Max) FixWord(ea + 0x44,"wFormCount"+ "_" + catstring,"Number of forms present",Min,Max) FixWord(ea + 0x46,"wExternalCount"+ "_" + catstring,"Number of external controls",Min,Max) FixDword(ea + 0x48,"dwThunkCount"+ "_" + catstring,"Number of thunks to create",Min,Max) FixDword(ea + 0x4C,"lpGuiTable"+ "_" + catstring,"Pointer to GUI Table",Min,Max) FixDword(ea + 0x50,"lpExternalTable"+ "_" + catstring,"Pointer to External Table",Min,Max) FixDword(ea + 0x54,"lpComRegisterData"+ "_" + catstring,"Pointer to COM Information",Min,Max) FixDword(ea + 0x58,"bSZProjectDescription"+ "_" + catstring,"Offset to Project Description",Min,Max) FixDword(ea + 0x5C,"bSZProjectExeName"+ "_" + catstring,"Offset to Project EXE Name",Min,Max) FixDword(ea + 0x60,"bSZProjectHelpFile"+ "_" + catstring,"Offset to Project Help File",Min,Max) FixDword(ea + 0x64,"bSZProjectName"+ "_" + catstring,"Offset to Project Name",Min,Max) if Dword(ea+0x2c) != 0: AddEntryPoint(Dword(ea+0x2c),Dword(ea+0x2c),"Sub_Main",1) return # Translated from original IDC script def FixCOMRegistrationData(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixCOMRegistrationData" return ClearUnknown(ea,0x30,Min,Max) FixDword(ea + 0x00,"bRegInfo"+ "_" + catstring,"Offset to COM Interfaces Info",Min,Max) FixDword(ea + 0x04,"bSZProjectName"+ "_" + catstring,"Offset to Project/Typelib Name",Min,Max) FixDword(ea + 0x08,"bSZHelpDirectory"+ "_" + catstring,"Offset to Help Directory",Min,Max) FixDword(ea + 0x0C,"bSZProjectDescription"+ "_" + catstring,"Offset to Project Description",Min,Max) FixUUID(ea + 0x10,"uuidProjectClsId"+ "_" + catstring,"CLSID of Project/Typelib",Min,Max) FixDword(ea + 0x20,"dwTlbLcid"+ "_" + catstring,"LCID of Type Library",Min,Max) FixWord(ea + 0x24,"wUnknown"+ "_" + catstring,"Might be something. Must check",Min,Max) FixWord(ea + 0x26,"wTlbVerMajor"+ "_" + catstring,"Typelib Major Version",Min,Max) FixWord(ea + 0x28,"wTlbVerMinor"+ "_" + catstring,"Typelib Minor Version",Min,Max) return # Translated from original IDC script def FixCOMRegistrationInfo(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixCOMRegistrationInfo" return ClearUnknown(ea,0x44,Min,Max) FixDword(ea + 0x00,"bNextObject"+ "_" + catstring,"Offset to COM Interfaces Info",Min,Max) FixDword(ea + 0x04,"bObjectName"+ "_" + catstring,"Offset to Object Name",Min,Max) FixDword(ea + 0x08,"bObjectDescription"+ "_" + catstring,"Offset to Object Description",Min,Max) FixDword(ea + 0x0C,"dwInstancing"+ "_" + catstring,"Instancing Mode",Min,Max) FixDword(ea + 0x10,"dwObjectId"+ "_" + catstring,"Current Object ID in the Project",Min,Max) FixUUID(ea + 0x14,"uuidObject"+ "_" + catstring,"CLSID of Object",Min,Max) FixDword(ea + 0x24,"fIsInterface"+ "_" + catstring,"Specifies if the next CLSID is valid",Min,Max) FixDword(ea + 0x28,"bUuidObjectIFace"+ "_" + catstring,"Offset to CLSID of Object Interface",Min,Max) FixDword(ea + 0x2C,"bUuidEventsIFace"+ "_" + catstring,"Offset to CLSID of Events Interface",Min,Max) FixDword(ea + 0x30,"fHasEvents"+ "_" + catstring,"Specifies if the CLSID above is valid",Min,Max) FixDword(ea + 0x34,"dwMiscStatus"+ "_" + catstring,"OLEMISC Flags (see MSDN docs)",Min,Max) FixByte(ea + 0x38,"fClassType"+ "_" + catstring,"Class Type",Min,Max) FixByte(ea + 0x39,"fObjectType"+ "_" + catstring,"Flag identifying the Object Type",Min,Max) FixWord(ea + 0x3A,"wToolboxBitmap32"+ "_" + catstring,"Control Bitmap ID in Toolbox",Min,Max) FixWord(ea + 0x3C,"wDefaultIcon"+ "_" + catstring,"Minimized Icon of Control Window",Min,Max) FixWord(ea + 0x3E,"fIsDesigner"+ "_" + catstring,"Specifies whether this is a Designer",Min,Max) FixDword(ea + 0x40,"bDesignerData"+ "_" + catstring,"Offset to Designer Data",Min,Max) return # Translated from original IDC script def FixDesignerInfo(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixDesignerInfo" return ClearUnknown(ea,Dword(ea+0x10)+0x14,Min,Max) FixUUID(ea + 0x00,"uuidDesigner"+ "_" + catstring,"CLSID of the Addin/Designer",Min,Max) FixDword(ea + 0x10,"cbStructSize"+ "_" + catstring,"Total Size of the next fields.",Min,Max) ea = ea + 0x18 MakeDword(ea - 0x04) FixStr(ea, ea + Dword(ea - 0x04),"bstrAddinRegKey"+ "_" + catstring,"Registry Key of the Addin",Min,Max) ea = ea + 0x04 + Dword(ea - 0x04) MakeDword(ea - 0x04) FixStr(ea, ea + Dword(ea - 0x04),"bstrAddinName"+ "_" + catstring,"Friendly Name of the Addin",Min,Max) ea = ea + 0x04 + Dword(ea - 0x04) MakeDword(ea - 0x04) FixStr(ea, ea + Dword(ea - 0x04),"bstrAddinDescription"+ "_" + catstring,"Description of Addin",Min,Max) ea = ea + Dword(ea - 0x04) FixDword(ea,"dwLoadBehaviour"+ "_" + catstring,"CLSID of Object",Min,Max) ea = ea + 0x08 MakeDword(ea - 0x04) FixStr(ea, ea + Dword(ea - 0x04), "bstrSatelliteDll"+ "_" + catstring,"Satellite DLL, if specified",Min,Max) ea = ea + 0x04 + Dword(ea - 0x04) MakeDword(ea - 0x04) FixStr(ea, ea + Dword(ea - 0x04),"bstrAdditionalRegKey"+ "_" + catstring,"Extra Registry Key, if specified",Min,Max) ea = ea + Dword(ea - 0x04) FixDword(ea,"dwCommandLineSafe"+ "_" + catstring,"Specifies a GUI-less Addin if 1.",Min,Max) return # Translated from original IDC script def FixProjectInformation(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixProjectInformation" return ClearUnknown(ea,0x23c,Min,Max) FixDword(ea + 0x00,"dwVersion"+ "_" + catstring,"5.00 in Hex (0x1F4). Version.",Min,Max) FixDword(ea + 0x04,"lpObjectTable"+ "_" + catstring,"Pointer to the Object Table",Min,Max) FixDword(ea + 0x08,"dwNull"+ "_" + catstring,"Unused value after compilation.",Min,Max) FixDword(ea + 0x0C,"lpCodeStart"+ "_" + catstring,"Points to start of code. Unused.",Min,Max) FixDword(ea + 0x10,"lpCodeEnd"+ "_" + catstring,"Points to end of code. Unused.",Min,Max) FixDword(ea + 0x14,"dwDataSize"+ "_" + catstring,"Size of VB Object Structures. Unused.",Min,Max) FixDword(ea + 0x18,"lpThreadSpace"+ "_" + catstring,"Pointer to Pointer to Thread Object.",Min,Max) FixDword(ea + 0x1C,"lpVbaSeh"+ "_" + catstring,"Pointer to VBA Exception Handler",Min,Max) FixDword(ea + 0x20,"lpNativeCode"+ "_" + catstring,"Pointer to .DATA section.",Min,Max) FixStr(ea + 0x24, ea + 0x234,"szPathInformation"+ "_" + catstring,"Contains Path and ID string. < SP6",Min,Max) FixDword(ea + 0x234,"lpExternalTable"+ "_" + catstring,"Pointer to External Table.",Min,Max) FixDword(ea + 0x238,"dwExternalCount"+ "_" + catstring,"Objects in the External Table.",Min,Max) return # Translated from original IDC script def FixSecondaryProjectInformation(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixSecondaryProjectInformation" return ClearUnknown(ea,0x28,Min,Max) FixDword(ea + 0x00,"lpHeapLink"+ "_" + catstring,"Unused after compilation, always 0.",Min,Max) FixDword(ea + 0x04,"lpObjectTable"+ "_" + catstring,"Back-Pointer to the Object Table.",Min,Max) FixDword(ea + 0x08,"dwReserved"+ "_" + catstring,"Always set to -1 after compiling. Unused",Min,Max) FixDword(ea + 0x0C,"dwUnused"+ "_" + catstring,"Not written or read in any case.",Min,Max) FixDword(ea + 0x10,"lpObjectList"+ "_" + catstring,"Pointer to Object Descriptor Pointers.",Min,Max) FixDword(ea + 0x14,"dwUnused2"+ "_" + catstring,"Not written or read in any case.",Min,Max) FixDword(ea + 0x18,"szProjectDescription"+ "_" + catstring,"Pointer to Project Description",Min,Max) FixDword(ea + 0x1C,"szProjectHelpFile"+ "_" + catstring,"Pointer to Project Help File",Min,Max) FixDword(ea + 0x20,"dwReserved2"+ "_" + catstring,"Always set to -1 after compiling. Unused",Min,Max) FixDword(ea + 0x24,"dwHelpContextId"+ "_" + catstring,"Help Context ID set in Project Settings.",Min,Max) return # Translated from original IDC script def FixObjectTable(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixObjectTable" return ClearUnknown(ea,0x54,Min,Max) FixDword(ea + 0x00,"lpHeapLink"+ "_" + catstring,"Unused after compilation, always 0.",Min,Max) FixDword(ea + 0x04,"lpExecProj"+ "_" + catstring,"Pointer to VB Project Exec COM Object.",Min,Max) FixDword(ea + 0x08,"lpProjectInfo2"+ "_" + catstring,"Secondary Project Information.",Min,Max) FixDword(ea + 0x0C,"dwReserved"+ "_" + catstring,"Always set to -1 after compiling. Unused",Min,Max) FixDword(ea + 0x10,"dwNull"+ "_" + catstring,"Not used in compiled mode.",Min,Max) FixDword(ea + 0x14,"lpProjectObject"+ "_" + catstring,"Pointer to in-memory Project Data.",Min,Max) FixUUID(ea + 0x18,"uuidObject"+ "_" + catstring,"GUID of the Object Table.",Min,Max) FixWord(ea + 0x28,"fCompileState"+ "_" + catstring,"Internal flag used during compilation.",Min,Max) FixWord(ea + 0x2A,"dwTotalObjects"+ "_" + catstring,"Total objects present in Project.",Min,Max) FixWord(ea + 0x2C,"dwCompiledObjects"+ "_" + catstring,"Equal to above after compiling.",Min,Max) FixWord(ea + 0x2E,"dwObjectsInUse"+ "_" + catstring,"Usually equal to above after compile.",Min,Max) FixDword(ea + 0x30,"lpObjectArray"+ "_" + catstring,"Pointer to Object Descriptors",Min,Max) FixDword(ea + 0x34,"fIdeFlag"+ "_" + catstring,"Flag/Pointer used in IDE only.",Min,Max) FixDword(ea + 0x38,"lpIdeData"+ "_" + catstring,"Flag/Pointer used in IDE only.",Min,Max) FixDword(ea + 0x3C,"lpIdeData2"+ "_" + catstring,"Flag/Pointer used in IDE only.",Min,Max) FixDword(ea + 0x40,"lpszProjectName"+ "_" + catstring,"Pointer to Project Name.",Min,Max) FixDword(ea + 0x44,"dwLcid"+ "_" + catstring,"LCID of Project.",Min,Max) FixDword(ea + 0x48,"dwLcid2"+ "_" + catstring,"Alternate LCID of Project.",Min,Max) FixDword(ea + 0x4C,"lpIdeData3"+ "_" + catstring,"Flag/Pointer used in IDE only.",Min,Max) FixDword(ea + 0x50,"dwIdentifier"+ "_" + catstring,"Template Version of Structure.",Min,Max) return # Translated from original IDC script def FixPrivateObjectDescriptor(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixPrivateObjectDescriptor" return ClearUnknown(ea,0x40,Min,Max) FixDword(ea + 0x00,"lpHeapLink"+ "_" + catstring,"Unused after compilation, always 0.",Min,Max) FixDword(ea + 0x04,"lpObjectInfo"+ "_" + catstring,"Pointer to the Object Info for this Object.",Min,Max) FixDword(ea + 0x08,"dwReserved"+ "_" + catstring,"Always set to -1 after compiling.",Min,Max) FixDword(ea + 0x0C,"dwIdeData"+ "_" + catstring,"[3] Not valid after compilation.",Min,Max) MakeDword(ea + 0x10) MakeDword(ea + 0x14) FixDword(ea + 0x18,"lpObjectList"+ "_" + catstring,"Points to the Parent Structure (Array)",Min,Max) FixDword(ea + 0x1C,"dwIdeData2"+ "_" + catstring,"Not valid after compilation.",Min,Max) FixDword(ea + 0x20,"lpObjectList2"+ "_" + catstring,"[3] Points to the Parent Structure (Array).",Min,Max) MakeDword(ea + 0x24) MakeDword(ea + 0x28) FixDword(ea + 0x2C,"dwIdeData3"+ "_" + catstring,"[3] Not valid after compilation.",Min,Max) MakeDword(ea + 0x30) MakeDword(ea + 0x34) FixDword(ea + 0x38,"dwObjectType"+ "_" + catstring,"Type of the Object described.",Min,Max) FixDword(ea + 0x3C,"dwIdentifier"+ "_" + catstring,"Template Version of Structure.",Min,Max) return # Translated from original IDC script def FixPublicObjectDescriptor(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixPublicObjectDescriptor" return ClearUnknown(ea,0x30,Min,Max) FixDword(ea + 0x00,"lpObjectInfo"+ "_" + catstring,"Pointer to the Object Info for this Object.",Min,Max) FixDword(ea + 0x04,"dwReserved"+ "_" + catstring,"Always set to -1 after compiling.",Min,Max) FixDword(ea + 0x08,"lpPublicBytes"+ "_" + catstring,"Pointer to Public Variable Size integers.",Min,Max) FixDword(ea + 0x0C,"lpStaticBytes"+ "_" + catstring,"Pointer to Static Variable Size integers.",Min,Max) FixDword(ea + 0x10,"lpModulePublic"+ "_" + catstring,"Pointer to Public Variables in DATA section",Min,Max) FixDword(ea + 0x14,"lpModuleStatic"+ "_" + catstring,"Pointer to Static Variables in DATA section",Min,Max) FixDword(ea + 0x18,"lpszObjectName"+ "_" + catstring,"Name of the Object.",Min,Max) FixDword(ea + 0x1C,"dwMethodCount"+ "_" + catstring,"Number of Methods in Object.",Min,Max) FixDword(ea + 0x20,"lpMethodNames"+ "_" + catstring,"If present, pointer to Method names array.",Min,Max) FixDword(ea + 0x24,"bStaticVars"+ "_" + catstring,"Offset to where to copy Static Variables.",Min,Max) FixDword(ea + 0x28,"fObjectType"+ "_" + catstring,"Flags defining the Object Type.",Min,Max) FixDword(ea + 0x2C,"dwNull"+ "_" + catstring,"Not valid after compilation.",Min,Max) return # Translated from original IDC script def FixObjectInformation(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixObjectInformation" return ClearUnknown(ea,0x38,Min,Max) FixWord(ea + 0x00,"wRefCount"+ "_" + catstring,"Always 1 after compilation.",Min,Max) FixWord(ea + 0x02,"wObjectIndex"+ "_" + catstring,"Index of this Object.",Min,Max) FixDword(ea + 0x04,"lpObjectTable"+ "_" + catstring,"Pointer to the Object Table",Min,Max) FixDword(ea + 0x08,"lpIdeData"+ "_" + catstring,"Zero after compilation. Used in IDE only.",Min,Max) FixDword(ea + 0x0C,"lpPrivateObject"+ "_" + catstring,"Pointer to Private Object Descriptor.",Min,Max) FixDword(ea + 0x10,"dwReserved"+ "_" + catstring,"Always -1 after compilation.",Min,Max) FixDword(ea + 0x14,"dwNull"+ "_" + catstring,"Unused.",Min,Max) FixDword(ea + 0x18,"lpObject"+ "_" + catstring,"Back-Pointer to Public Object Descriptor.",Min,Max) FixDword(ea + 0x1C,"lpProjectData"+ "_" + catstring,"Pointer to in-memory Project Object.",Min,Max) FixWord(ea + 0x20,"wMethodCount"+ "_" + catstring,"Number of Methods",Min,Max) FixWord(ea + 0x22,"wMethodCount2"+ "_" + catstring,"Zeroed out after compilation. IDE only.",Min,Max) FixDword(ea + 0x24,"lpMethods"+ "_" + catstring,"Pointer to Array of Methods.",Min,Max) FixWord(ea + 0x28,"wConstants"+ "_" + catstring,"Number of Constants in Constant Pool.",Min,Max) FixWord(ea + 0x2A,"wMaxConstants"+ "_" + catstring,"Constants to allocate in Constant Pool.",Min,Max) FixDword(ea + 0x2C,"lpIdeData2"+ "_" + catstring,"Valid in IDE only.",Min,Max) FixDword(ea + 0x30,"lpIdeData3"+ "_" + catstring,"Valid in IDE only.",Min,Max) FixDword(ea + 0x34,"lpConstants"+ "_" + catstring,"Pointer to Constants Pool.",Min,Max) if Dword(ea+0x34) != (ea+0x38) : FixOptionalObjectInformation(ea+0x38,"O"+catstring,Min,Max) return # Translated from original IDC script def FixOptionalObjectInformation(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixOptionalObjectInformation" return ClearUnknown(ea,0x40,Min,Max) FixDword(ea + 0x00,"dwObjectGuids"+ "_" + catstring,"How many GUIDs to Register. 2 = Designer",Min,Max) FixDword(ea + 0x04,"lpObjectGuid"+ "_" + catstring,"Unique GUID of the Object *VERIFY*",Min,Max) FixDword(ea + 0x08,"dwNull"+ "_" + catstring,"Unused.",Min,Max) FixDword(ea + 0x0C,"lpuuidObjectTypes"+ "_" + catstring,"Pointer to Array of Object Interface GUIDs",Min,Max) FixDword(ea + 0x10,"dwObjectTypeGuids"+ "_" + catstring,"How many GUIDs in the Array above.",Min,Max) FixDword(ea + 0x14,"lpControls2"+ "_" + catstring,"Usually the same as lpControls.",Min,Max) FixDword(ea + 0x18,"dwNull2"+ "_" + catstring,"Unused.",Min,Max) FixDword(ea + 0x1C,"lpObjectGuid2"+ "_" + catstring,"Pointer to Array of Object GUIDs.",Min,Max) FixDword(ea + 0x20,"dwControlCount"+ "_" + catstring,"Number of Controls in array below.",Min,Max) FixDword(ea + 0x24,"lpControls"+ "_" + catstring,"Pointer to Controls Array.",Min,Max) FixWord(ea + 0x28,"wEventCount"+ "_" + catstring,"Number of Events in Event Array.",Min,Max) FixWord(ea + 0x2A,"wPCodeCount"+ "_" + catstring,"Number of P-Codes used by this Object.",Min,Max) FixWord(ea + 0x2C,"bWInitializeEvent"+ "_" + catstring,"Offset to Initialize Event from Event Table.",Min,Max) FixWord(ea + 0x2E,"bWTerminateEvent"+ "_" + catstring,"Offset to Terminate Event in Event Table.",Min,Max) FixDword(ea + 0x30,"lpEvents"+ "_" + catstring,"Pointer to Events Array.",Min,Max) FixDword(ea + 0x34,"lpBasicClassObject"+ "_" + catstring,"Pointer to in-memory Class Objects.",Min,Max) FixDword(ea + 0x38,"dwNull3"+ "_" + catstring,"Unused.",Min,Max) FixDword(ea + 0x3C,"lpIdeData"+ "_" + catstring,"Only valid in IDE.",Min,Max) dwControlCount = Dword(ea + 0x20) if dwControlCount != 0: counter = 0 while counter < dwControlCount: FixControlInformation(Dword(ea+0x24)+(counter*0x28),catstring+"CI"+"%x" % (counter+1),Min,Max) counter += 1 counter = 0 wEventCount = Word(ea + 0x28) while counter < wEventCount: lpEvent = Dword(Dword(ea+0x30)+(0x04*counter)) if Byte(lpEvent) == 0xE9: lpEvent = lpEvent + 0x05 + Dword(lpEvent+0x01) AddEntryPoint(lpEvent,lpEvent,catstring+"Event"+"%x" %(counter+1),1) counter += 1 return # Translated from original IDC script def FixControlInformation(ea,catstring,Min,Max): if ea == BADADDR or ea >= Max or ea <= Min: print "[VbPython] Erroneous incoming parameters in FixControlInformation" return ClearUnknown(ea,0x28,Min,Max) FixDword(ea + 0x00,"fControlType"+ "_" + catstring,"Type of control.",Min,Max) FixWord(ea + 0x04,"wEventcount"+ "_" + catstring,"Number of Event Handlers supported.",Min,Max) FixWord(ea + 0x06,"bWEventsOffset"+ "_" + catstring,"Offset in to Memory struct to copy Events.",Min,Max) FixDword(ea + 0x08,"lpGuid"+ "_" + catstring,"Pointer to GUID of this Control.",Min,Max) FixDword(ea + 0x0C,"dwIndex"+ "_" + catstring,"Index ID of this Control.",Min,Max) FixDword(ea + 0x10,"dwNull"+ "_" + catstring,"Unused.",Min,Max) FixDword(ea + 0x14,"dwNull2"+ "_" + catstring,"Unused.",Min,Max) FixDword(ea + 0x18,"lpEventTable"+ "_" + catstring,"Pointer to Event Handler Table.",Min,Max) FixDword(ea + 0x1C,"lpIdeData"+ "_" + catstring,"Valid in IDE only.",Min,Max) FixDword(ea + 0x20,"lpszName"+ "_" + catstring,"Name of this Control.",Min,Max) FixDword(ea + 0x24,"dwIndexCopy"+ "_" + catstring,"Secondary Index ID of this Control.",Min,Max) return # Pythonized version of Reginald Wong's analysis # Translated from original IDC script def VbPythonAnalysis(Min,Max): dwEntryPoint = GetEntryPoint(GetEntryOrdinal(0)) if not idaapi.ExtraGet(dwEntryPoint+0x0a,1000): idaapi.describe(dwEntryPoint+0x0a,1, ';========================================================================\n' + \ ';VBPython\n' + ';Copyright Paolo Palumbo, 2008. Reginald Wong for original IDC script\n' + \ ';Detected functions can be reached using the entry point lister (Ctrl-E) ...\n' + \ ';========================================================================\n') dwExeProjectInfo = GetOperandValue(dwEntryPoint,0) print "[VbPython] ThunRTMain Exe Project Info at 0x%x" % dwExeProjectInfo if Dword(dwExeProjectInfo) != 0x21354256: return print "[VbPython] Restructuring VB Header" FixVBHeader(dwExeProjectInfo,'',Min,Max) lpComRegisterData = Dword(dwExeProjectInfo+0x54) if lpComRegisterData != 0: print "[VbPython] Restructuring COM registration Data" FixCOMRegistrationData(lpComRegisterData,"CRD",Min,Max) bRegInfo = Dword(lpComRegisterData) if bRegInfo != 0: print "[VbPython] Restructuring COM Registration Info" FixCOMRegistrationInfo(lpComRegisterData + bRegInfo, "CRI",Min,Max) bDesignerData = lpComRegisterData + Dword(lpComRegisterData + bRegInfo + 0x40) if Dword(bDesignerData) != 0: print "[VbPython] Restructuring Designer Information" FixDesignerInfo(bDesignerData,"DI",Min,Max) lpProjectData = Dword(dwExeProjectInfo+0x30) if lpProjectData != 0: print "[VbPython] Restructuring Project Information" FixProjectInformation(lpProjectData, "PI",Min,Max) lpObjectTable = Dword(lpProjectData+0x04) if lpObjectTable != 0: dwCompiledObjects = Word(lpObjectTable+0x2c) print "[VbPython] Restructuring Object Table" FixObjectTable(lpObjectTable,"OT",Min,Max) lpProjectInfo2 = Dword(lpObjectTable+0x08) if lpProjectInfo2 != 0: print "[VbPython] Restructuring 2nd Project Information" FixSecondaryProjectInformation(lpProjectInfo2,"PI2",Min,Max) lpObjectList = Dword(lpProjectInfo2+0x10) if lpObjectList != 0: counter = 0 while counter < dwCompiledObjects: MakeDword(lpObjectList+(counter*0x04)) print "[VbPython] Restructuring Private Object Descriptor 0x%x" % (counter+1) FixPrivateObjectDescriptor(Dword(lpObjectList+(counter*0x04)),"PriOD"+"%x" % (counter+1),Min,Max) print "[VbPython] Restructuring Object Information 0x%x" % (counter+1) Object = Dword(lpObjectList+(counter*4)) if Object != BADADDR: FixObjectInformation(Dword(Object+4),"PriOI"+"%x" % (counter+1),Min,Max) counter += 1 lpObjectArray = Dword(lpObjectTable+0x30) if lpObjectArray != 0: counter = 0 while counter < dwCompiledObjects: print "[VbPython] Restructuring Public Object Descriptor 0x%x" % (counter+1) FixPublicObjectDescriptor(lpObjectArray+(counter*0x30),"PubOD"+"%x" % (counter+1),Min,Max) print "[VbPython] Restructuring Object Information 0x%x" % (counter+1) FixObjectInformation(Dword(lpObjectArray+(counter*0x30)),"PubOI"+"%x" % (counter+1),Min,Max) counter += 1 return # Analysis part for DllFunctionCall stubs def VbDllFunctionAnalysis(): gOrdinal = 0 # for strings issues # Check the existence of DllFunctionCall function AddressOfDllCall = idaapi.get_name_ea(BADADDR,"DllFunctionCall") if AddressOfDllCall == BADADDR: print "[VbPython] Cannot find DllFunctionCall!" return # Get Xrefs to the function DllFunctionCallsReferences = CodeRefsTo(AddressOfDllCall,0) # Iterate through references for Reference in DllFunctionCallsReferences: print "[VbPython] Use at 0x%x" % Reference # Move to where we believe the stub starts StubStartAddress = Reference - 0x15 # Do check if this is the stub we support if ( (Byte(StubStartAddress) == 0xA1) and (Word(StubStartAddress + 5) == 0xC00B) and \ (Byte(StubStartAddress + 7) == 0x74) and (Word(StubStartAddress + 9) == 0xE0FF) ): print "[VbPython] Stub start at 0x%x" % StubStartAddress # Create function if IDA did not create it already if not idaapi.get_func(Reference): print "[VbPython] Creating a function for the stub" MakeFunction(StubStartAddress,BADADDR) # Retrieve address of the DllFunctionCallStructure OffsetToDllFunctionCallStructure = GetOperandValue(StubStartAddress + 0xB,0) # Read the offset to wrapped function OffsetToDllFunctionName = Dword(OffsetToDllFunctionCallStructure + 4) # Convert that to string MakeUnkn(OffsetToDllFunctionName,3) idaapi.make_ascii_string(OffsetToDllFunctionName,0x0,ASCSTR_C) # Read the name and name the current properly the current stub. Note that IDA will # add type info where available :) FunctionName = idaapi.get_ascii_contents(OffsetToDllFunctionName,idaapi.get_max_ascii_length(OffsetToDllFunctionName,ASCSTR_C),ASCSTR_C) if not FunctionName: # NULL Function name print "[VbPython] Invalid FunctionName. Cannot create stub." return if(MakeName(StubStartAddress,FunctionName) == 0): # We cannot create the string, create alternate string gOrdinal += 1 MakeName(StubStartAddress,FunctionName + "_%i" % gOrdinal) MakeName(Dword(StubStartAddress+1),'g'+FunctionName) print "[VbPython] Stub successfully created!" else: print "[VbPython] Unsupported DllFunctionCall use at 0x%x" % Reference # Will put to no return required functions def VbNoReturnAnalysis(): NonReturningFunctions = ['__vbaEnd'] for FName in NonReturningFunctions: ea = LocByName(FName) if ea == BADADDR: print "[VbPython] Function %s was not found in the database" % (FName) else: idaapi.set_aflags(ea,idaapi.get_aflags(ea)|idaapi.AFL_NORET) print "[VbPython] %s is set to not return" % (FName) return # Will set correct type information for several interesting functions def VbTypeHelper(): FunctionsAndTypes = ['__vbaStrCopy','LPWSTR *__fastcall __vbaStrCopy(LPWSTR *,LPWSTR);', \ '__vbaStrCmp','int __stdcall __vbaStrCmp(LPCWSTR,LPCWSTR);', \ '__vbaLenBstr','int __stdcall __vbaLenBstr(LPCWSTR);', \ '__vbaLenBstrB','int __stdcall __vbaLenBstrB(LPCWSTR);', \ '__vbaStrMove','LPCWSTR __fastcall _vbaStrMove(LPCWSTR *pDestination,LPCWSTR pSource);', \ '__vbaStrToAnsi','LPCWSTR __stdcall __vbaStrToAnsi(char **,LPCWSTR);', \ '__vbaStrCat','LPCWSTR __stdcall __VbaStrCat(LPCWSTR,LPCWSTR);', \ '_remove','int __cdecl __remove(const char *);', \ '__rmdir','int __cdecl __rmdir(const char *);' , \ '__vbaStrToAnsi','char *__stdcall __vbaStrToAnsi(char **lpDestination, BSTR Source);', \ '__vbaStrToUnicode','LPWSTR __stdcall __vbaStrToUnicode(char **lpDestination, BSTR Source);', \ 'rtcMakeDir',' int __stdcall rtcMakeDir(LPCWSTR lpDirectoryName);', \ 'rtcRemoveDir',' int __stdcall rtcRemoveDir(LPCWSTR lpDirectoryName);', \ 'rtcChangeDir','int __stdcall rtcChangeDir(LPCWSTR lpDirectoryName);', \ 'rtcChangeDrive','unsigned int __stdcall rtcChangeDrive(char *lpNewDrive);', \ 'rtcGetTimer','int __stdcall rtcGetTimer();', \ 'rtcFileLength','int __stdcall rtcFileLength(int uFileNumber);', \ '__vbaFileOpen','void __stdcall __vbaFileOpen(long dwRecLength, long dwMode, int dwFileNumber, LPWSTR lpFilename);',\ '__vbaFileClose','void __stdcall __vbaFileClose(int dwFileNumber);', \ 'rtcSpaceBstr','char * __stdcall rtcSpaceBstr(int dwSize);' \ ] Index = 0 ListLength = len(FunctionsAndTypes) while Index < ListLength: ea = LocByName(FunctionsAndTypes[Index]) if ea != BADADDR: SetType(ea,FunctionsAndTypes[Index+1]) print "[VbPython] Added type information for function %s" % (FunctionsAndTypes[Index]) else: print "[VbPython] Cannot find imported function %s" % (FunctionsAndTypes[Index]) Index += 2 # Main function print "[VbPython] VbPython version 1.2a" print "[VbPython] by Paolo Palumbo, 2008. Contact: Ppalumbo1979@gmail.com" print "[VbPython] Starting the task" VbNoReturnAnalysis() VbTypeHelper() VbPythonAnalysis(MinEA(),MaxEA()) VbDllFunctionAnalysis() print "[VbPython] Forcing analysis...", AnalyseArea(MinEA(),MaxEA()) print "Done!" print "[VbPython] Task completed!" print "[VbPython] Enjoy!" print "[VbPython]"