Calling SendIpcMessage() from injected DLL's init code?
Calling SendIpcMessage() from injected DLL's init code?
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.
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.
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.
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:
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;
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.
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.
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...
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...