winapi — C ++ Port Monitor (mfilemon.dll) Код RDP Virtual Channel не выполняется

Недавно я начал работать с открытым исходным кодом mfilemon.dll и пытался добавить к нему дополнительные функции.

Функция, которую я добавляю, заключается в передаче данных по виртуальному каналу. Я написал небольшой консольный exe-файл для проверки кода и то, что у меня ниже, успешно отправляет данные (я получаю всплывающее сообщение на другой стороне).

Когда этот код помещается в mfilemon.dll, ничего не происходит. Все остальные функции DLL работают как обычно, но этот код просто не выполняется. Я думаю, что служба Spooler наряду с чем-то в 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 знает, как загрузить этот плагин.

Если кто-то знаком с мониторами портов и выполнением кода, который делает что-то кроме создания файла, это было бы здорово.

0

Решение

Spoolsv.exe является службой и, следовательно, работает в сеансе, который НЕ совпадает с сеансом, подключенным через RDP. Любые используемые библиотеки DLL и порожденные дочерние процессы также являются частью этого сеанса.

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

(DWORD)-1 должен быть изменен на фактический сеанс, который подключен через RDP.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]