-
Mar 28th, 2020, 03:43 AM
#1
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.
http://sandsprite.com/vbdec/
Last edited by dz32; May 7th, 2023 at 11:49 AM.
-
Mar 28th, 2020, 09:04 AM
#2
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.
-
Mar 29th, 2020, 06:31 AM
#3
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>
Last edited by wqweto; Mar 29th, 2020 at 09:20 AM.
-
Mar 29th, 2020, 10:05 AM
#4
-
Mar 29th, 2020, 10:33 AM
#5
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
-
Apr 1st, 2020, 08:46 PM
#6
Last edited by dz32; May 7th, 2023 at 11:49 AM.
-
Apr 2nd, 2020, 09:18 AM
#7
Hyperactive Member
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
-
May 5th, 2021, 03:23 PM
#8
Last edited by dz32; May 15th, 2023 at 09:29 PM.
-
May 5th, 2021, 09:15 PM
#9
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.
-
May 6th, 2021, 09:32 AM
#10
Hyperactive Member
Re: pcode internals
interesting very good work
-
May 12th, 2021, 03:50 PM
#11
Last edited by dz32; May 15th, 2023 at 09:29 PM.
-
May 16th, 2021, 08:49 PM
#12
Re: pcode internals
btw the vbdec pcode disassembler/debugger has now been released as a free download
-
May 17th, 2021, 03:35 AM
#13
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)
-
May 17th, 2021, 03:58 AM
#14
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>
-
May 18th, 2021, 01:14 PM
#15
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.
-
Apr 7th, 2022, 11:21 AM
#16
Addicted Member
Re: pcode internals
Originally Posted by dz32
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
-
Apr 7th, 2022, 11:37 AM
#17
Re: pcode internals
Originally Posted by smkperu
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>
-
Apr 7th, 2022, 12:26 PM
#18
Addicted Member
Re: pcode internals
Originally Posted by wqweto
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
-
Apr 9th, 2022, 03:35 AM
#19
Addicted Member
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
-
Apr 9th, 2022, 04:47 AM
#20
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.
-
Apr 9th, 2022, 05:33 AM
#21
Re: pcode internals
Originally Posted by smkperu
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>
-
Apr 9th, 2022, 06:06 AM
#22
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.
-
Apr 9th, 2022, 06:10 AM
#23
Addicted Member
Re: pcode internals
Originally Posted by wqweto
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
-
Apr 9th, 2022, 06:14 AM
#24
Addicted Member
Re: pcode internals
Originally Posted by dz32
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
-
Apr 12th, 2022, 12:47 AM
#25
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.
-
Apr 12th, 2022, 12:49 PM
#26
Last edited by dz32; May 15th, 2023 at 09:30 PM.
-
Apr 18th, 2022, 11:10 PM
#27
Addicted Member
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
-
Apr 19th, 2022, 02:45 AM
#28
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|