c++winapireverse-engineeringdll-injection

Using undocumented classes in C++


I'm in the process of reverse-engineering a Windows executable. I found a class that I want to use from some code that I inject into the executable (different thread, own stack). How would I go about declaring such a class, given method addresses and member variables structure?

For instance, let's say I found a class called foo, with it's constructor @ 0x4012D30 and a function doTheMario @ 40125D4. I also know it holds three DWORDs of private data. Since both the methods are _thiscalls, I declare a class like so in my code:

class GuessedFoo {
    private:
        int bar;
        char *cafebabe;
        float deadbeef;
    public:
        GuessedFoo(int a, int b);
        void doTheMario();
};

Now, this is a perfectly dandy class, but now is there any way to make the compiler / linker bind the class methods to the two previous addresses I stated? Of course I can write an asm wrapper to convert an stdcall into a thiscall for every method that I need to use, and then use structs instead of classes, but there has to be a better way.

I use gcc/g++ at the moment, but I can switch to VC++ (since gcc's inline asm gives me headaches anyway).


Solution

  • If the class has no vtable, you could, in principle, create such a class in your own code, where all the function calls invoke the appropriate real implementations. You can do this by wring the member functions as naked functions containing an assembly jump instruction to the real implementation.

    If the class has a vtable, things are likely to get much more complex; you'll likely need to explicitly create the vtable as a struct of function pointers, and make your function stubs call into them. This means more complex shim functions; a simple naked function with a jump may not be enough, and it may be better to go with a real function. Remember, though, that member functions on win32 use a different calling convention; this means that an ordinary member function call will not work. You may be able to get away with building pointers-to-member-functions, but keep in mind they have a rather strange structure to them, and you'll need to match it with something that has the same representation as the vtable pointers. Good luck!