6
0
mirror of https://github.com/avast/ioc synced 2024-06-20 22:08:34 +00:00
ioc-collection/VB-Research/decrypt_test/main.cpp
2021-05-19 13:26:37 +02:00

169 lines
4.8 KiB
C++

#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){
printf("initExtendedTLS failed...");
return;
}*/
//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();
}