www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get access to Voldemort / private thingies

reply Johan Engelen <j j.nl> writes:
Hi all,
   Is there another way to get access to Voldemort class methods, 
or private class members, other than using "pragma(mangle, ...)" 
on user symbols?

Example code:

In library, and _should not_ be changed :
```
Object getObject() {
     class Vold : Object {
         int store;
         this(int i) {
            store = i;
         }
     }
     return new Vold(2);
}

class Thread
{
      private:
      static struct AAA
      {
           int i;
      }
     __gshared AAA*  sm_cbeg;
}
```

And then the code seeking access:
```
pragma(mangle, "mangled name of Vold's constructor")
     private extern(C) void defaultTraceInfoCtor(Object)  nogc;

struct A
{
     int i;
}
__gshared extern {
     pragma(mangle, "the mangled symbol name") A* sm_cbeg;
}
```

Go mad on the "code seeking access" :-) The problem is that the 
types of `defaultTraceInfoCtor` and `sm_cbeg` are incorrect. If I 
can get the types to match (internally in the compiler), I'm 
happy.

Thanks,
   Johan
Jun 17 2016
next sibling parent reply cy <dlang verge.info.tm> writes:
On Friday, 17 June 2016 at 19:49:18 UTC, Johan Engelen wrote:
 Hi all,
   Is there another way to get access to Voldemort class 
 methods, or private class members, other than using 
 "pragma(mangle, ...)" on user symbols?
Well, I'm sure you know that's a horrible idea. Anyway, a trick I use in C++ is to copy and paste the class's source into my own file, and change everything to public, then just cast to my hiijacking class type. So, in D... import std.stdio; final class SeriousBusiness { private: int soconfidential; char wow; void thisIsTotallyProtectedHonest() { // import underlying.implementation; // import dependency.hell // import kitchen.sink writeln("We can totally put sensitive data in here"); } this(int s, char w) { this.soconfidential = s; this.wow = w; } } final class ProtectionAttributesSuck { int soconfidential; char wow; void thisIsTotallyProtectedHonest() { // import underlying.implementation; // import dependency.hell // import kitchen.sink writeln("We can totally put sensitive data in here"); writeln("see ",wow," for any equipment you need."); } } void main() { SeriousBusiness srs = new SeriousBusiness(42,'Q'); ProtectionAttributesSuck* hack = cast(ProtectionAttributesSuck*)&srs; writeln("the answer is ",hack.soconfidential); hack.thisIsTotallyProtectedHonest(); }
Jun 17 2016
parent cy <dlang verge.info.tm> writes:
On Friday, 17 June 2016 at 20:12:53 UTC, cy wrote:
 	  writeln("see ",wow," for any equipment you need.");
Oh, and as you can see it's important to automate that, so you don't make any mistakes while copying.
Jun 17 2016
prev sibling parent reply cy <dlang verge.info.tm> writes:
On Friday, 17 June 2016 at 19:49:18 UTC, Johan Engelen wrote:
 Hi all,
   Is there another way to get access to Voldemort class 
 methods, or private class members, other than using
Voldemort data is pretty well protected though. Because unlike protection attributes, modularizing stuff in functions actually means something. I mean, D doesn't exactly make it easy. You can't normally define a function in a different file it's declared in. But if you use extern(C) to avoid mangling getObject, you can pretty much provide interface.d and secrets.o and without analyzing the binary machine code, there's no way to tell the size or nature of what getObject returns, aside from that it (claims) to have pointers to functions that match the interface. interface.d: interface Object { ... }; extern(C) Object getObject(); secrets.d: class Vold : Object { ... }; extern(C) Object getObject() { ... return new Vold(...); ... } secrets.o: ???? Because of the guarantee that you can link to opaque .o files, there's no general way to introspect into just what a function does, because that function might not have any source at all. (I suppose you could instrument "new" itself in the raw runtime, to at least get the size of it. Assuming it wasn't malloc'd, or static...)
Jun 17 2016
parent reply Johan Engelen <j j.nl> writes:
On Friday, 17 June 2016 at 21:07:31 UTC, cy wrote:
 On Friday, 17 June 2016 at 19:49:18 UTC, Johan Engelen wrote:
 Hi all,
   Is there another way to get access to Voldemort class 
 methods, or private class members, other than using
[... snip ...] Because of the guarantee that you can link to opaque .o files,
Thanks for your response. Without going in too much detail, the problem is that I am not linking to opaque .o files. The user symbol has to have the same type (as the hidden type) internally in the compiler; both will be present in the same translation unit because of inlining, and so if the mangled names are the same, their types have to be the same. Hmm... -Johan
Jun 18 2016
next sibling parent Johan Engelen <j j.nl> writes:
Someone figured out how to do it and put it in std.traits! ;-)

Example:
```
import std.stdio;
import core.thread;
import std.traits;

void main()
{
     Fields!Thread[11] a;
     writeln(typeid(a));
}
```
This prints "core.thread.Thread.Context" , which is a private 
struct type of core.thread.Thread.
Success! :-)

-Johan
Jun 18 2016
prev sibling parent reply cy <dlang verge.info.tm> writes:
On Saturday, 18 June 2016 at 08:41:30 UTC, Johan Engelen wrote:
 Without going in too much detail, the problem is that I am not 
 linking to opaque .o files.
The problem is the compiler has to assume you *might* be linking to opaque .o files, so it can't provide any introspection capabilities. There's no way to tell which "hidden type" that the getObject function is returning, since that's decided in the (possibly opaque) function body. You could hack something with debugging, I suppose. (Probably not. DWARF/ptrace is ridiculously undocumented.) Perhaps you could make an alternate version of the function with the same source code, that returns auto instead of an Object type? As in... Object evil() { class Vold {...} Vold v = new Vold(...); return v; } auto notevil() { static class Vold {...} Vold v = new Vold(...); return v; } ... auto hack = new typeof(notevil()); That can magically allow you to return type Vold, even though it's an error to say Vold notevil() { static class Vold { ... } ... }
Jun 18 2016
parent Johan Engelen <j j.nl> writes:
On Saturday, 18 June 2016 at 17:50:51 UTC, cy wrote:
 On Saturday, 18 June 2016 at 08:41:30 UTC, Johan Engelen wrote:
 Without going in too much detail, the problem is that I am not 
 linking to opaque .o files.
The problem is the compiler has to assume you *might* be linking to opaque .o files, so it can't provide any introspection capabilities. There's no way to tell which "hidden type" that the getObject function is returning, since that's decided in the (possibly opaque) function body.
The function body is not opaque. In my compilation unit, the compiler knows it, and that's exactly why I run into troubles. For ease of discussion, just pretend the function that returns the Voldemort type is in the same file as the user code: let's say it's all in one source file. Just like there is a way to get private types out of structs (using .tupleof or the Fields!Strukt[*] thing I pasted above), I was hoping there was a way to get a Voldemort type out of a function. This is of course all a big hack. The pragma(mangle,..) thing works well, but unfortunately conflicts with the LDC inlining improvement I'm working on. Like you say, I could copy the whole function definition, but it would mean copying quite a lot and some more types etc... - Johan
Jun 18 2016