Possible bug with IPC comms in BDS 2009 with UnicodeString

c++ / delphi package - dll injection and api hooking
Post Reply
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

Possible bug with IPC comms in BDS 2009 with UnicodeString

Post by mikec »

Hi all,

Just started to port my injection code over to BDS 2009. I use both aspects of BDS i.e. BCB and Delphi. I havent tried any injection stuff yet, I'm just looking at setting up the IPC comms.

I think i might have run into a bug with the SendIPCMessage / IPC callback when used with the BDS UnicodeString. I’m using a UnicodeString and the Length() method should return the size of the string contained in the UnicodeString object. Under tests, this returns 17 – which is correct for my packet based on the fact that the UnicodeString is twice the length of a the Ansi equiverlent. However, on the IPC callback side, using this value causes the packet to be truncated:

Code: Select all

// Client Send
int iIPCRtn = -1;
DWORD dwSessionId, dwProcessId;
dwProcessId = GetCurrentProcessId();
dwSessionId = ProcessIdToSessionId(dwProcessId, &dwSessionId);

UnicodeString wzPacket;

wzPacket.sprintf(IPC_PACKET_KEY_STATUS,
                       IPC_PROTOCOL_STARTER,
                       IPC_TYPE_KEY,
                       IPC_PROTOCOL_DELIMITER,
                       IPC_REQUEST_KEY_STATUS,
                       IPC_PROTOCOL_DELIMITER,
                       IPC_ACTION_QUERY_OBJECT,
                       IPC_PROTOCOL_DELIMITER,
                       dwSessionId,
                       IPC_PROTOCOL_DELIMITER,
                       dwProcessId,
                       IPC_PROTOCOL_TERMINATOR);
if ((SendIpcMessage(IPC_QUEUE_KEY_STATUS_NAME, wzPacket.c_str(), wzPacket.Length(), &iIPCRtn, sizeof(&iIPCRtn), SEND_IPC_TIMEOUT)) && (iIPCRtn >= -1))
{ 
   // do something…
} 

// Server Receive
void CALLBACK TKeyPollThrd::IPCKeyMsg(char *cName, void *pMsgBuf, unsigned int iMsgLen, void *pRtnBuf, unsigned int iRtnLen)
{
      EnterCriticalSection(&pThis->csKeyCritSect);
      try
      {
            UnicodeString wzMsg = UnicodeString((wchar_t*)pMsgBuf);
            wzMsg.SetLength(iMsgLen);
      }
      __finally
      {
            LeaveCriticalSection(&pThis->csKeyCritSect);
      }
}
- even though the packet size is correct at both the client and server side i.e. 17, assigning and / or setting the length of the UnicodeString to this causes the data to be corrupted. Even if I simply assign the data, without setting the size, it still gets corrupted. The only way I have found to over come this is by doubling the size that SendIPCMessage() reports the data as i.e.

Code: Select all

if ((SendIpcMessage(IPC_QUEUE_KEY_STATUS_NAME, 
                              wzPacket.c_str(), 
                              ([b]wzPacket.Length()*2)[/b],
                              &iIPCRtn, sizeof(&iIPCRtn), 
                              SEND_IPC_TIMEOUT)) && (iIPCRtn >= -1))

I have tried adding 1 or 2 to the Length() value just incase the terminator was being clipped of but it makes no difference.

Not quite sure if this is a bug or a problem with UnicodeString. Please advice if anyone else has seen this.

Mike C
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

Length() returns the number of elements in an array (WideChars in this case) - not the size in bytes.
Length(x) * sizeof(x[0]) is the size in bytes.
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

hmmm

Post by mikec »

Thanks Nico,

That certainly makes sense and it looks obvious when you present it like that. What you’re suggesting is that the value that is needed is the total size of the buffer - which based on what I have found seems to be correct i.e.

Length(wz) * sizeof(wchar_t)

however, the documentation for the IPC stuff says
function SendIpcMessage(ipc : pchar;
messageBuf : pointer;
messageLen : dword;
answerBuf : pointer = nil;
answerLen : dword = 0;
answerTimeOut : dword = INFINITE;
handleMessages : bool = true ) : bool; stdcall;
- this is possibly where the confusion is happening - MessageLen suggestions the length of the message, not the size of the message buffer.

Anyway, problem seems to be solved and it is clearer now.

Many thanks

Mike C
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

In many APIs "Length" and "Size" are used for the same purpose.
However, because messageBuf isn’t typed, a "size in bytes" interpretation for messageLen makes sense.
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Nico is right, of course.

The IPC functions were written with binary data in mind. Of course you can send Unicode strings, if you want, but to the IPC functions you are sending a simple buffer filled with some bytes. Because of that the "len/size" field of course calculates in bytes and not in words.
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

Ashamed

Post by mikec »

:sorry:

Yes, I hold my head in shame. It seems so obvious now but at the time I was in Unicode hell and nothing was making sense to me.

I will sulk of now. :wink:

Mike C
Post Reply