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@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