代码之家  ›  专栏  ›  技术社区  ›  David Bentley

C++端口监视器(mfilemon.dll)RDP虚拟通道代码未执行

  •  0
  • David Bentley  · 技术社区  · 6 年前

    我最近开始使用开源mfilemon。并尝试向其添加其他功能。

    我添加的功能是通过虚拟通道传输数据。我编写了一个小型控制台exe来测试代码,下面的内容成功地发送了数据(我在另一侧得到一条弹出消息)。

    当此代码放入mfilemon时。dll,什么都没有发生。DLL的所有其他函数都像普通函数一样工作,但这段代码就是不执行。我认为后台处理程序服务和windows中的某些东西正在阻止某些API调用,但如果能确定这一点,那就好了。

    下面是我编写的exe的代码,它成功地通过我的虚拟通道发送数据(我的项目是目标Win8.1,因此我必须添加 legacy_stdio_definitions.lib 链接器输入文件)。

    #include "stdafx.h"
    #include "conio.h"
    #include "iostream"
    struct IUnknown; // Workaround for "combaseapi.h(229): error C2187: syntax error: 'identifier' was unexpected here" when using /permissive-
    #include "windows.h"
    #include "WtsApi32.h"
    #pragma comment(lib, "wtsapi32.lib")
    
    int main()
    {
        std::cout << "Testing";
    
        const char* data = "You just printed data!";
    
        HANDLE mHandle;
        mHandle = WTSVirtualChannelOpen(NULL, (DWORD)-1, (LPSTR)"PRINTWP");
        PULONG written = 0;
        bool ret = WTSVirtualChannelWrite(mHandle, (PCHAR)data, 22, written);
    
        if (!ret || written == (PULONG)13)
        {
    
        }
        else
        {
    
        }
    
        ret = WTSVirtualChannelClose(mHandle);
    
        _getch();
        return 0;
    }
    

    这是我的虚拟通道DLL代码。

    #include "stdafx.h"
    #include <windows.h>
    #include <stdlib.h>
    #include <Shellapi.h>
    #include <Cchannel.h> // Contains the definition for PCHANNEL_ENTRY_POINTS
    #include <string.h>
    #include <winspool.h>
    #include <fstream>
    #include <iostream>
    
    PCHANNEL_ENTRY_POINTS gpEntryPoints;
    LPHANDLE gphChannel;
    void VCAPITYPE VirtualChannelInitEventProc(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength);
    
    void VCAPITYPE VirtualChannelOpenEvent_PRINTWP(DWORD openHandle, UINT event, LPVOID pdata, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags);
    DWORD gdwOpenChannel_PRINTWP;
    const char* channel_PRINTWP = "PRINTWP";
    
    BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
    {
        MessageBox(NULL, TEXT("RDP Virtual channel DLL Loaded."), TEXT("Hosted Channel"), MB_OK);
    
        gpEntryPoints = (PCHANNEL_ENTRY_POINTS)LocalAlloc(LPTR, pEntryPoints->cbSize);
        CopyMemory(gpEntryPoints, pEntryPoints, pEntryPoints->cbSize);
    
        UINT rc_channel;
        CHANNEL_DEF channel_def[1]; // This is where you can increase the number of registered virtual channels assuming you define them later.
    
        ZeroMemory(&channel_def[0], sizeof(CHANNEL_DEF));
        CopyMemory(channel_def[0].name, channel_PRINTWP, strlen(channel_PRINTWP));
    
        rc_channel = gpEntryPoints->pVirtualChannelInit((LPVOID *)&gphChannel, channel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, (PCHANNEL_INIT_EVENT_FN)VirtualChannelInitEventProc);
    
        if (rc_channel != CHANNEL_RC_OK)
        {
            MessageBox(NULL, TEXT("RDP Virtual Channel registration has failed!"),TEXT("Channel Message"), MB_OK);
            return FALSE;
        }
    
        if (channel_def[0].options != CHANNEL_OPTION_INITIALIZED)
        {
            MessageBox(NULL, TEXT("RDP Virtual Channel options initialization failure!"), TEXT("Channel Message"), MB_OK);
            return FALSE;
        }
    
        MessageBox(NULL, TEXT("RDP Virtual Channel initialized."), TEXT("Channel Message"), MB_OK);
        return TRUE;
    }
    
    void VCAPITYPE VirtualChannelInitEventProc(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
    {
        UINT rc_channel_HLINK;
        UINT rc_channel_PREVIEW;
        UINT rc_channel_PRINTWP;
    
        switch (event)
        {
        case CHANNEL_EVENT_INITIALIZED:
            break;
        case CHANNEL_EVENT_CONNECTED:
    
            rc_channel_PRINTWP = gpEntryPoints->pVirtualChannelOpen(gphChannel, &gdwOpenChannel_PRINTWP, (PCHAR)channel_PRINTWP, (PCHANNEL_OPEN_EVENT_FN)VirtualChannelOpenEvent_PRINTWP);
    
            if (rc_channel_PRINTWP != CHANNEL_RC_OK)
            {
                MessageBox(NULL, TEXT("Open of RDP virtual channel failed"), TEXT("Channel Message"), MB_OK);
            }
            else
            {
                MessageBox(NULL, TEXT("Open of RDP virtual channel success"), TEXT("Channel Message"), MB_OK);
            }
    
            break;
    
        case CHANNEL_EVENT_V1_CONNECTED:
            MessageBox(NULL, TEXT("Connecting to a non Windows 2000 Terminal Server"), TEXT("Channel Message"), MB_OK);
            break;
    
        case CHANNEL_EVENT_DISCONNECTED:
            break;
    
        case CHANNEL_EVENT_TERMINATED:
            LocalFree((HLOCAL)gpEntryPoints);
            break;
    
        default:
            break;
        }
    }
    
    void VCAPITYPE VirtualChannelOpenEvent_PRINTWP(DWORD openHandle, UINT event, LPVOID pdata, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
    {
        switch (event)
        {
        case CHANNEL_EVENT_DATA_RECEIVED:
    
            MessageBox(NULL, TEXT("Data received."), TEXT("Channel Message"), MB_OK);
    
            char* data;
            data = (char*)malloc(dataLength + 1);
            CopyMemory(data, pdata, dataLength);
            data[dataLength] = '\0';
    
            MessageBoxA(NULL, data, "PRINTWP", MB_OK);
    
            free(data);
    
            break;
    
        default:
            break;
        }
    }
    

    def文件:

    LIBRARY FrzHostedChannel
    EXPORTS
    VirtualChannelEntry
    

    dllmain公司:

    #include "stdafx.h"
    

    使用上述代码需要更改注册表,以便mstsc。exe知道加载此插件。

    如果有人熟悉端口监视器和执行除创建文件以外的其他操作的代码,那就太棒了。

    1 回复  |  直到 6 年前
        1
  •  0
  •   David Bentley    6 年前

    滑阀SV。exe是一种服务,因此在与通过RDP连接的会话不同的会话中运行。使用的所有DLL和派生的子进程也是该会话的一部分。

    mHandle = WTSVirtualChannelOpen(NULL, (DWORD)-1, (LPSTR)"PRINTWP");
    

    这个 (DWORD)-1 需要更改为通过RDP连接的实际会话。

    推荐文章