Results 1 to 28 of 28

Thread: pcode internals

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    pcode internals

    If you are curious about programming language design looking at the vb6 runtime & pcode implementation
    is a very interesting research subject.

    Its a huge and intricate topic that is not well documented. The best way to really understand it, is
    to watch it run live in a pcode debugger.

    Name:  dbg.jpg
Views: 1169
Size:  12.0 KB

    http://sandsprite.com/vbdec/
    Last edited by dz32; May 7th, 2023 at 11:49 AM.

  2. #2
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: pcode internals

    This is a very interesting subject, one I've always been fascinated with. In fact, just the other day I was sitting down thinking about creating my own VM with its own stack machine and opcodes. Not for any practical use but just because it's extremely interesting to me and I know I'd enjoy learning and implementing something like this.

    If you are curious about programming language design looking at the vb6 runtime & pcode implementation
    is a very interesting research subject.
    As a matter of historical interest, pcode is a good subject but I think if one wants to really learn about compilers, stack machines etc., there is quite a lot more information in the .Net and Java world. The .Net Framework's internals, including the CIL which can also be implemented using a stack machine, has a lot more information on it. I've had a passive interest in this stuff for many many years and I remember looking for information on VB's PCode implementation and there was almost no information. When MSIL, now known as CIL became a standard, there was so much information becoming available on it. In fact, it's what gave me the confidence to believe I could actually make my own as a matter of academic interest. There's just so much information in the Java and .Net eco-systems on this subject. One shouldn't just limit their study to VB6's PCode if they really want to learn this stuff. Also, the brilliant minds behind these things have learned a lot and I mean a lot since the days where VB6's PCode interpreter was a giant in it's domain. Highly optimized JIT compilers are just one area where massive advancements have been made.

    Nonetheless, this is a very interesting topic you raised.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  3. #3
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: pcode internals

    > Highly optimized JIT compilers are just one area where massive advancements have been made.

    Tracing JIT compiler for VB6 p-code is next :-))

    Edit: Some info on JS state of JIT -- https://mathiasbynens.be/notes/shapes-ics

    cheers,
    </wqw>

  4. #4

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,989

    Re: pcode internals

    CIL is probably an easier place to start than VB6 pcode for another reason, as well: It's reasonably close to ASM, so if you have any background in ASM you will find that you can work your way through CIL pretty well, whereas this distance between pcode and ASM is greater, making it harder to read.

    However, one should be willing to dance if one wants to take up writing a JIT compiler. After all, any mistakes you make could be considered JITer bugs.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    Re: pcode internals

    [...]
    Last edited by dz32; May 7th, 2023 at 11:49 AM.

  7. #7
    Hyperactive Member
    Join Date
    Jun 2016
    Location
    España
    Posts
    506

    Re: pcode internals

    very good work.
    I follow you and I always like all your videos.
    Although for me it is complicated, but I think it is a great job.
    Greetings

  8. #8

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    Re: pcode internals

    [….]
    Last edited by dz32; May 15th, 2023 at 09:29 PM.

  9. #9
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,421

    Re: pcode internals

    Very useful learning materials, thank you very much, dz32.

    Thanks also to Niya, wqweto, The trick and Shaggy Hiker for their information.
    Last edited by SearchingDataOnly; May 5th, 2021 at 09:18 PM.

  10. #10
    Hyperactive Member
    Join Date
    Jun 2016
    Location
    España
    Posts
    506

    Re: pcode internals

    interesting very good work

  11. #11

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    Re: pcode internals

    [….]
    Last edited by dz32; May 15th, 2023 at 09:29 PM.

  12. #12

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    Re: pcode internals

    btw the vbdec pcode disassembler/debugger has now been released as a free download

  13. #13
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: pcode internals

    [slightly off-topic]

    Is VB pcode the same pcode as used by Pascal compilers from the 1980's (and now?) ? Or are these pcodes quite different?
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  14. #14
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: pcode internals

    This is like assuming that VB's IR (Intermediate Representation) can be the same as some Pascal (or any other) compiler's IR. This might happen if both compilers are from the same vendor or both use (outsource) IR to something like LLVM.

    The point is that p-code is not something specific to VB's interpreter. Most interpreted languages VM's use some form of p-code (Lua, python, not sure about VBScript) using whatever bytecode and opcodes are most suitable for them.

    cheers,
    </wqw>

  15. #15
    PowerPoster
    Join Date
    Jan 2020
    Posts
    3,746

    Re: pcode internals

    What virtual machine interpreter are you working on?I can't understand these, so I can only optimize or choose some ordinary algorithms.If I don't understand, I will send some questions and let's Technology Communication and Learning them together.

    How to decompile the VB6 code parser and debugger, this thing is really useful.

  16. #16
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: pcode internals

    Quote Originally Posted by dz32 View Post
    next article: Writing a PCode Debugger

    https://decoded.avast.io/davidzimmer...code-debugger/

    One more to go after this on how to extract and call pcode byte blobs from C
    (study in pcode function structure, const pool layout, and how execution is transferred from native code to pcode)
    Hello dz32,

    In the article https://decoded.avast.io/davidzimmer...ode-functions/

    I tried the following code of decrypt_test sample of vb-research folder by uncommenting initExtendedTLS() call.But I did'nt understand the difference.


    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    
    #include "vb.h"     //structures
    #include "pcode.h"
    
    int lpProcCallEngine = 0;
    
    //examples progress callback (same vb declare as sleep)
    void __stdcall callback(int arg){
    	printf("%d\n",arg);
    }
    
    void __stdcall strCallBack(char* arg){
    	printf("string callback: %s\n",arg);
    }
    
    //get a temp pointer to p + xBytes without casts or pointer arithmetic
    int* pPlus(int * p, int increment){
    	_asm{
    		mov eax, p
    		add eax, increment
    	}
    }
    
    int initExtendedTLS(HMODULE hRuntime){
    	
    	//vb file access however requires Ebthread+18 to point to valid alloc that doesnt happen with IExprSrvObj initilization..
    	//we dont really need this if we use C callbacks...only use this if really necessary since it adds complexity
    
    	//we get its tls index offset from the start of the rtcGetErl export...
    	//.text:660EA58E FF 35 00 00 11 66   push    _g_itlsEbthread
        int* lpRtcErl = (int*)GetProcAddress(hRuntime,"rtcGetErl");
    	if(lpRtcErl==0) return -1;
    
    	short p = (short)(*lpRtcErl);
    	if (p != 0x35FF) return -2;                    //Check rtcGetErl for push opcode failed
    
    	int* tlsEbthread = (int*)*(pPlus(lpRtcErl,2)); //address of tls slot variable
    	int* tlsMem = (int*)TlsGetValue(*tlsEbthread); //slot value -> actual memory alloc
        if ( tlsMem == 0 ) return -3;                  //TlsGetValue(*g_itlsEbthread) failed 
    
    	int buf = (int)malloc(80);
    	if(buf==0) return -4;
    	memset((void*)buf,0,80);  //MUST be zeroed out
    
    	//printf("tlsMem = %x dummy=%x\n", tlsMem, buf);
        //printf("tlsMem + 0x18 = %x\n", (char*)tlsMem + 0x18);
    
        //_asm int 3
    	*pPlus(tlsMem,0x18) = buf; //fill in this field of struct with our own alloced memory
    	return 1;
    
    }
    
    int offset_rc4;
    
    void __declspec(naked) stubCall_rc4(){
    	_asm{
    		//int 3
    		mov     edx, offset_rc4
    		mov     ecx, lpProcCallEngine
    		jmp     ecx
    	}
    }
    
    
    
    void main(void){
    
    	int rv = 0;
    	int abort = 0; 
    	int constPool[20] = {0};
    	int lpProjObj[10] = {0};
    	
    	objInfo.aObject = (int)&codeObj;
    	objInfo.lpConstantPool = (int)&constPool;
    	objInfo.aObjectTable = (int)&objtable;
    	objtable.lpProjectObject = (int)&lpProjObj;
    
    	/*some debugging values 
    	printf("objtable = %x\n",  &objtable);
    	printf("lpProjObj = %x\n", &lpProjObj);
    	printf("constPool = %x\n", &constPool);
    	printf("pcode = %x - %x\n", &pcode, &pcode + sizeof(pcode));
    	printf("abort addr: %x\n", (int)&abort);*/
    
    	HMODULE hRuntime = (HMODULE)LoadLibrary("msvbvm60.dll");
    	lpProcCallEngine = (int)GetProcAddress(hRuntime,"ProcCallEngine");
    	CreateIExprSrvObj IExprSrvObj = (CreateIExprSrvObj)GetProcAddress(hRuntime,"CreateIExprSrvObj"); 
    
    	IExprSrvObj(0,4,0); //initilize runtime enough for most things to work (COM, native pcode handlers etc)
    
    	//do you need access to native vb file access functions or vb msgbox? (C callbacks cleaner)
    	if(initExtendedTLS(hRuntime) != 1){ //uncommented here
    		printf("initExtendedTLS failed...");
    		return;
    	}//uncommented here
    
    	//build the const pool
    	constPool[0x0] = (int)GetProcAddress(hRuntime,"rtcVarBstrFromAnsi");
    	constPool[0x1] = (int)SysAllocString(L"AAAA");
        constPool[0x2] = (int)&stubCall_rc4; //Module1.Proc_4015EC
    	constPool[0x3] = (int)&strCallBack;
    	constPool[0x4] = (int)GetProcAddress(hRuntime,"rtcTypeName");
    	constPool[0x5] = (int)SysAllocString(L"Byte()");
    	constPool[0x6] = (int)&callback;
    	constPool[0x7] = (int)SysAllocString(L"String");
    	constPool[0x8] = (int)GetProcAddress(hRuntime,"rtcStrConvVar2");
    	constPool[0x9] = (int)GetProcAddress(hRuntime,"rtcLeftCharBstr");
    
    	offset_rc4 = (int)&rc4 + 0x3e4;
    	(*(int*)offset_rc4) = (int)&objInfo;	
    
    	int offset_sub_main = (int)&sub_main + 0x90;
    	(*(int*)offset_sub_main) = (int)&objInfo;
    	
    	/* full run tested & working..
    	_asm{
    		//int 3
    		mov edx, offset_sub_main 
            mov ecx, lpProcCallEngine
    		call ecx
    		mov rv, eax
    	}
    	*/
    
        //now lets call the rc4 function on our own
    	/*
    		Public Function rc4(ByteOrString As Variant, ByVal password As String, strret As Boolean) as variant
    
    		0019FC58 ebp-E8  0x0019FC70 ; ebp-D0 = empty variant (retval)
    		0019FC5C ebp-E4  0x0019FC88 ; ebp-B8 = variant bstr aaaa
    		0019FC60 ebp-E0  0x00794DEC =         0x41
    		0019FC64 ebp-DC  0x0019FC82 ; ebp-BE = -1
    	*/
    	
    	VARIANT retVal = {VT_EMPTY};
    	VARIANT v = {VT_EMPTY};
    	v.vt = VT_BSTR;
    	v.bstrVal = SysAllocStringByteLen("\x92\x01\x60\x01\xA7\x00\x7C\x00",8);
    	BSTR passwd = SysAllocString(L"A");
        int boolStrRet = -1; //vb true
    
    	_asm{
    		//int 3
    		lea eax, boolStrRet
    		push eax
    		push passwd
    		lea eax, v
    		push eax
    		lea eax, retVal
    		push eax
    		mov edx, offset_rc4
            mov ecx, lpProcCallEngine
    		call ecx
    	}
    
    	printf("retval.vt = %x\n", retVal.vt);
        wprintf(L"retval.bstr = %s\n", retVal.bstrVal);
    	printf("Press any key to exit...");
    	getch();
    
    }
    can you explain what the function initExtendedTLS() does when used with a small example.

    Thanks

  17. #17
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: pcode internals

    Quote Originally Posted by smkperu View Post
    can you explain what the function initExtendedTLS() does when used with a small example.
    The link to the article you provided explains the rationale behind this function in detail. Did you read it?

    cheers,
    </wqw>

  18. #18
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: pcode internals

    Quote Originally Posted by wqweto View Post
    The link to the article you provided explains the rationale behind this function in detail. Did you read it?

    cheers,
    </wqw>
    Hello wqewto,

    After reading the article I wanted to see practically.But when I uncommented and used the function I could not see any difference in output.May be I have to add something which is missing and I am unable to understand.

    Thanks

  19. #19
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: pcode internals

    Hello wqw,


    In the article https://decoded.avast.io/davidzimmer...ode-functions/
    as per explanation:



    The allocation at offset 0x18 is only required if we wish to use
    built in VB file operation commands or the MsgBox function.


    Therefore in iniExtendedTLS() function

    when we initialize EBThread+18 as follows:

    Code:
    memset((void*)buf,0,80);  //MUST be zeroed out
    
    	//printf("tlsMem = %x dummy=%x\n", tlsMem, buf);
        //printf("tlsMem + 0x18 = %x\n", (char*)tlsMem + 0x18);
    
        //_asm int 3
    	*pPlus(tlsMem,0x18) = buf; //fill in this field of struct with our own alloced memory

    But this does not happen ie.,when we use built in VB file operation commands or the MsgBox function
    they are not working in pcode.I donot know whether you have checked this practically.

    Thanks

  20. #20
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,651

    Re: pcode internals

    Slightly off topic; but is there a trick to get VBDec to work on Win10? The project tree loads but the only part of the right pane that works is the loading log and the icon viewer. It successfully exports to files, and the popups that show things like resource files or do searches work, so it's just the main form GUI that's broken. It just shows an empty textbox for everything (e.g. if I open the structure search, it shows everything in the VB Header, but on the main form, clicking it just gives an empty textbox with blinking cursor). I've tried various compatibility modes with no success; both pcode and native exes.

  21. #21
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,120

    Re: pcode internals

    Quote Originally Posted by smkperu View Post
    But this does not happen ie.,when we use built in VB file operation commands or the MsgBox function
    they are not working in pcode.I donot know whether you have checked this practically.
    Cannot hide how *glad* I am this does not work!

    You don't expect me to debug it for your next ransomware, do you?

    cheers,
    </wqw>

  22. #22

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    Re: pcode internals

    It has been developed on a win 10 machine and works ok. Just tested the installer on a clean win10 machine
    default install location and everything seemed to work fine for me. Not sure whats up.

    Sounds like the scinitinilla dll or ocx is not working maybe your av ate SciLexer.dll which scivb2.ocx depends on?
    should all be in the hone directory.

    Uncommenting the initilizetls function in the decrypt sample will not do anything noticeable because the
    sample pcode does not use any of the functions that require it. It was just included as an example of how.

    I will not answer any further questions about tls or using ripped pcode.
    Last edited by dz32; Apr 9th, 2022 at 06:13 AM.

  23. #23
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: pcode internals

    Quote Originally Posted by wqweto View Post
    Cannot hide how *glad* I am this does not work!

    You don't expect me to debug it for your next ransomware, do you?

    cheers,
    </wqw>
    Hello wqw,

    Please don't take anything serious.Because you replied me I conveyed you what I have seen practically.
    I really appreciate dz32 for his great work and tried the sample and gave my comments.

    Thanks

  24. #24
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: pcode internals

    Quote Originally Posted by dz32 View Post
    It has been developed on a win 10 machine and works ok. Just tested the installer on a clean win10 machine
    default install location and everything seemed to work fine for me. Not sure whats up.

    Sounds like the scinitinilla dll or ocx is not working maybe your av ate SciLexer.dll which scivb2.ocx depends on?
    should all be in the hone directory.

    Uncommenting the initilizetls function in the decrypt sample will not do anything noticeable because the
    sample pcode does not use any of the functions that require it. It was just included as an example of how.

    I will not answer any further questions about tls or using ripped pcode.
    Hello dz32,

    Thankyou for the clarification and great work.

    Thanks

  25. #25
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,651

    Re: pcode internals

    SciLexer is present; I disabled Windows Defender extremely thoroughly so it's processes don't even load. For AV I rely on firewall, script and adblocking, and obsessively watching processes and connections. Criticize if you want but I haven't had any sign of malware whatsoever since when there was that XP virus that infected you simply by being connected to the internet with no user action. Meanwhile Windows Defender immediately pissed me off with multiple false positives on day 1, then after adjusting various settings still left it making problems, and it insulted me by immediately reverting Group Policy changes, it got ripped out entirely.

    Perhaps it uses components not installed by default on my Win10 version? I run LTSC, which doesn't come with a lot of the bloat of regular editions.

  26. #26

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,055

    Re: pcode internals

    [….]
    Last edited by dz32; May 15th, 2023 at 09:30 PM.

  27. #27
    Addicted Member
    Join Date
    Dec 2021
    Posts
    144

    Re: pcode internals

    Dear dz32,

    Can you provide a c/c++ console app which runs pcode for InputBox vb6 function which accepts a given user input string and returns it using proccallengine() since none of the code samples at https://github.com/avast/ioc/tree/master/VB-Research provide this.

    Thanks

  28. #28
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,651

    Re: pcode internals

    I ran the uninstaller, installed the new version, and now it's working, thanks.

    You know, I can't recall if I ran the installer as administrator last time, but I did this time, perhaps that's the difference? I know regsvr32 sometimes fails if not run as admin.


    @smkperu, is this for your super secret program that's totally not malware but you can't tell anybody what you're doing? I saw that thread, good laughs.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width