我正在开发rdp虚拟 channel 应用程序。我已经在注册表中注册了客户端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 session 出现在屏幕上时:
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 - 0x00000004pVirtualChannelOpen - 0x0000ffffpVirtualChannelClose - 0x000000b8pVirtualChannelWrite - 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
}
最佳答案
pVirtualChannelInit
应该是有效的指针(指向代码)。 0x00000004
不是,因此access violation
您的问题可能是由编译时不正确的结构打包/对齐引起的。
通过检查传递给PCHANNEL_ENTRY_POINTS pEntryPoints
实现的VirtualChannelEntry
参数指向的内存,使用调试器找出正确的对齐方式。该结构以2个 32位值开头,后跟4个函数指针。第一个字段是大小字段(值取决于位,32位:0x0018或64:0x0028),第二个字段应为0x00001。
然后,在定义#pragma pack push/pop
结构的 header 周围使用CHANNEL_ENTRY_POINTS
(MSVC编译器),以在编译时强制正确对齐。