VB6 Hijacking

Author: David Zimmer
Date: 07.04.21 - 5:04pm

So a forum user wanted to devise a way to automate a VB6 application that did not have a plugin or scripting framework. He wanted to get a hold of the Vb.Global.Forms collection so that he could access the open forms and then automate them as if his dll was loaded as a plugin.

Another forum user knew where to find the cached Vb.Global pointer, and the following code ensued: (you can read the fill thread here)

Option Explicit
'add one listbox and two buttons

Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Sub GetMem4 Lib "msvbvm60.dll" (ByVal lAddress As Long, var As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes&)

Private Type extEntry
    flag As Long
    offset As Long
End Type

Dim readyToReturn As Boolean

Private Sub Command1_Click()
    readyToReturn = True
End Sub

Function IsIde() As Boolean
    On Error GoTo out
    Debug.Print 1 / 0
out: IsIde = Err
End Function

Private Sub Command2_Click()
End Sub

Private Sub Form_Load()

'    Dim v  As VB.Global
'    MsgBox v.App.EXEName 'variable not set..this is good, sanity check
'    End
    If IsIde Then
        MsgBox "Only run compiled"
        Me.Caption = "It worked!"
        Command1.Caption = "Continue"
        Command2.Caption = "End"
        List1.Move 0, 0, 8000, 8000
        Me.Width = 8400
        Me.Height = 9100
        Command1.Move Me.Width - 3000, 8025
        Command2.Move Me.Width - 1500, 8025
    End If
End Sub

Sub xx(msg As String, v As Long, Optional wait As Boolean = False)
    List1.AddItem msg & ": " & Hex(v) & IIf(wait, "  --- Waiting for continue click...", Empty)
    If wait Then
        readyToReturn = False
        While Not readyToReturn
    End If
End Sub

Private Sub DoTheTrickStuff() Dim vbHeader As Long, lpProjectData As Long, projectDataPointerValue As Long Dim lpExternalTable As Long, externalTablePointerValue As Long Dim externalCount As Long, lpExternalCount As Long Dim i As Integer, e As extEntry, myCaption As String Dim globalPtr As Long, lpGlobalPtr As Long, globalClone As VB.Global Me.Visible = True xx "The pointer I am after", ObjPtr(VB.Global) vbHeader = GetVBHeader() xx "Header", vbHeader lpProjectData = vbHeader + &H30 GetMem4 ByVal lpProjectData, projectDataPointerValue xx "lpProject", projectDataPointerValue lpExternalCount = projectDataPointerValue + &H238 xx "lpExternalCount", lpExternalCount GetMem4 ByVal lpExternalCount, externalCount xx "ExtCount", externalCount lpExternalTable = projectDataPointerValue + &H234 xx "lpExtTable", lpExternalTable GetMem4 ByVal lpExternalTable, externalTablePointerValue xx "ExtTable", externalTablePointerValue For i = 0 To externalCount CopyMemory ByVal VarPtr(e), ByVal externalTablePointerValue, 8 Debug.Print i & ") " & Hex(externalTablePointerValue) & " " & e.flag & " " & Hex(e.offset) If e.flag = 6 Then 'Tag of global object xx "Found flag", e.flag GetMem4 ByVal e.offset + 4, lpGlobalPtr xx "lpGlobalPointer", lpGlobalPtr GetMem4 ByVal lpGlobalPtr, globalPtr xx "GlobalPointer", globalPtr If globalPtr = ObjPtr(VB.Global) Then List1.AddItem "Success!!" Else List1.AddItem "FAIL!!" Exit For End If Set globalClone = GlobalFromPointer(ByVal globalPtr) xx "ObjPtr(globalClone)", ObjPtr(globalClone) ', True myCaption = globalClone.Forms(0).Caption List1.AddItem "globalClone.Forms(0).Caption = " & myCaption globalClone.Forms(0).Caption = "Are you sure?!" Exit For End If externalTablePointerValue = externalTablePointerValue + 8 Next List1.AddItem "Complete" End Sub Private Function GlobalFromPointer(ByVal ptr&) As VB.Global ' this function returns a reference to our form class ' dimension an object variable that we can copy the ' passed pointer into Dim globalClone As VB.Global ' use the CopyMemory API function to copy the ' long pointer into the object variable. CopyMemory globalClone, ptr, 4& Set GlobalFromPointer = globalClone CopyMemory ptr&, 0&, 4& End Function Public Function ObjFromPtr(ByVal pObj As Long) As Object Dim obj As Object CopyMemory obj, pObj, LenB(obj) 'not size 4! Set ObjFromPtr = obj CopyMemory obj, 0&, LenB(obj) 'not size 4! End Function ' // Get VBHeader structure Private Function GetVBHeader() As Long Dim ptr As Long Dim hModule As Long hModule = GetModuleHandle(ByVal "Project1.exe") ' Get e_lfanew GetMem4 ByVal hModule + &H3C, ptr ' Get AddressOfEntryPoint GetMem4 ByVal ptr + &H28 + hModule, ptr ' Get VBHeader GetMem4 ByVal ptr + hModule + 1, GetVBHeader End Function Private Sub Form_Resize() On Error Resume Next List1.Width = Me.Width End Sub

Special considerations:
  • inject native dll which loads vb dll as "plugin"
  • native call vb6 activex method which sets timer
  • vb plugin must execute in the same thread as STA main vb6 app


find the VBHeader.aProjectInfo at offset 0x30 of the VBHeader

walk the VBHeader.aProjectInfo.aExternalTable (offset 0x234 in VBHeader.aProjectInfo struct) of which there will be VBHeader.aProjectInfo.ExternalCount entries (offset 0x238 from start of VBHeader.aProjectInfo )

each entry will be an 8 byte structure

private type extEntry flag as long offset as long end type

when you find flag = 6 you found your target. at that target.offset you will find another 8 byte structure

private type extEntryTarget clsidIIDStructOffset as long lpValue as long end type

you can verify the clsidIID values they are actually another struct 32 bytes consecutive of just use the hex dump of the guids the value of the actual vb.globals you want will be found at the lpValue offset.

I havent played with it as in injection yet, but its an interesting concept.

The Trick ended up posting a full example with injection here. (Local snapshot)

Comments: (0)

Leave Comment:
Email: (not shown)
Message: (Required)
Math Question: 79 + 62 = ? followed by the letter: I 

About Me
More Blogs
Main Site
Posts: (year)
2023 (4)
     UDTs in Native Const Pool
     PublicBytes struct
     VB6 Class Instances
2022 (6)
     VB6 Implements
     vbdec remote scripting
     VB6 Stubs BS
     VB6 TypeInfo
     VB6 VTable Layout
     Yara isPCode rule
2021 (4)
     VB6 Hijacking
     VB6 Gosub
     VB App object
2020 (6)
     AutoIT versions
     IDA JScript 2
     Using VB6 Obj files from C
     Vb6 PCode Internals
     Yara Corrupt Imports
     Yara Undefined values
2019 (6)
     Yara WorkBench
     vb6 API and call backs
     UConnect Disable Cell Modem
2017 (5)
     IDA python over IPC
     dns wildcard blocking
     64bit IDA Plugins
     anterior lines
     misc news/updates
2016 (4)
     KANAL Mod
     Decoders again
     CDO.Message Breakpoints
     SysAnalyzer Updates
2015 (6)
     SysAnalyzer and Site Updates
     crazy decoder
     ida js w/dbg
     flash patching #2
     JS Graphing
     packet reassembly
2014 (5)
     Delphi IDA Plugin
     scdbg IDA integration
     API Hash Database
     Winmerge plugin
     IDACompare Updates
2013 (9)
     Guest Post @ hexblog
     TCP Stream Reassembly
     SysAnalyzer Updates
     Apilogger Video
     Shellcode2Exe trainer
     scdbg updates
     IDA Javascript w/IDE
     Rop Analysis II
     scdbg vrs ROP
2012 (13)
     flash patching
     x64 Hooks
     micro hook
     jmp api+5 *2
     SysAnalyzer Updates
     InjDll runtime config
     C# Asm/Dsm Library
     Shellcode Hook Detection
     Updates II
     Java Hacking
     Windows 8
     Win7 x64
2011 (19)
     Graphing ideas
     .Net Hacking
     Old iDefense Releases
     hll shellcode
     ActionScript Tips
     -patch fu
     scdbg ordinal lookup
     scdbg -api mode
     Peb Module Lists
     scdbg vrs Process Injection
     GetProcAddress Scanner
     scdbg fopen mode
     scdbg findsc mode
     scdbg MemMonitor
     demo shellcodes
     scdbg download
     api hashs redux
     Api hash gen
2010 (11)
     Retro XSS Chat Codes
     Exe as DLL
     Olly Plugins
     Debugging Explorer
     Attach to hidden process
     JS Refactoring
     Asm and Shellcode in CSharp
     Fancy Return Address
     PDF Stream Dumper
     Malcode Call API by Hash
     WinDbg Cheat Sheet
2009 (1)
     GPG Automation