diff --git a/loader/include/Geode/utils/addresser.hpp b/loader/include/Geode/utils/addresser.hpp index 96de6db6..ec09837d 100644 --- a/loader/include/Geode/utils/addresser.hpp +++ b/loader/include/Geode/utils/addresser.hpp @@ -83,28 +83,39 @@ namespace geode::addresser { // } // I extra gave up + template static cocos2d::extension::CCScrollView* generateInstance(cocos2d::extension::CCScrollView*) { return cocos2d::extension::CCScrollView::create({0.0f, 0.0f}, cocos2d::CCLayer::create()); } + template + static cocos2d::CCFileUtils* generateInstance(cocos2d::CCFileUtils*) { + return cocos2d::CCFileUtils::sharedFileUtils(); + } + template static Class* generateInstance(Class*) { - // Create a random memory block with the size of Class - // Assign a pointer to that block and cast it to type Class* - uint8_t dum[sizeof(Class)]{}; - auto ptr = reinterpret_cast(dum); - // Now you have a object of Class that actually isn't an object of Class and is just a - // random memory But C++ doesn't know that of course So now you can copy an object - // that wasn't there in the first place - // ((oh also get the offsets of the virtual tables)) - auto ins = new Class(*ptr); - // this is how the first human was made - return ins; + if constexpr (std::is_abstract_v) { + // Cant construct abstract classes, so fail early + return nullptr; + } else { + // Create a random memory block with the size of Class + // Assign a pointer to that block and cast it to type Class* + uint8_t dum[sizeof(Class)]{}; + auto ptr = reinterpret_cast(dum); + // Now you have a object of Class that actually isn't an object of Class and is just a + // random memory But C++ doesn't know that of course So now you can copy an object + // that wasn't there in the first place + // ((oh also get the offsets of the virtual tables)) + auto ins = new Class(*ptr); + // this is how the first human was made + return ins; + } } template static Class* cachedInstance() { - static auto ret = generateInstance(nullptr); + static auto ret = generateInstance(static_cast(nullptr)); return ret; } @@ -112,24 +123,20 @@ namespace geode::addresser { * Specialized functionss */ template - static intptr_t addressOfVirtual( - R (T::*func)(Ps...), typename std::enable_if_t>* = 0 - ) { + static intptr_t addressOfVirtual(R (T::*func)(Ps...)) { using geode::cast::reference_cast; + auto ins = cachedInstance(); + // generateInstance will return nullptr on most abstract classes, + // so dont bother getting the address + if (ins == nullptr) { + return 0; + } auto index = indexOf(func); auto thunk = thunkOf(func); - auto ins = cachedInstance(); - // log::debug("[[" + utils::intToHex((void*)ins) + " + " + utils::intToHex(thunk) + "] + - // " + utils::intToHex(index) + "]"); - // log::debug( - // "[[{} + {}] + {}]", utils::intToHex((void*)ins), utils::intToHex(thunk), - // utils::intToHex(index) - // ); - - // [[this + thunk] + offset] is the f we want - auto address = *(intptr_t*)(*(intptr_t*)(reference_cast(ins) + thunk) + index); + // [[this + thunk] + offset] is the function we want + auto address = *reinterpret_cast(*reinterpret_cast(reinterpret_cast(ins) + thunk) + index); address = followThunkFunction(address); @@ -137,27 +144,10 @@ namespace geode::addresser { } template - static intptr_t addressOfVirtual( - R (T::*func)(Ps...) const, - typename std::enable_if_t && !std::is_abstract_v>* = 0 - ) { + static intptr_t addressOfVirtual(R (T::*func)(Ps...) const) { return addressOfVirtual(reinterpret_cast(func)); } - template - static intptr_t addressOfVirtual( - R (T::*func)(Ps...), typename std::enable_if_t>* = 0 - ) { - return 0; - } - - template - static intptr_t addressOfVirtual( - R (T::*func)(Ps...) const, typename std::enable_if_t>* = 0 - ) { - return 0; - } - template static intptr_t addressOfNonVirtual(R (T::*func)(Ps...) const) { return addressOfNonVirtual(reinterpret_cast(func));