[Win32] Remotely execute functions of a D program

alex info at alexanderbothe.com
Fri Sep 14 10:34:47 PDT 2012


Hi everyone,

To keeps things short: There shall be a extended debugging 
feature integrated into Mono-D / VisualD later on. As you may see 
on 
http://mono-d.alexanderbothe.com/wordpress/wp-content/uploads/2012/09/2ylpkqg.jpg 
, there already is debugging functionality possible for windows 
programs (when it's arrived a pretty stable status it'll be 
released as a second D addin, that's for sure)

Anyway, we'd like to replace all those 'struct main at helper' value 
strings with actual values returned by the object's toString 
function.
So the debug engine shall execute the toString() 
function/overload of an object
1) via a D DLL that has been injected into the program run-time or
2) directly via CreateRemoteThread(), whereas it should be 
possible to allocate some code memory and write binary code right 
into it

I kept experimenting with all the injection, assembler and 
program hacking stuff quite a while, and these are my primary 
perceptions:

- It seems that one cannot inject D DLLs into D programs without 
crashing the actual program (it's always an exception thrown by 
RTLMultiPool::SelectFree), whereas:
     --One may write a main() function instead of the DllMain() 
callback
     and then start a normal WindowMessage-loop in order to
     prevent both DLL and Program unload/crash - but that's not 
really it, because it's just caught in a loop, and nothing less.
     --It's possible to call LoadLibrary with the DLLs file path 
inside the DllMain() to hook into the program without letting it 
crash - but then it seems impossible to access the dll from the 
outside (probably via named pipes, then)
     --It doesn't seem to make sense to load in a C dll - because 
from there, it's practically impossible to call D functions.

- I've created an export toString(int pointerToObject) method 
inside the
D program - and it's not possible to invoke it via 
CreateRemoteThread().
So even if I did it to successfully inject a D Dll into the D 
program,
there's no guarantee that it's possible to call that toString 
function even in the D Dll.

extern(C) export string toSt(int p)
{
	return (cast(Object)cast(void*)p).toString();	
}
the 'p' paramter comes from the debugger engine then - so it 
knows the object address.

- Another approach was to put in raw assembler code into the 
program's
virtual memory space and try to execute it from there - so 'just'
put the assembler code (I've built it already lol) into the
program run-time, and execute it somehow. But I definitely do not 
know how to create real working assembler etc.

Or: I've tried Winject yesterday, too, and there it worked to 
load in the DLL just at launching the program - this is something 
which could be realized with the debug engine, I guess.
But then again the question of having execution access to the 
exported functions of the client dll .. named pipes?

Okay, these are my explenanations so far - and I think it would 
be really interesting to have such debugger-debugee communication 
in D.
1) So to anyone who's got richer experiences in programming 
assembler and hacking/'debugging' programs than I - how would you 
do it?
2) And why can't I inject a D DLL right into the program? I tried 
it with a C DLL, it's working with that one, but then I don't 
have access to D-specific functions..
Looking at that, would it make a difference to use dmc to 
build/link a dll as a D/C++ hybrid or something?

Thanks in advance for any ideas, recommendations etc.!

Oh and the debugger addin project: 
https://github.com/aBothe/monodevelop-win32-debugger


More information about the Digitalmars-d mailing list