Author: David Zimmer
Date: 08.24.19 - 11:16am
Ok here is an interesting vb6 pcode implementation. So far I have only found this one used when calling a friend method. Consider the following:
Friend Property Let ReplaceFormActive(x As Boolean) bReplaceFormActive = x End Property Private Sub Form_Load() Me.ReplaceFormActive = True End Sub 4017C8 Form1.Form_Load: 4017C8 F4 FF LitI2_Byte 255 4017CA 2B 7AFF PopTmpLdAd2 var_86 4017CD 6C 0800 ILdRf [arg_8] <-- obj target fx is on 4017D0 FF1E 00000800 ImpAdCallNonVirt 4017D6 13 ExitProcHresultWe are trying to figure out what 0000 0800 represents so we can resolve the target method in the disassembly.
Looking at the native handler we see that the arg byte stream is loaded as two int args (two bytes each). The second is used as a stack check after the call:
movzx edi, word ptr [esi+2] add edi, esp ...call... cmp edi, esp jnz StackErr_0Ok cool I like the sanity checking..so whats the 0000? It is an const pool index to load a literal value from. In my test case it loads 4013a8 which is then used in a call eax
004013A8 . B8 00000000 MOV EAX,0 004013AD . 66:3D 33C0 CMP AX,0C033 <-- reserve 4 bytes as do nothing 004013B1 . BA 441B4000 MOV EDX,401B44 <-- target pcode fx Last Offset: 401B44 004013B6 . 68 38104000 PUSH 401038 <-- next native address to jump to 004013BB . C3 RETN .text:00401038 jmp ds:MethCallEngineSo to get back to the pcode, they had to embed a custom thunk configured as a loader for that function. To decode this one in the disassembler I am going to have to add a new post processor specifically for this command.
It is very interesting to watch how they implemented things.
On a funny side note, I have been programming in Vb6 for almost 20 years now, using it pretty much every day and I am still finding new language features I did not know about.
I had never seen the following before until I found the OnGoSub pcode instruction and went googling:
Sub OnGosubGotoDemo() Dim Number, MyString Number = 2 ' index to jump to On Number GoSub Sub1, Sub2 ' calls sub 2 resumes here after On Number GoTo Line1, Line2 ' Branch to Line2. ' Execution does not resume here after On...GoTo. Exit Sub Sub1: MyString = "In Sub1" : Return Sub2: MyString = "In Sub2" : Return Line1: MyString = "In Line1" Line2: MyString = "In Line2" End SubSearching out unhandled opcodes in the pcode disasm also lead me to some (handled) errors in my programs that went unnoticed for years. I had apparently removed a control on the form and not stripped out its resizing code in Form_Resize that was handled with on error resume next. The calls in the pcode just transitioned to late bound calls so no compile error (I was lazy and didnt use Option Explicit in that small form).
I also noticed there is built in pcode instructions for things like MidStr. Eventually they do bubble up to the vba export version, but its interesting they still exist in the pcode set itself. In this case its only used in a specific instance where you call Mid(str,str,len) = str.
Couple other interesting structures I have found that I have no idea how to decode yet (any tips appreciated for those in the know:)