[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