VirtualChannelInit卡住了。

3
我正在开发一个rdp虚拟通道应用程序。我已经在注册表中注册了客户端侧的dll,并试图理解客户端dll何时被加载。
但是,当调用

pEntryPoints中的pVirtualChannelInit时,我卡住了。 它根本没有返回任何结果,调试器进入了这个函数的反汇编代码。但是如果不停止在此调用上,VirtualChannelEntry会第二次被调用(为什么?)。

如果我使用调试器调试mstsc.exe。 在第一次调用后一段时间,控制台会显示以下内容: mstsc.exe中0x00000004处的第一次机会异常:0xC0000005:在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(为什么是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
}

我的回答有帮助吗? - manuell
谢谢你的回答,我会尽快检查它。 - Dimson
有什么新消息吗?我目前正在做虚拟通道的事情,我可以帮忙 :-) - manuell
1个回答

3

pVirtualChannelInit 应该是一个有效的指针(指向代码)。0x00000004 不是,因此出现了 access violation

你的问题可能是由于编译时结构体打包/对齐不当引起的。

使用调试器检查由传递给你的 VirtualChannelEntry 实现的 PCHANNEL_ENTRY_POINTS pEntryPoints 参数所指向的内存,以找出正确的对齐方式。该结构以 2 个32位值开头,后跟 4 个函数指针。第一个字段是大小字段(值取决于位数,32位:0x0018,或64位:0x0028),第二个字段应为 0x00001。

然后,在包含定义 CHANNEL_ENTRY_POINTS 结构的头文件周围使用 #pragma pack push/pop(MSVC 编译器)来强制在编译时使用正确的对齐方式。


非常感谢,#pragma pack 在 Cchannel.h 中解决了它。 - Dimson
@Dimson 没问题。如果你有其他问题,在这里评论中提醒我。祝编程愉快! - manuell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接