views:

109

answers:

4

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).

A: 

I'm not entirely sure that I understand you correctly, but anyhow: I think the easiest route to "hand-locating" methods is by using function-pointers.

S.C. Madsen
Yes, but they're thiscalls. I don't feel like converting each and everyone of them to stdcalls with an asm wrapper (popping the first argument and moving it to ecx, calling the function). I'd just prefer to do GuessedFoo f = new GuessedFoo(42, 18); instead of GuessedFoo_GuessedFoo((void*)data, 42, 18);
Serge
A: 

C++ does not define any kind of binary interface making it all but impossible to implement any kind of dynamic binding for c++ classes.

the best you can do is to declare two structs - one containing c function typedefs for each method, the other mirrors the class data layout.

Of course - because __thiscall on a class method passes 'this' via the ecs register, I don't belive you can actually make an explicit c function declaration that will have the same effect so you might need to perform all the calls via a custom "CallThisCallMethodWithParameters" that you had write in assembly.

Chris Becke
C++'s binary interfaces are defined - just like C or any other language, they vary by platform, and are defined in platform documentation. One can certainly implement dynamic binding for C++, it's just a bit complex when one has to deal with template types in parameters and etc, so there are few (if any) complete dynamic binding systems that don't punt the hard work to a full C++ compiler in the end.
bdonlan
+1  A: 

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!

bdonlan
Naked functions will do the trick, most of the classes in the original code aren't inherited, so there's no virtual functions, so there's no vtables. Muchas gracias!
Serge
+1  A: 

You're reverse-engineering here, hence (almost, probably) forced to get lower when it comes to interacting with existing code.

I'd call this function using pure assembly code.
If the EXE's base address is fixed it's even easier.
Example code:

void main()
{
    int bar = 5;
    int * cafebabe = &bar;
    __asm
    {
        push [bar];
        push [cafebabe];
        mov eax, 123456; // address of the function
        call eax;
    }
}

Simply check how this function is being called by original code to see in which order you need to push arguments. Don't forget that some arguments might need to be passed through registers!

Poni
Yes, "this" is passed by ecx when calling an object method. I know I can write assembly and C to create a happy fun environment to use the original code, but it gets tedious when there's a couple dozen classes each with a dozen methods. Thanks anyway!
Serge