So, I'm attempting to create a mod for an older game, Fable: The Lost Chapters. I was able to find the MacOS release of the game, which contains symbols, and I was also able to find a leaked debug build for windows, which also contains symbols. Both have made the modding process far easier, however this function specifically I have been unable to call or hook.
Here's what the function looks like within IDA when demangled.
MacOS CThingCreatureBase::SetCurrentAction(CCreatureActionBase const&)
Windows Debug Build bool __thiscall CThingCreatureBase::SetCurrentAction(CThingCreatureBase *this, const CCreatureActionBase *action)
And here's how I'm hooking the function.
typedef bool (__thiscall* tSetCurrentAction)(CThingCreatureBase*, CCreatureActionBase const &); tSetCurrentAction oSetCurrentAction; bool __fastcall hSetCurrentAction(CThingCreatureBase* This, CCreatureActionBase const & action) { return oSetCurrentAction(This, action); } if (MH_Initialize() == MH_OK) std::cout << "MinHook Initialized" << std::endl; if(MH_CreateHook((LPVOID)0x6644F0, &hSetCurrentAction, reinterpret_cast<void**>(&oSetCurrentAction)) == MH_OK) std::cout << "SetCurrentAction Hooked" << std::endl; if (MH_EnableHook((LPVOID)0x6644F0) == MH_OK) std::cout << "SetCurrentAction Enabled" << std::endl; Though for some reason, the game crashes whenever oSetCurrentAction is called.
Here's the exception when debugging Exception thrown at 0x00692F03 in Fable.exe: 0xC0000005: Access violation reading location 0xCCCCCCD0.
I'm hopeful that I'm just missing something obvious, what someone will easily spot, but that's probably not the case. Any help would be greatly appreciated.
MH_CreateHook(...)you use an absolute address:0x6644F0. If it is taken from the symbols table offsets, it is an offset from the ImageBase that you need to calculate to the correct virtual address.tSetCurrentAction()as a__thiscall. Your hook function,hSetCurrentActionis declared as__fastcall. The hook function will take theactionargument fromEDXwhich is undefined. The original function, trying to access theactionargument will most likely end up reading some arbitrary memory address and crash.__thiscallis just a calling convention. Changing the pointer to that should work. Your function is called by the game as__thiscallwith athis *in ECX (same as a__fastcall) andactionon the stack. Translated to__fastcallterms, theactionargument is the third arg passed to your hook function. If you add an unused second arg to your hook function then you can leave the content as is.