Fastest way to IPC from a DLL to an EXE

c++ / delphi package - dll injection and api hooking
abalonge
Posts: 11
Joined: Tue Jun 26, 2012 10:14 pm

Fastest way to IPC from a DLL to an EXE

Post by abalonge »

I have an EXE that I have written in Delphi which calls a DLL which I have also written in Delphi. This DLL is also loaded by an interpreted language which can not use pointers or addresses (ie, can not pass the address of a function or assign a pointer to a variable) in it's script language. When this interpreted language calls a function in my DLL I want to notify my EXE (IL -> DLL -> EXE). In tests I have it working with Windows IPC SendMessage and also with madCodeHook SendIpcMessage...from my DLL to my EXE. I am wanting the fastest execution method, no payload aside from an integer and do not need replies.
I am looking to see if I can do it in a faster way then those because many notification per second are needed. I know a callback, that is not inter-process (just between my EXE and DLL alone), is the fastest of the three in my tests (although that might not be the case if it was possible to implement in my situation) but given that the goal is inter-process and the interpreted language limitations, maybe something else that I have not mentioned would be better?

Thanks!
Last edited by abalonge on Wed Mar 31, 2021 2:52 pm, edited 28 times in total.
iconic
Site Admin
Posts: 994
Joined: Wed Jun 08, 2005 5:08 am

Re: inter-process callback possible?

Post by iconic »

Why not simply export your “callback”? That would make the most sense to be honest. You can calculate the address rather easily, relative virtual address (RVA) of exported callback + load address (HMODULE) in the other process to call it.

In general though each process has a separate address space (NT) so the function can have a different virtual address. It varies process to process. Also, MMF and other IPC can fail for several reasons so I wouldn’t find it reliable for sharing a function address with other processes.

—Iconic
madshi
Site Admin
Posts: 10365
Joined: Sun Mar 21, 2004 5:25 pm

Re: inter-process callback possible?

Post by madshi »

A "function address of a delphi program" sounds like you're talking about code that is located in an EXE file?

If so, no, you cannot easily make this available in other processes. Other processes would first have to load a module (DLL/EXE) file which contains the same code. Please understand that each process is completely separated in modern OSs. Which means that code which is available in process A is not available in process B. And a pointer in process A doesn't point to the same physical RAM as a pointer with the same value in process B.
abalonge
Posts: 11
Joined: Tue Jun 26, 2012 10:14 pm

Re: inter-process callback possible?

Post by abalonge »

@iconic - I'll think on that idea.
@madshi - Yes an EXE. That seperation of process code can be inconvenient in my case.
abalonge
Posts: 11
Joined: Tue Jun 26, 2012 10:14 pm

Re: inter-process callback possible?

Post by abalonge »

I'm thinking of replacing the callback with a madCodeHook IPC Message or a Windows IPC Message. I did a test with that and it works well, but I was wanting to use a callback because it would execute faster in my case.
madshi
Site Admin
Posts: 10365
Joined: Sun Mar 21, 2004 5:25 pm

Re: inter-process callback possible?

Post by madshi »

I think you need to work on understanding the concepts of process isolation better. IPC will not magically make your EXE's code available to another process. If you want to call your EXE's code in the context of another process then you first have to get the other process to load your EXE's code somehow. Usually this is done by putting the code into a DLL and then make the other process load the DLL somehow. That's the cleanest solution, anyway.

How to actually "call" your code in the context of the other process is a whole different topic. It's a separate problem you also have to solve. But the first thing to solve is that any code you want to call must first be made available in the target process.

Maybe if you give us a full explanation of what you really want to do and for which purpose in great detail, then we can give you better advise.
iconic
Site Admin
Posts: 994
Joined: Wed Jun 08, 2005 5:08 am

Re: inter-process callback possible?

Post by iconic »

Simple/Easiest steps:

Export your callback from your DLL

Inject your DLL into whichever processes you need to have callback execute remotely

In your process (which executes code in other processes) enumerate modules in the target process(es)
and add the module base address (HMODULE), if your module is found, to the relative virtual address (RVA) of the exported callback function

You can calculate the function's RVA by loading the DLL into your process and subtracting the base address (HMODULE) from the callback's virtual address (VA), and store the RVA, it won't change regardless of process, only the VA can change from process to process.

Create a new remote thread at this function address (your exported callback in the target process with Base + RVA which turns into VA)

Done.

That's the short end of it for the sake of brevity, there are things you'll need to pay attention to such as process bitness differences, the state of the process (suspended, debugged, uninitialized, initialized), process session isolation etc. It mostly pertains to if/when it's "safe" to execute a remote thread, but that's magic which Madshi and I already know too well and it's not a quick and easily understood post to elaborate upon.


--Iconic
abalonge
Posts: 11
Joined: Tue Jun 26, 2012 10:14 pm

Re: inter-process callback possible?

Post by abalonge »

@madshi - When I said I used IPC in a test to replace the callback, it was not to make my EXE's code available to another process but to accomplish the end goal in a different way...which you are correct, I will reword my original post and explain the purpose instead.

@iconic - Unfortunately, I found out that the other process can only load a DLL but can not handle pointers/addresses (I seem to work with many interpreted/script based languages). The callback is in my process and the executing code would be in the interpreted process.

Sorry for any confusion, hopefully I can clear things up with a rewording.
iconic
Site Admin
Posts: 994
Joined: Wed Jun 08, 2005 5:08 am

Re: inter-process callback possible?

Post by iconic »

the other process can only load a DLL but can not handle pointers/addresses
If the other process can load a DLL which exports a function it needs no knowledge of what is going on, it's only loaded some .dll file that exports an API, "remotely" callable from any other process. That's why Windows is built on modularization with DLL's, the main .EXE can't perform everything on its own with(out) additional resources, eg: other DLL dependencies.

If you tell Madshi and I more we can help.

--Iconic
abalonge
Posts: 11
Joined: Tue Jun 26, 2012 10:14 pm

Re: inter-process callback possible?

Post by abalonge »

Thanks. I reworded my question, if it is not clear please ask whatever.
madshi
Site Admin
Posts: 10365
Joined: Sun Mar 21, 2004 5:25 pm

Re: inter-process callback possible?

Post by madshi »

A simple "callback" won't work across process boundaries. I think the easiest way to solve this is to simply use PostMessage(). It's surprisingly fast and very easy to use. E.g. in your DLL (when loaded inside of the script process) do:

PostMessage(YourExesMainFormWindowHandle, WM_USER + 123, param1, param2);

You can send 2 parameters this way, param1 and param2. And in your Delphi EXE, simply add a message handler for WM_USER + 123.
iconic
Site Admin
Posts: 994
Joined: Wed Jun 08, 2005 5:08 am

Re: inter-process callback possible?

Post by iconic »

You've reworded your initial question, so that led to confusion. My response was solely based on how to remotely "execute" code without any other library assistance. Now that we have a better context of what you mean, it seems to be you may want to simply "notify" your EXE of a function call and not actually execute any code in remote processes.

As Madshi said with PostMessage():

You can use PostMessage() (It's fast and doesn't wait like SendMessage) from your scripted program that loads your DLL and needs to inform your EXE for (IPC) means, however it only works with non-service processes, so be careful of this. madCodeHook's SendIpcMessage() works in both services and GUI apps regardless of session. There's a BIG difference, but if speed is a factor for "notification" PostMessage() is very fast, it's governed below user32.dll by Win32k.sys as a direct system call (e.g: NtUserXxX).

Perhaps, if I understand what you mean, you should have titled your post "Fastest way to IPC from a DLL to an EXE" - actually mailslots are VERY quick too, but that's another rant :D

--Iconic
madshi
Site Admin
Posts: 10365
Joined: Sun Mar 21, 2004 5:25 pm

Re: inter-process callback possible?

Post by madshi »

Yes, iconic is right, of course, about services. PostMessage may not work if the other process is a service. Considering abalonge talked about a script process, I thought it would be a normal user process. But it might not be.

@iconic, calling PostMessage does not internally make the thread handle messages or put the thread into an alertable state, does it? I don't think it does, just wondering...
iconic
Site Admin
Posts: 994
Joined: Wed Jun 08, 2005 5:08 am

Re: inter-process callback possible?

Post by iconic »

PostMessage() doesn't touch the alertable state of any thread, the request sits in the queue of the target window that received it until it's processed asynchronously.

--Iconic
madshi
Site Admin
Posts: 10365
Joined: Sun Mar 21, 2004 5:25 pm

Re: inter-process callback possible?

Post by madshi »

I was mainly worried about the alertable state of the thread calling PostMessage. But good to know it doesn't change the alertable state of any thread, thanks!
Post Reply