c++内存执行脚本语言

好久没写博客了,抓住四月的小尾巴,分享一篇利用c++提供的com接口,来执行各种脚本语言

直接上代码,下面demo使用vs2019编译,功能是通过c++执行vbscript脚本,创建进程:

#include <iostream>
#include <windows.h>
#include <objbase.h>
#include <activscp.h>


using namespace std;

HRESULT getEngineGuid(LPCTSTR extension, GUID* guidBuffer)
{
    wchar_t   buffer[100];
    HKEY      hk;
    DWORD     size;
    HKEY      subKey;
    DWORD     type;

    // See if this file extension is associated
    // with an ActiveX script engine
    if (!RegOpenKeyEx(HKEY_CLASSES_ROOT, extension, 0,
        KEY_QUERY_VALUE | KEY_READ, &hk))
    {
        type = REG_SZ;
        size = sizeof(buffer);
        size = RegQueryValueEx(hk, 0, 0, &type,
            (LPBYTE)&buffer[0], &size);
        RegCloseKey(hk);
        if (!size)
        {
            // The engine set an association.
            // We got the Language string in buffer[]. Now
            // we can use it to look up the engine's GUID

            // Open HKEY_CLASSES_ROOT\{LanguageName}
        again:   size = sizeof(buffer);
            if (!RegOpenKeyEx(HKEY_CLASSES_ROOT, (LPCTSTR)&buffer[0], 0,
                KEY_QUERY_VALUE | KEY_READ, &hk))
            {
                // Read the GUID (in string format)
                // into buffer[] by querying the value of CLSID
                if (!RegOpenKeyExA(hk, "CLSID", 0,
                    KEY_QUERY_VALUE | KEY_READ, &subKey))
                {
                    size = RegQueryValueExW(subKey, 0, 0, &type,
                        (LPBYTE)&buffer[0], &size);
                    RegCloseKey(subKey);
                }
                else if (extension)
                {
                    // If an error, see if we have a "ScriptEngine"
                    // key under here that contains
                    // the real language name
                    if (!RegOpenKeyExA(hk, "ScriptEngine", 0,
                        KEY_QUERY_VALUE | KEY_READ, &subKey))
                    {
                        size = RegQueryValueEx(subKey, 0, 0, &type,
                            (LPBYTE)&buffer[0], &size);
                        RegCloseKey(subKey);
                        if (!size)
                        {
                            RegCloseKey(hk);
                            extension = 0;
                            goto again;
                        }
                    }
                }
            }

            RegCloseKey(hk);

            if (!size)
            {
                // Convert the GUID string to a GUID
                // and put it in caller's guidBuffer
                if ((size = CLSIDFromString(&buffer[0], guidBuffer)))
                    MessageBoxA(0, "Can't convert engine GUID",
                        "Error", MB_OK | MB_ICONEXCLAMATION);
                return(size);
            }
        }
    }

    MessageBoxA(0, "Can't get engine GUID from registry",
        "Error", MB_OK | MB_ICONEXCLAMATION);
    return(E_FAIL);
}

class CMyActiveScriptSite : public IActiveScriptSite
{
public:
    HRESULT STDMETHODCALLTYPE GetLCID(__RPC__out LCID* plcid) 
    {
        return S_OK;
    }


    HRESULT STDMETHODCALLTYPE GetItemInfo(
        /* [in] */ __RPC__in LPCOLESTR pstrName,
        /* [in] */ DWORD dwReturnMask,
        /* [out] */ __RPC__deref_out_opt IUnknown** ppiunkItem,
        /* [out] */ __RPC__deref_out_opt ITypeInfo** ppti)
    {
        return S_OK;
    }

     HRESULT STDMETHODCALLTYPE GetDocVersionString(
        /* [out] */ __RPC__deref_out_opt BSTR* pbstrVersion)
     {
         return S_OK;
     }

     HRESULT STDMETHODCALLTYPE OnScriptTerminate(
        /* [in] */ __RPC__in const VARIANT* pvarResult,
        /* [in] */ __RPC__in const EXCEPINFO* pexcepinfo)
     {
         return S_OK;
     }

     HRESULT STDMETHODCALLTYPE OnStateChange(
        /* [in] */ SCRIPTSTATE ssScriptState)
     {
         return S_OK;
     }

     HRESULT STDMETHODCALLTYPE OnScriptError(
        /* [in] */ __RPC__in_opt IActiveScriptError* pscripterror)
     {
         return S_OK;
     }

     HRESULT STDMETHODCALLTYPE OnEnterScript(void)
     {
         return S_OK;
     }

     HRESULT STDMETHODCALLTYPE OnLeaveScript(void)
     {
         return S_OK;
     }
     
      HRESULT STDMETHODCALLTYPE QueryInterface(
         /* [in] */ REFIID riid,
         /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject)
     {
          if (riid == IID_IActiveScriptSite || (riid == IID_IUnknown))
          {
              *ppvObject = this;
              AddRef();
              return S_OK;
          }

          *ppvObject = NULL;
          return E_NOINTERFACE;
     }

      ULONG STDMETHODCALLTYPE AddRef(void)
     {
         return S_OK;
     }

      ULONG STDMETHODCALLTYPE Release(void)
     {
         return S_OK;
     }

};
int main()
{
    GUID guidBuffer = { 0 };
    IActiveScript* activeScript = NULL;
    IActiveScriptParse* activeScriptParse = NULL;
    CMyActiveScriptSite MyActiveScriptSite;
    wchar_t VBscript[] = L"Set Sh = CreateObject(\"WScript.Shell\")\r\n\
        Sh.Run \"calc.exe\", 0";

    do
    {
        HRESULT res = getEngineGuid(L".vbs", &guidBuffer);
        if (res != ERROR_SUCCESS)
        {
            break;
        }
        res = CoInitialize(0);
        res = CoCreateInstance(guidBuffer, 0, CLSCTX_ALL, (const IID)IID_IActiveScript, (void**)&activeScript);
        if (res != ERROR_SUCCESS)
        {
            break;
        }

        res = activeScript->QueryInterface(IID_IActiveScriptParse,(void**)&activeScriptParse);
        if (res != ERROR_SUCCESS)
        {
            break;
        }

        res = activeScriptParse->InitNew();
        if (res != ERROR_SUCCESS)
        {
            break;
        }

        res = activeScript->SetScriptSite((IActiveScriptSite*)&MyActiveScriptSite);
        if (res != ERROR_SUCCESS)
        {
            break;
        }

        res = activeScriptParse->ParseScriptText(&VBscript[0],0,0,0,0,0,0,0,0);
        if (res != ERROR_SUCCESS)
        {
            break;
        }

        res = activeScript->SetScriptState(SCRIPTSTATE_CONNECTED);
        if (res != ERROR_SUCCESS)
        {
            break;
        }

        res = activeScript->Close();
        if (res != ERROR_SUCCESS)
        {
            break;
        }
        activeScript->Release();
        activeScriptParse->Release();



        CoUninitialize();
    } while (0);


    std::cout << "Hello World!\n";
}


参考资料:
https://www.codeproject.com/Articles/14905/COM-in-plain-C-Part-6
https://modexp.wordpress.com/2019/07/21/inmem-exec-script/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值