VirtualChannelInit卡住了

时间:2016-03-22 20:37:42

标签: c++ windows rdp virtual-channel

我正在开发一个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. //用谷歌翻译 在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 个答案:

答案 0 :(得分:2)

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结构的标头,以在编译时强制正确对齐。