VirtualChannelInit застревает

Я разрабатываю приложение виртуального канала RDP. Я зарегистрировал клиентскую DLL в реестре и пытаюсь понять, что клиентская DLL загружена. Но я застреваю при звонке pVirtualChannelInit от pEntryPoints, Он просто не возвращает никакого результата, отладчик переходит к дизассемблированному коду этой функции. Но если не останавливаться на этом вызове, VirtualChannelEntry звонили во второй раз (почему?).

Если я использую отладчик для mstsc.exe. Через некоторое время после первого звонка в консоли я вижу это:First-chance exception at 0x00000004 in mstsc.exe: 0xC0000005: an access violation in the performance at 0x00000004. // переведено с помощью Google и после второго вызова, когда на экране появляется rdp сессия:

First-chance exception at 0x773EC42D (KernelBase.dll) in mstsc.exe: 0x000006BA: RPC server is unavailable.
First-chance exception at 0x773EC42D (KernelBase.dll) in mstsc.exe: 0x000006BA: RPC server is unavailable.
First-chance exception at 0x773EC42D (KernelBase.dll) in mstsc.exe: 0x000006BA: RPC server is unavailable.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: unsigned long at memory location 0x06CCF8C0.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: unsigned long at memory location 0x06CCF8C0.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: unsigned long at memory location 0x06CCF8C0.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: unsigned long at memory location 0x06CCF8C0.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x773EC42D in mstsc.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.

Указатели в pEntryPoints всегда:

pVirtualChannelInit - 0x00000004 pVirtualChannelOpen - 0x0000ffff pVirtualChannelClose - 0x000000b8 pVirtualChannelWrite - 0x00000000 (Why 0?)

HANDLE ClientHandle = NULL;
CHANNEL_DEF pChannel[1];
CHANNEL_ENTRY_POINTS SavedEntryPoints;
PCHANNEL_INIT_EVENT_FN pChannelInitEventProc;

BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS  pEntryPoints)
{
    ofstream myfile;
    myfile.open ("D:\\Projects\\bench_cli\\ConsoleApplication1\\Release\\example.txt");
    myfile << "Writing this to a file.\n";

    UINT retval1 = 0;
    ZeroMemory(&pChannel[0], sizeof(CHANNEL_DEF));
    strcpy(pChannel[0].name, "Bench");
    pChannel[0].options = CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP;
    pChannelInitEventProc = VirtualChannelInitEvent;
    memcpy(&SavedEntryPoints, pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS));

    myfile << " copied" << endl;

    // call VirtualChannelInit using the function pointer in
    // PCHANNEL_ENTRY_POINTS
    myfile << "Initing" << endl;

    retval1 = pEntryPoints->pVirtualChannelInit (&ClientHandle,
                pChannel, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
                pChannelInitEventProc); //here we stuck

    myfile << " init" << endl; //this never printed
    myfile.close();

    return TRUE;
}

VOID VCAPITYPE VirtualChannelInitEvent( LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
{
...//never called
}

1 ответ

Решение

pVirtualChannelInit должен быть действительным указателем (на код). 0x00000004 нет, следовательно, access violation

Ваша проблема может быть вызвана неправильной упаковкой / выравниванием структуры во время компиляции.

Используйте отладчик, чтобы выяснить правильное выравнивание, проверяя память, указанную PCHANNEL_ENTRY_POINTS pEntryPoints параметр передан вашему VirtualChannelEntry реализация. Структура начинается с 2 32-битных значений, за которыми следуют 4 функциональных указателя. Первое поле является полем размера (значение зависит от битности, 32 бита:0x0018 или 64:0x0028), второе должно быть 0x00001.

Затем используйте #pragma pack push/pop (Компилятор MSVC) вокруг включения заголовка, определяющего CHANNEL_ENTRY_POINTS структура для принудительного выравнивания во время компиляции.

Другие вопросы по тегам