How do we get this code to not crash? This was working up until we bumped our macOS deployment to 10.15. When deployment is set to macOS 10.14, the code works fine. Data is nearly identical in the debugger, although the vtable is at a slightly lower address in 10.15.
Have the C++ vtables been put in read-only marked pages, and if so how do we prevent that? Hardened runtime is not enabled, and I don't recall any mention from Apple about this change.
Have the C++ vtables been put in read-only marked pages, and if so how do we prevent that? Hardened runtime is not enabled, and I don't recall any mention from Apple about this change.
Code Block #import <Foundation/Foundation.h> class Base { public: virtual ~Base() {}; virtual const char* Print() { return "Base"; } }; class Derived : public Base { public: virtual const char* Print() override { return "Derived"; } }; const char* PrintPatch( Base* localThis ) { return "Patch"; } template <class T1, class T2> void* PatchVtablePtr( void** vtable, T1 memberFunction, T2 newFunction ) { // Replace the instance of memberFunction in the vtable with newFunction void* offset = *(void**)&memberFunction; auto vtableIndex = (uintptr_t)offset / sizeof(void*); vtable[vtableIndex] = (void*)newFunction; <- Thread 1: EXC_BAD_ACCESS (code=2, address=0x100004038) // return the original vtable address return offset; } int main(int argc, const char * argv[]) { Derived* derived = new Derived(); printf("%s\n", derived->Print()); // monkeypatch the vtable //Base* base = derived; //void** vtable = *(void*)base; void vtable = *(void***)derived; PatchVtablePtr( vtable, &Derived::Print, &PrintPatch ); printf("%s\n", derived->Print()); return 0; }