Calling SendIpcMessage() from injected DLL's init code?

c++ / delphi package - dll injection and api hooking
Post Reply
sklein
Posts: 19
Joined: Sat Apr 23, 2005 6:08 pm

Calling SendIpcMessage() from injected DLL's init code?

Post by sklein »

I have a program that calls CreateIpcQueue() and then InjectLibrary(). The injected DLL hooks a number of functions and successfully calls SendIpcMessage() when those functions are called. The messages sent are successfully received. That seems to work great.

However, I tried adding a SendIpcMessage() call to the DLL's init code to send which processes are being injected into back to the injecting program. This results in the injecting program hanging consistently for about 10 seconds after the injection. I timestamped the incoming IPC messages, and they are all received within 200 milliseconds of the injection, but the injecting program doesn't become responsive again for 10 more seconds. The injecting program is a single form with a listbox (to display the IPC messages) plus Inject/UnInject buttons.

If I remove the single SendIpcMessage() call from the DLL's init code, there is no hang/delay.

Any suggestions? Either how to resolve the 10 second "hang" (if I am doing something wrong), or an alternate mechanism to get notification back to the injecting program of all the processes that were injected/hooked.

Thanks in advance.
neji
Posts: 155
Joined: Wed Mar 09, 2005 11:39 am
Contact:

Post by neji »

i've also done that, but ive not made this experience....maybe you can show some code?

Code: Select all

var arrCh : array [0..MAX_PATH] of char;
begin
  GetModuleFileName(0, arrCh, MAX_PATH);
  SendIpcMessage('IPCname'', @arrCh, StrLen(arrCh) + 1);
end.
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

sklein, please show us your IPC callback function.
sklein
Posts: 19
Joined: Sat Apr 23, 2005 6:08 pm

Post by sklein »

I went to grab the callback code, but first I ran the test again. This time it worked, with no delay! If I had rebooted since running the tests yesterday, I would understand the situation, but I didn't reboot...

Since this problem originally didn't make any sense, I'm happy that it doesn't exist anymore. But I am concerned that it was there initially.

If anyone has any thoughts, please let me know.

For completeness, here's the callback:

Code: Select all

const
  IpcMsgSepr = #9;

Procedure Callback(qName: pchar; messageBuf: pointer; messageLen: dword;
                   answerBuf: pointer; answerLen: dword); stdcall;
var
  logMsg: String;
  t: SYSTEMTIME;

begin
  GetLocalTime(t);
  logMsg := Format('%4d%2.2d%2.2d %2.2d:%2.2d:%2.2d:%3.3d',
                   [t.wYear, t.wMonth, t.wDay,
                    t.wHour, t.wMinute, t.wSecond, t.wMilliseconds]) + '    '
              + AnsiReplaceStr(PChar(messageBuf), IpcMsgSepr, '    ');

  if Form1.chkWriteFile.Checked then
    WriteLn(logFile, logMsg)
  else
    Form1.lstLog.AddItem(logMsg, Form1);
end;
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Just to make sure: Are you using CreateIpcQueue or CreateIpcQueueEx? Your IPC callback function is not thread safe, as far as I can say. So you should really at least use CreateIpcQueueEx with "maxThreadCount = 1" to make sure that the callback function is only called by one and the same thread all the time.

Better would be, of course, to make the callback function thread safe. For that you want to synchronize access to the log file, e.g. by using a critical section. Don't know what lstLog is. Maybe you need to synchronize access to that, too.
sklein
Posts: 19
Joined: Sat Apr 23, 2005 6:08 pm

Post by sklein »

I have the test program setup for both CreateIpcQueue and CreateIpcQueueEx (a checkbox selects which one is used when I start injection). When there was a delay, it was the same no matter whether I chose single-threaded or multi-threaded. Now that there isn't a delay, the behavior is essentially the same whether multi-threaded or not --

for 27 processes injected:
multi-threaded injection = 484 ms.
single-threaded injection = 313 ms.

The lstLog object is a standard listbox (TListBox), which likely isn't thread-safe. I didn't run the experiments with file logging enabled.

Is it conceivable that the possible lack of thread-safety for TListBox could result in a delay? I would think either a crash or garbled output would be more likely...
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Depends on how the logging looks like inside, it could result in crashes, garbled output, delays and some other interesting effects.
Post Reply