[utils] improve rdpdr packet dump

This commit is contained in:
Armin Novak 2022-12-22 12:04:13 +01:00 committed by David Fort
parent 833a1b2d24
commit 37454c7420
4 changed files with 167 additions and 88 deletions

View File

@ -1502,7 +1502,7 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
if (!rdpdr || !s)
return CHANNEL_RC_NULL_DATA;
rdpdr_dump_received_packet(s, "rdpdr-channel");
rdpdr_dump_received_packet(rdpdr->log, WLOG_TRACE, s, "[rdpdr-channel] receive");
if (Stream_GetRemainingLength(s) >= 4)
{
Stream_Read_UINT16(s, component); /* Component (2 bytes) */
@ -1650,7 +1650,7 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
else
{
const size_t pos = Stream_GetPosition(s);
rdpdr_dump_send_packet(s, "rdpdr-channel");
rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, "[rdpdr-channel] send");
status = plugin->channelEntryPoints.pVirtualChannelWriteEx(
plugin->InitHandle, plugin->OpenHandle, Stream_Buffer(s), pos, s);
}

View File

@ -35,7 +35,7 @@ FREERDP_API const char* scard_get_ioctl_string(UINT32 ioControlCode, BOOL funcNa
FREERDP_API BOOL rdpdr_write_iocompletion_header(wStream* out, UINT32 DeviceId, UINT32 CompletionId,
UINT32 ioStatus);
FREERDP_API void rdpdr_dump_received_packet(wStream* out, const char* custom);
FREERDP_API void rdpdr_dump_send_packet(wStream* out, const char* custom);
FREERDP_API void rdpdr_dump_received_packet(wLog* log, DWORD lvl, wStream* out, const char* custom);
FREERDP_API void rdpdr_dump_send_packet(wLog* log, DWORD lvl, wStream* out, const char* custom);
#endif

View File

@ -268,102 +268,180 @@ BOOL rdpdr_write_iocompletion_header(wStream* out, UINT32 DeviceId, UINT32 Compl
return TRUE;
}
void rdpdr_dump_received_packet(wStream* s, const char* custom)
static void rdpdr_dump_packet(wLog* log, DWORD lvl, wStream* s, const char* custom, BOOL send)
{
if (!WLog_IsLevelActive(log, lvl))
return;
const size_t gpos = Stream_GetPosition(s);
const size_t pos = send ? Stream_GetPosition(s) : Stream_Length(s);
UINT16 component = 0, packetid = 0;
Stream_SetPosition(s, 0);
if (Stream_Length(s) >= 4)
{
BOOL done = FALSE;
UINT16 component, packetid;
UINT32 deviceID = 0;
UINT32 FileId = 0;
UINT32 CompletionId = 0;
UINT32 MajorFunction = 0;
UINT32 MinorFunction = 0;
const size_t pos = Stream_GetPosition(s);
wLog* log = WLog_Get(TAG);
if (pos >= 2)
Stream_Read_UINT16(s, component);
if (pos >= 4)
Stream_Read_UINT16(s, packetid);
if (Stream_GetRemainingLength(s) >= 4)
Stream_Read_UINT32(s, deviceID);
if (component == RDPDR_CTYP_CORE)
{
if (packetid == PAKID_CORE_DEVICE_IOREQUEST)
{
if (Stream_GetRemainingLength(s) >= 16)
{
Stream_Read_UINT32(s, FileId); /* FileId (4 bytes) */
Stream_Read_UINT32(s, CompletionId); /* CompletionId (4 bytes) */
Stream_Read_UINT32(s, MajorFunction); /* MajorFunction (4 bytes) */
Stream_Read_UINT32(s, MinorFunction); /* MinorFunction (4 bytes) */
WLog_Print(log, WLOG_DEBUG,
"[%s] receive [%s | %s] [0x%08" PRIx32 "] FileID=0x%08" PRIx32
", CompletionID=0x%08" PRIx32 ", MajorFunction=%s [0x%08" PRIx32
"] -> %" PRIuz,
custom, rdpdr_component_string(component),
rdpdr_packetid_string(packetid), deviceID, FileId, CompletionId,
rdpdr_irp_string(MajorFunction), MinorFunction, deviceID,
Stream_Length(s));
done = TRUE;
}
switch (packetid)
{
case PAKID_CORE_SERVER_ANNOUNCE:
case PAKID_CORE_CLIENTID_CONFIRM:
{
UINT16 versionMajor = 0, versionMinor = 0;
UINT32 clientID = 0;
if (pos >= 6)
Stream_Read_UINT16(s, versionMajor);
if (pos >= 8)
Stream_Read_UINT16(s, versionMinor);
if (pos >= 12)
Stream_Read_UINT32(s, clientID);
WLog_Print(log, lvl,
"%s [%s | %s] [version:%" PRIu16 ".%" PRIu16 "][id:0x%08" PRIx32
"] -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
versionMajor, versionMinor, clientID, pos);
}
break;
case PAKID_CORE_CLIENT_NAME:
{
char name[256] = { 0 };
UINT32 unicodeFlag = 0;
UINT32 codePage = 0;
UINT32 computerNameLen = 0;
if (pos >= 8)
Stream_Read_UINT32(s, unicodeFlag);
if (pos >= 12)
Stream_Read_UINT32(s, codePage);
if (pos >= 16)
Stream_Read_UINT32(s, computerNameLen);
if (pos >= 16 + computerNameLen)
{
if (unicodeFlag == 0)
Stream_Read(s, name, MIN(sizeof(name), computerNameLen));
else
ConvertWCharNToUtf8((const WCHAR*)Stream_Pointer(s),
computerNameLen / sizeof(WCHAR), name, sizeof(name));
}
WLog_Print(log, lvl,
"%s [%s | %s] [ucs:%" PRIu32 "|cp:%" PRIu32 "][len:0x%08" PRIx32
"] '%s' -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
unicodeFlag, codePage, computerNameLen, name, pos);
}
break;
case PAKID_CORE_DEVICE_IOREQUEST:
{
UINT32 CompletionId = 0;
UINT32 deviceID = 0, FileId = 0, MajorFunction = 0, MinorFunction = 0;
if (pos >= 8)
Stream_Read_UINT32(s, deviceID);
if (pos >= 12)
Stream_Read_UINT32(s, FileId);
if (pos >= 16)
Stream_Read_UINT32(s, CompletionId);
if (pos >= 20)
Stream_Read_UINT32(s, MajorFunction);
if (pos >= 24)
Stream_Read_UINT32(s, MinorFunction);
WLog_Print(log, lvl,
"%s [%s | %s] [0x%08" PRIx32 "] FileId=0x%08" PRIx32
", CompletionId=0x%08" PRIx32 ", MajorFunction=0x%08" PRIx32
", MinorFunction=0x%08" PRIx32 " -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, FileId, CompletionId, MajorFunction, MinorFunction, pos);
}
break;
case PAKID_CORE_DEVICE_IOCOMPLETION:
{
UINT32 completionID = 0, ioStatus = 0;
UINT32 deviceID = 0;
if (pos >= 8)
Stream_Read_UINT32(s, deviceID);
if (pos >= 12)
Stream_Read_UINT32(s, completionID);
if (pos >= 16)
Stream_Read_UINT32(s, ioStatus);
WLog_Print(log, lvl,
"%s [%s | %s] [0x%08" PRIx32 "] completionID=0x%08" PRIx32
", ioStatus=0x%08" PRIx32 " -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, completionID, ioStatus, pos);
}
break;
case PAKID_CORE_DEVICE_REPLY:
{
UINT32 deviceID = 0, status = 0;
if (pos >= 8)
Stream_Read_UINT32(s, deviceID);
if (pos >= 12)
Stream_Read_UINT32(s, status);
WLog_Print(log, lvl,
"%s [%s | %s] [id:0x%08" PRIx32 ",status=0x%08" PRIx32 "] -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, status, pos);
}
break;
case PAKID_CORE_CLIENT_CAPABILITY:
case PAKID_CORE_SERVER_CAPABILITY:
{
UINT16 numCapabilities = 0;
if (pos >= 6)
Stream_Read_UINT16(s, numCapabilities);
if (pos >= 8)
Stream_Seek_UINT16(s); /* padding */
WLog_Print(log, lvl, "%s [%s | %s] [caps:%" PRIu16 "] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid),
numCapabilities, pos);
}
break;
case PAKID_CORE_DEVICELIST_ANNOUNCE:
case PAKID_CORE_DEVICELIST_REMOVE:
{
{
UINT32 count = 0;
if (pos >= 8)
Stream_Read_UINT32(s, count);
WLog_Print(log, lvl, "%s [%s | %s] [%" PRIu32 "] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid),
count, pos);
if (count > 0)
WLog_WARN(TAG, "xxx");
}
}
Stream_SetPosition(s, pos);
if (!done)
break;
case PAKID_CORE_USER_LOGGEDON:
WLog_Print(log, lvl, "%s [%s | %s] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid), pos);
break;
default:
{
WLog_Print(log, WLOG_DEBUG, "[%s] receive [%s | %s] [0x%08" PRIx32 "] -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, Stream_Length(s));
WLog_Print(log, lvl, "%s [%s | %s] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid), pos);
}
winpr_HexLogDump(log, WLOG_TRACE, Stream_Buffer(s), Stream_Length(s));
break;
}
// winpr_HexLogDump(log, lvl, Stream_Buffer(s), pos);
Stream_SetPosition(s, gpos);
}
void rdpdr_dump_send_packet(wStream* s, const char* custom)
void rdpdr_dump_received_packet(wLog* log, DWORD lvl, wStream* s, const char* custom)
{
WINPR_ASSERT(s);
rdpdr_dump_packet(log, lvl, s, custom, FALSE);
}
if (Stream_Length(s) >= 8)
{
UINT16 component, packetid;
UINT32 deviceID;
const size_t pos = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
Stream_Read_UINT16(s, component);
Stream_Read_UINT16(s, packetid);
Stream_Read_UINT32(s, deviceID);
switch (packetid)
{
case PAKID_CORE_DEVICE_IOCOMPLETION:
{
UINT32 completionID, ioStatus;
Stream_Read_UINT32(s, completionID);
Stream_Read_UINT32(s, ioStatus);
WLog_DBG(TAG,
"[%s] sending [%s | %s] [0x%08" PRIx32 "] completionID=0x%08" PRIx32
", ioStatus=0x%08" PRIx32 " -> %" PRIuz,
custom, rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, completionID, ioStatus, pos);
}
break;
default:
WLog_DBG(TAG, "[%s] sending [%s | %s] [0x%08" PRIx32 "] -> %" PRIuz, custom,
rdpdr_component_string(component), rdpdr_packetid_string(packetid),
deviceID, pos);
break;
}
winpr_HexDump(TAG, WLOG_TRACE, Stream_Buffer(s), pos);
Stream_SetPosition(s, pos);
}
void rdpdr_dump_send_packet(wLog* log, DWORD lvl, wStream* s, const char* custom)
{
rdpdr_dump_packet(log, lvl, s, custom, TRUE);
}
const char* rdpdr_irp_string(UINT32 major)

View File

@ -176,7 +176,7 @@ static UINT rdpdr_client_send(pClientContext* pc, wStream* s)
return ERROR_INTERNAL_ERROR;
Stream_SealLength(s);
rdpdr_dump_send_packet(s, "proxy-client");
rdpdr_dump_send_packet(WLog_Get(TAG), WLOG_TRACE, s, "proxy-client");
WINPR_ASSERT(pc->context.instance->SendChannelData);
if (!pc->context.instance->SendChannelData(pc->context.instance, channelId, Stream_Buffer(s),
Stream_Length(s)))
@ -1072,11 +1072,12 @@ BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context*
if (!s)
continue;
Stream_SetPosition(s, Stream_Length(s));
rdpdr_dump_send_packet(s, "proxy-client-queue");
const size_t len = Stream_Length(s);
Stream_SetPosition(s, len);
rdpdr_dump_send_packet(WLog_Get(TAG), WLOG_TRACE, s, "proxy-client-queue");
WINPR_ASSERT(pc->context.instance->SendChannelData);
if (!pc->context.instance->SendChannelData(pc->context.instance, channelId,
Stream_Buffer(s), Stream_Length(s)))
Stream_Buffer(s), len))
{
WLog_WARN(TAG, "xxxxxx TODO: Failed to send data!");
}
@ -1152,7 +1153,7 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const
return FALSE;
}
rdpdr_dump_received_packet(s, "proxy-client");
rdpdr_dump_received_packet(WLog_Get(TAG), WLOG_TRACE, s, "proxy-client");
switch (rdpdr->state)
{
case STATE_CLIENT_EXPECT_SERVER_ANNOUNCE_REQUEST:
@ -1235,7 +1236,7 @@ BOOL pf_channel_rdpdr_client_handle(pClientContext* pc, UINT16 channelId, const
}
break;
#else
return pf_channel_rdpdr_client_send_to_server(rdpdr, ps, s);
return pf_channel_rdpdr_client_send_to_server(ps, s);
#endif
default:
WLog_ERR(TAG,