Skip to content

Instantly share code, notes, and snippets.

@StephenLeafWW
Forked from kumatti1/Module1.bas
Created December 13, 2024 06:05
Show Gist options
  • Save StephenLeafWW/2dd6db6837013db4ac04b4b6092f4fda to your computer and use it in GitHub Desktop.
Save StephenLeafWW/2dd6db6837013db4ac04b4b6092f4fda to your computer and use it in GitHub Desktop.
Option Explicit
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Long, Source As Long, ByVal Length As Long)
Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Long, _
ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
ByVal lpProcName As String) As Long
Private Declare Function DialogBoxParam Lib "user32" Alias "DialogBoxParamA" (ByVal hInstance As Long, _
ByVal pTemplateName As Long, ByVal hWndParent As Long, _
ByVal lpDialogFunc As Long, ByVal dwInitParam As Long) As Integer
Private Declare PtrSafe Function MessageBox Lib "user32" Alias "MessageBoxW" (ByVal hwnd As LongPtr, ByVal lpText As LongPtr, ByVal lpCaption As LongPtr, ByVal wType As Long) As Long
Dim HookBytes(0 To 5) As Byte
Dim OriginBytes(0 To 5) As Byte
Dim pFunc As Long
Dim Flag As Boolean
Public Sub RecoverBytes()
MoveMemory ByVal pFunc, ByVal VarPtr(OriginBytes(0)), 6
End Sub
Public Function Hook() As Boolean
Dim TmpBytes(0 To 5) As Byte
Dim p As Long
Dim OriginProtect As Long
Hook = False
Dim hdll&
hdll = GetModuleHandleA("vbe7.dll")
pFunc = GetProcAddress(hdll, "rtcMsgBox")
If VirtualProtect(ByVal pFunc, 6, PAGE_EXECUTE_READWRITE, OriginProtect) <> 0 Then
MoveMemory ByVal VarPtr(TmpBytes(0)), ByVal pFunc, 6
If TmpBytes(0) <> &H68 Then
MoveMemory ByVal VarPtr(OriginBytes(0)), ByVal pFunc, 6
p = VBA.CLng(AddressOf Hookd)
HookBytes(0) = &H68
MoveMemory ByVal VarPtr(HookBytes(1)), ByVal VarPtr(p), 4
HookBytes(5) = &HC3
MoveMemory ByVal pFunc, ByVal VarPtr(HookBytes(0)), 6
Flag = True
Hook = True
End If
End If
End Function
Private Function Hookd(a, ByVal b&, c, d, e) As Long
Hookd = MessageBox(Application.hwnd, StrPtr(a), StrPtr(""), b)
End Function
Sub Main()
Hook
MsgBox ChrW(&H2113)
RecoverBytes
End Sub
@StephenLeafWW
Copy link
Author

Simple rtcMsgBox hooking example (wrapping some basic stuff, types not fully supported)

#include <windows.h>
#include <OleAuto.h> // For SAFEARRAY functions and VARIANT handling
#include <iostream>
#include <comdef.h>
#include <sstream>

// Function pointer type for rtcMsgBox
typedef int (WINAPI *rtcMsgBox_Type)(
    VARIANTARG* vPrompt,
    unsigned int Buttons,
    VARIANTARG* vTitle,
    VARIANTARG* vHelpFile,
    VARIANTARG* vContext);

// Global variables
rtcMsgBox_Type g_OriginalRtcMsgBox = NULL;
BYTE g_OriginalBytes[6] = {0};
BYTE* g_Trampoline = NULL;

std::wstring VariantToString(const VARIANTARG* v) {
    if (!v) return L"<NULL>";

    std::wstringstream ss;

    if (v->vt & VT_BYREF) {
        ss << L"VT_BYREF | ";
        switch (v->vt & ~VT_BYREF) {
            case VT_I4:
                ss << L"VT_I4: " << *(v->plVal);
                return ss.str();
            case VT_BSTR:
                ss << L"VT_BSTR: " << (*(v->pbstrVal) ? *(v->pbstrVal) : L"<NULL>");
                return ss.str();
            default:
                ss << L"<Unsupported BYREF Type> (" << v->vt << L")";
                return ss.str();
        }
    }

    switch (v->vt) {
        case VT_EMPTY: return L"VT_EMPTY";
        case VT_NULL: return L"VT_NULL";
        case VT_I2: ss << v->iVal; return ss.str();
        case VT_I4: ss << v->intVal; return ss.str();
        case VT_R4: ss << v->fltVal; return ss.str();
        case VT_R8: ss << v->dblVal; return ss.str();
        case VT_CY: return L"VT_CY";
        case VT_DATE: return L"VT_DATE";
        case VT_BSTR: return v->bstrVal ? v->bstrVal : L"<NULL>";
        case VT_DISPATCH: return L"VT_DISPATCH";
        case VT_ERROR: return L"VT_ERROR";
        case VT_BOOL: return v->boolVal ? L"True" : L"False";
        case VT_VARIANT: return L"VT_VARIANT";
        case VT_UNKNOWN: return L"VT_UNKNOWN";
        case VT_DECIMAL: return L"VT_DECIMAL";
        case VT_I1: ss << (int)v->cVal; return ss.str();
        case VT_UI1: ss << (int)v->bVal; return ss.str();
        case VT_UI2: ss << v->uiVal; return ss.str();
        case VT_UI4: ss << v->ulVal; return ss.str();
        case VT_I8: ss << v->llVal; return ss.str();
        case VT_UI8: ss << v->ullVal; return ss.str();
        case VT_INT: ss << v->intVal; return ss.str();
        case VT_UINT: ss << v->uintVal; return ss.str();
        case VT_ARRAY: return L"VT_ARRAY";
        case VT_BYREF: return L"VT_BYREF";
        default:
            ss << L"<Unsupported Type> (" << v->vt << L")";
            return ss.str();
    }
}

int WINAPI CustomHook(
    VARIANTARG* vPrompt,
    unsigned int Buttons,
    VARIANTARG* vTitle,
    VARIANTARG* vHelpFile,
    VARIANTARG* vContext)
{
    
    std::wstring promptStr = VariantToString(vPrompt);

    std::wstring message = L"Hook triggered!\n" + promptStr;

    MessageBoxW(NULL, message.c_str(), L"rtcMsgBox Hook", MB_OK);

    return 0;
}

// Hook installation logic
void ApplyHook() {
    HMODULE hModule = GetModuleHandleA("msvbvm60.dll");
    if (!hModule) {
        MessageBoxW(NULL, L"msvbvm60.dll not loaded!", L"Error", MB_ICONERROR);
        return;
    }

    BYTE* pFunc = (BYTE*)GetProcAddress(hModule, "rtcMsgBox");
    if (!pFunc) {
        MessageBoxW(NULL, L"Failed to find rtcMsgBox in msvbvm60.dll!", L"Error", MB_ICONERROR);
        return;
    }

    DWORD oldProtect;
    if (VirtualProtect(pFunc, 6, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        // Save original bytes
        memcpy(g_OriginalBytes, pFunc, 6);

        // Prepare hook bytes
        BYTE hookBytes[6];
        hookBytes[0] = 0x68; // PUSH instruction
        *((void**)&hookBytes[1]) = (void*)CustomHook; // Address of the hook function
        hookBytes[5] = 0xC3; // RET instruction

        memcpy(pFunc, hookBytes, 6);    // Apply the hook

        // Restore memory protection
        VirtualProtect(pFunc, 6, oldProtect, &oldProtect);

        MessageBoxW(NULL, L"rtcMsgBox hooked successfully!", L"Success", MB_OK);
    } else {
        MessageBoxW(NULL, L"Failed to modify rtcMsgBox!", L"Error", MB_ICONERROR);
    }
}

// Hook recovery logic
void RecoverHook() {
    HMODULE hModule = GetModuleHandleA("msvbvm60.dll");
    if (!hModule) return;

    BYTE* pFunc = (BYTE*)GetProcAddress(hModule, "rtcMsgBox");
    if (!pFunc) return;

    DWORD oldProtect;
    if (VirtualProtect(pFunc, 6, PAGE_EXECUTE_READWRITE, &oldProtect)) {
        // Restore original bytes
        memcpy(pFunc, g_OriginalBytes, 6);

        // Restore memory protection
        VirtualProtect(pFunc, 6, oldProtect, &oldProtect);

        MessageBoxW(NULL, L"rtcMsgBox restored successfully!", L"Success", MB_OK);
    }
}

// DLL Main function
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
        ApplyHook();
    } else if (ul_reason_for_call == DLL_PROCESS_DETACH) {
        RecoverHook();
    }
    return TRUE;
}

type reference (convert dec to hex before decode)

enum VARENUM
    {
        VT_EMPTY	= 0,
        VT_NULL	= 1,
        VT_I2	= 2,
        VT_I4	= 3,
        VT_R4	= 4,
        VT_R8	= 5,
        VT_CY	= 6,
        VT_DATE	= 7,
        VT_BSTR	= 8,
        VT_DISPATCH	= 9,
        VT_ERROR	= 10,
        VT_BOOL	= 11,
        VT_VARIANT	= 12,
        VT_UNKNOWN	= 13,
        VT_DECIMAL	= 14,
        VT_I1	= 16,
        VT_UI1	= 17,
        VT_UI2	= 18,
        VT_UI4	= 19,
        VT_I8	= 20,
        VT_UI8	= 21,
        VT_INT	= 22,
        VT_UINT	= 23,
        VT_VOID	= 24,
        VT_HRESULT	= 25,
        VT_PTR	= 26,
        VT_SAFEARRAY	= 27,
        VT_CARRAY	= 28,
        VT_USERDEFINED	= 29,
        VT_LPSTR	= 30,
        VT_LPWSTR	= 31,
        VT_RECORD	= 36,
        VT_INT_PTR	= 37,
        VT_UINT_PTR	= 38,
        VT_FILETIME	= 64,
        VT_BLOB	= 65,
        VT_STREAM	= 66,
        VT_STORAGE	= 67,
        VT_STREAMED_OBJECT	= 68,
        VT_STORED_OBJECT	= 69,
        VT_BLOB_OBJECT	= 70,
        VT_CF	= 71,
        VT_CLSID	= 72,
        VT_VERSIONED_STREAM	= 73,
        VT_BSTR_BLOB	= 0xfff,
        VT_VECTOR	= 0x1000,
        VT_ARRAY	= 0x2000,
        VT_BYREF	= 0x4000,
        VT_RESERVED	= 0x8000,
        VT_ILLEGAL	= 0xffff,
        VT_ILLEGALMASKED	= 0xfff,
        VT_TYPEMASK	= 0xfff
    } ;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment