I have a .exe application and I need to create some customizations to this executable, so I need to hook a dll in it for the changes to be loaded. Until then, everyone knows.
The scenario is this:
Hook(0xOffset, &myClass::myFunc);
There is a class in .exe that I need to rewrite completely and I've done that in my dll, but I'm having trouble with the hook of the functions of class, they aren't static. I've read many topics and I could not implement it with any method presented. In some cases, the compiler will not accept, in others cases has accepted but the .exe could not find the actual address of the function.
A friend gave me a solution, but it is a little confusing to understand how I can call the function there and from what I saw would be very big in my source code and many loops, so to speak.
Could help me?
Member functions are indeed far more complex. You have to deal with normal inheritance, multiple inheritance, and virtual inheritance; with direct calls and virtual calls. Possibly the worst is dealing with member function pointers, which are entirely unlike normal function pointers.
As a result, many solutions deal only with the easy cases. It's perfectly normal that a solution capable of dealing with all edge cases takes a lot of code.
Related
I'm knee deep in a project to connect Windows OpenVR applications running in Wine directly to Linux native SteamVR via a Winelib wrapper, the idea being to sidestep all the problems with trying to make what is effectively a very complicated device driver run inside Wine itself. I pretty much immediately hit a wall. The problem appears to be related to calling conventions, though I've had trouble getting meaningful information out of winedbg, so there's a chance I'm way way off.
The OpenVR API is C++ and consists primarily of classes filled with virtual methods. The application calls a getter (VR_GetGenericInterface) to acquire a derivative class object implementing those methods from the (closed source) runtime. It then calls those methods directly on the object given to it.
My current attempt goes like this: My wrapped VR_GetGenericInterface returns a custom wrapper class for the requested interface. This class's methods are defined in their own file separately compiled with -mabi=ms. It calls non-member methods in a separate file that is compiled without -mabi=ms, which finally make the corresponding call into the actual runtime.
This seems to work, until the application calls a method that returns a struct of some description. Then the application segfaults on the line the call happened, apparently just after the call returned, as my code isn't anywhere on the stack at that point and I verified with printfs that my wrapped class reaches the point of returning to the app.
This leads me to think there's yet another calling convention gotcha I haven't accounted for yet, related to structs and similar complex types. From googling it appears returning a struct is one of the more poorly-defined things in ABIs typically, but I found no concrete answers or descriptions of the differences.
What is most likely happening, and how can I dig deeper to see what exactly the application is expecting?
I've been developing for some time. And these beasts appear from time to time in MFC, wxWidgets code, and yet I can't find any info on what they do exactly.
As I understand, they appeared before dynamic_cast was integrated into core C++. And the purpose, is to allow for object creation on the fly, and runtime dynamic casts.
But this is where all the information I found, ends.
I've run into some sample code that uses DECLARE_DYNAMIC_CLASS and IMPLEMENT_DYNAMIC_CLASS within a DLL, and that is used for exported classes. And this structure confuses me.
Why is it done this way? Is that a plugin based approach, where you call LoadLibrary and then call the CreateDynamicClass to get a pointer which can be casted to the needed type?
Does the DECLARE/IMPLEMENT_DYNAMIC work over DLL boundaries? Since even class is not so safe to DLLEXPORT, and here we have a custom RTTI table in addition to existing problems.
Is it possible to derive my class from a DYNAMIC_CLASS from another DLL, how would it work?
Can anyone please explain me what these things are for, or where I can find more than a two sentences on a topic?
This stuff appends addional type information to your class, which allows to RTTI in runtime-independent manner, possibility of having factories to create your classes and many other things. You can find similar approach at COM, QMetaObject, etc
Have you looked at the definitions of DECLARE/IMPLEMENT_DYNAMIC?
In the MS world, all uppercase usually denotes a macro, so you can just look up the definition and try to work out what it's doing from there. If you're in Visual Studio, there's a key you can hit to jump to the definition - see what it says, and look that up and try to work from there.
Update:
Thanks everyone for kindly replying. Seems I was a little bit confused. The change was to add a new member function to the base class. I just realized maybe I do need to recompile everything that depends on the dll that exporting this class, since the addresses for function names in the symbol table changed. Please confirm I'm right or wrong.
Got into a debate for this,
When there is a member function change in some base class, I only recompiled all classes derived from this base, and ran into some run time error.
On the other side of the debate, I was told instead I should recompile all the classes that "depends" on this base class.
I'm not sure whether that is correct or not? Because I'm building DLLs and I always understand this dynamic link idea to be not to recompile.
If it's true, I'm also wondering what kind of "dependency" here is?
This question might be asked too general, please let me know if any other details I should provide. Really need to learn about the compiling and linking stuff.
Thanks!
DLLs and classes don't play well together. (Using classes inside a DLL is fine, it's when you try to export them that you have problems.)
For this reason, component/object systems (such as COM, ActiveX, CORBA) define an interface that separates the user from the implementation. If the public API for the DLL only uses pointers to a type with only pure virtual functions, then it has no layout shared between the DLL and caller.
If you try to share classes with data or inline functions, you have tight coupling and will need to recompile all users for the slightest implementation change.
I'm pretty sure this problem isn't new, and pretty sure it's hard to solve. Hopefully I'm wrong about the latter.
I'm trying to use the Loki::Singleton from Modern C++ Design in a program of mine.
However, I can't seem to get it to work across DLLs. I think I know why this is happening: the templated code gets instantiated in every source module, so instead of there being one global variable, each module has its own.
Obviously, this makes the Singleton very much non-single.
Is there any way to get around this behavior?
I see in the Loki source directory that they have a specific SingletonDLL directory under test, looks like they use an exported, explicitly instantiated template (which would work). Hopefully that contains the code you want.
Note this is not going to address the question. An explicitly instantiated and exported singleton should do the trick...
-Rick
Check out #pragma data_seg here basically, you need to declare an instance of the singleton in a shared section of your code. By default statics are scoped to the dll.
It may get tricky with templates, but this is the path to success here that doesn't involve passing / copying static data around.
You are probably correct that each DLL has its own instance of the singleton. I'm not that familiar with the Loki implementation and the source code isn't a lot of fun to figure out.
Possible solutions are:
Not using singletons. This is actually my usual preference because you can avoid whole classes of issues by changing your design to not need them. For a long rant on why Singletons may be harmful see this Yegge post. I'm not THAT vehemently against them but 95% of the time Singletons cause many more problems than they solve (if they actually solve any)
Copying static members across DLL boundaries. I've also done this as a hack, where the DLL gets a pointer from an application or another DLL, and resets its own copy of the static class member to the pointer passed from outside. It's evil, it's dirty, you can't clean up after it, but it does work.
Is it possible to implement monkey patching in C++?
Or any other similar approach to that?
Thanks.
Not portably so, and due to the dangers for larger projects you better have good reason.
The Preprocessor is probably the best candidate, due to it's ignorance of the language itself. It can be used to rename attributes, methods and other symbol names - but the replacement is global at least for a single #include or sequence of code.
I've used that before to beat "library diamonds" into submission - Library A and B both importing an OS library S, but in different ways so that some symbols of S would be identically named but different. (namespaces were out of the question, for they'd have much more far-reaching consequences).
Similary, you can replace symbol names with compatible-but-superior classes.
e.g. in VC, #import generates an import library that uses _bstr_t as type adapter. In one project I've successfully replaced these _bstr_t uses with a compatible-enough class that interoperated better with other code, just be #define'ing _bstr_t as my replacement class for the #import.
Patching the Virtual Method Table - either replacing the entire VMT or individual methods - is somethign else I've come across. It requires good understanding of how your compiler implements VMTs. I wouldn't do that in a real life project, because it depends on compiler internals, and you don't get any warning when thigns have changed. It's a fun exercise to learn about the implementation details of C++, though. One application would be switching at runtime from an initializer/loader stub to a full - or even data-dependent - implementation.
Generating code on the fly is common in certain scenarios, such as forwarding/filtering COM Interface calls or mapping OS Window Handles to library objects. I'm not sure if this is still "monkey-patching", as it isn't really toying with the language itself.
To add to other answers, consider that any function exposed through a shared object or DLL (depending on platform) can be overridden at run-time. Linux provides the LD_PRELOAD environment variable, which can specify a shared object to load after all others, which can be used to override arbitrary function definitions. It's actually about the best way to provide a "mock object" for unit-testing purposes, since it is not really invasive. However, unlike other forms of monkey-patching, be aware that a change like this is global. You can't specify one particular call to be different, without impacting other calls.
Considering the "guerilla third-party library use" aspect of monkey-patching, C++ offers a number of facilities:
const_cast lets you work around zealous const declarations.
#define private public prior to header inclusion lets you access private members.
subclassing and use Parent::protected_field lets you access protected members.
you can redefine a number of things at link time.
If the third party content you're working around is provided already compiled, though, most of the things feasible in dynamic languages isn't as easy, and often isn't possible at all.
I suppose it depends what you want to do. If you've already linked your program, you're gonna have a hard time replacing anything (short of actually changing the instructions in memory, which might be a stretch as well). However, before this happens, there are options. If you have a dynamically linked program, you can alter the way the linker operates (e.g. LD_LIBRARY_PATH environment variable) and have it link something else than the intended library.
Have a look at valgrind for example, which replaces (among alot of other magic stuff it's dealing with) the standard memory allocation mechanisms.
As monkey patching refers to dynamically changing code, I can't imagine how this could be implemented in C++...