C++ - Simple Class to Handle Internal Function Calls menu

User Tag List

Results 1 to 11 of 11
  1. #1
    CodeBytes's Avatar Member
    Reputation
    14
    Join Date
    Feb 2020
    Posts
    39
    Thanks G/R
    7/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    C++ - Simple Class to Handle Internal Function Calls

    Here is a simple class I wrote to help you handle internal function calls. It requires some integration as you'll have to plug in your ObjectGuid class and offsets, but it has everything you need to get started with internal botting.

    Code:
    // - MemoryMgr.h
    
    #pragma  once
    
    #include  "MemoryDefines.h"
    #include  "ObjectGuid.h"
    
    class MemoryMgr
    {
    public:
        static MemoryMgr* instance();
    
        ObjectGuid GetLocalPlayerGuid() { return m_localGuid; }
    
        bool Spell_C_GetSpellCooldown(uint32 spellId, bool pet, int64* duration, int64* startTime, bool* enabled, int64* modRate);
        int64 CGUnit_C_GetPower(ObjectGuid* value, uint8 powerType, bool unmodified);
    
    private:
        MemoryMgr();
        MemoryMgr(MemoryMgr const&) { }
        MemoryMgr& operator=(MemoryMgr const&) { }
        static MemoryMgr* m_instance;
    
        ObjectGuid m_localGuid;
    
        uintptr m_objMgr;
        uintptr m_getSpellCooldown;
        uintptr m_getPower;
    };
    
    #define  sMemoryMgr MemoryMgr::instance()
    Code:
    // MemoryMgr.cpp
    
    #include  "MemoryMgr.h"
    #include  <Windows.h>
    
    MemoryMgr* MemoryMgr::m_instance = NULL;
    
    MemoryMgr::MemoryMgr()
    {
        uintptr base        = (uintptr)GetModuleHandle(nullptr);
    
        m_objMgr            = base + (uintptr)BASE_ADDR_OFFSET_OBJ_MGR;
    
        m_localGuid         = *(ObjectGuid*)( (*(uintptr*)(m_objMgr)) + OFFSET_OBJ_MGR_ACTIVE_PLAYER_GUID);
    
        m_getSpellCooldown  = base + (uintptr)WOW_FUNCTION_GET_SPELL_COOLDOWN;
        m_getPower          = base + (uintptr)WOW_FUNCTION_GET_POWER;
    }
    
    MemoryMgr* MemoryMgr::instance()
    {
        if (!m_instance)
            m_instance = new MemoryMgr;
    
        return m_instance;
    }
    
    bool MemoryMgr::Spell_C_GetSpellCooldown(uint32 spellId, bool pet, int64* duration, int64* startTime, bool* enabled, int64* modRate)
    {
        return reinterpret_cast<bool(__fastcall*)(uint32, bool, int64*, int64*, bool*, intptr, intptr, int64*)>(m_getSpellCooldown)(spellId, pet, duration, startTime, enabled, 0, 0, modRate);
    }
    
    int64 MemoryMgr::CGUnit_C_GetPower(ObjectGuid* value, uint8 powerType, bool unmodified)
    {
        return reinterpret_cast<bool(__fastcall*)(ObjectGuid*, uint8, bool)>(m_getPower)(value, powerType, unmodified);
    }
    Code:
    // Example use
    
    ObjectGuid guid = sMemoryMgr->GetLocalPlayerGuid();
    int64 energy = sMemoryMgr->CGUnit_C_GetPower(&guid, POWER_ENERGY, false);
    int64 cp = sMemoryMgr->CGUnit_C_GetPower(&guid, POWER_COMBO_POINTS, false);
    
    // TODO: Implement string formatting
    sNotification->ShowMessage("Energy: " + std::to_string(energy) + " Combo Points: " + std::to_string(cp));
    Last edited by CodeBytes; 05-13-2020 at 12:28 AM.

    C++ - Simple Class to Handle Internal Function Calls
  2. Thanks Corthezz (1 members gave Thanks to CodeBytes for this useful post)
  3. #2
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Or you can do it the modern way which is way more generic and extendable, besides it doesn't make use of singletons (they are the devil incarnate).

    Code:
    template <typename Fx, uintptr_t ofs>
    class function
    {
    	typedef Fx fx_t;
    
    public:
    	template <typename... Args>
    	auto operator()(Args&&... args)
    	{
    		return call(std::forward<Args>(args)...);
    	}
    
    	template <typename... Args>
    	auto call(Args&&... args)
    	{
    		fx_t* fn = reinterpret_cast<fx_t*>(reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr) + ofs));
    		return fn(std::forward<Args>(args)...);
    	}
    
    };
    
    // define the function
    typedef function<bool __cdecl(uint32_t, bool, uint64_t*, uint64_t*, uint64_t*, uint64_t, uint64_t, uint64_t*), 0xDEADBEEF> Spell_GetSpellCooldown_t;
    inline Spell_GetSpellCooldown_t Spell_GetSpellCooldown;
    
    // Macro for simpler definitions of functions
    #define  DEFINE_FUNC(name, fn, ofs)\
    	typedef function<fn, ofs> name ## _t;\
    	inline name ## _t name;
    
    DEFINE_FUNC(Unit_GetPower, uint64_t __fastcall(uintptr_t*, int8_t, bool), 0xDEADBEEF);
    
    void do_something()
    {
    	uint64_t duration = 0, start = 0, enabled = 0, modrate = 1;
    	if (Spell_GetSpellCooldown(1234, false, &duration, &start, &enabled, 0, 0, &modrate)
    	{
    		// do something with cds?
    	}
    
    	ObjectGuid guid;
    	if (Unit_GetPower(&guid, power_type::mana, 1) > 400)
    	{
    		// cast a spell maybe
    	}
    }
    Haven't tested the code, will probably not work as a copy-pasta but you get the idea. You get rid of all the boilerplate functions like you have in your code, also, singletons are the devil.

  4. Thanks Corthezz, badusername1234 (2 members gave Thanks to ejt for this useful post)
  5. #3
    krustx's Avatar Member
    Reputation
    11
    Join Date
    Nov 2018
    Posts
    6
    Thanks G/R
    2/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Im new to c++, how ever i made this template to invoke functions with diffrent calling conventions:

    Code:
    template<typename Return,uintptr_t addr, typename ...Args>
    Return invoke_stdcall(Args... args){
            return reinterpret_cast<Return ( __stdcall *)( Args...)>(addr)(std::forward<Args> (args) ...);
    }
    //same for fastcall, thiscall...
    auto obj_ptr = invoke_stdcall<uintptr_t, Addresses::function_get_object_by_guid>(guid);
    Last edited by krustx; 05-12-2020 at 05:19 AM.

  6. #4
    CodeBytes's Avatar Member
    Reputation
    14
    Join Date
    Feb 2020
    Posts
    39
    Thanks G/R
    7/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Singletons get a bad rep these days, but they still serve a purpose. I get that they are rigid, and flexibility is often desired; however, can you envision a reason to create multiple instances of an object manager class (for example)? In any case, we could meet in the middle with a template singleton class. That would ensure only one instance of the class exists, and we can still get rid of all the boilerplate functions as in the original example. And yes, these days programmers tend to avoid the singleton like the plague, so skipping out on the singleton altogether is certainly a viable alternative.

  7. #5
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by CodeBytes View Post
    Singletons get a bad rep these days, but they still serve a purpose. I get that they are rigid, and flexibility is often desired; however, can you envision a reason to create multiple instances of an object manager class (for example)? In any case, we could meet in the middle with a template singleton class. That would ensure only one instance of the class exists, and we can still get rid of all the boilerplate functions as in the original example. And yes, these days programmers tend to avoid the singleton like the plague, so skipping out on the singleton altogether is certainly a viable alternative.
    Using singletons is proof of bad programming discipline as they can be avoided in 99.9% of cases they are used.

    As for your example of "can you envision a reason to create multiple instances of an object manager class" and yes I can. When I did my framework I carefully planned it out so it could be used both internally and externally and because of this it also needs to be able to have multiple object-manager instances because when handling multiple instances of wow, you need... multiple instances of an object-manager!

    It is well agreed upon that singletons is bad practice and mostly just lazy implementations because of they are easy to use, however when they eventually become a problem they can be extremely frustrating to get rid of. This is why it has a bad reputation and also why mostly everyone discourages new programmers to stay clear.

    That being said, singletons can be used and are used in many code bases but it needs to be a very carefully thought through design decision and almost always must be a last-resort. Your code could easily be done without singleton, hence why I said it was bad.

    And as a last little note, you didn't even implement the singleton properly because your constructor is publicly available and you didn't remove/private the copy-constructors.

  8. #6
    doityourself's Avatar ★ Elder ★
    Reputation
    1424
    Join Date
    Nov 2008
    Posts
    843
    Thanks G/R
    35/448
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt View Post
    Using singletons is proof of bad programming discipline as they can be avoided in 99.9% of cases they are used.

    As for your example of "can you envision a reason to create multiple instances of an object manager class" and yes I can. When I did my framework I carefully planned it out so it could be used both internally and externally and because of this it also needs to be able to have multiple object-manager instances because when handling multiple instances of wow, you need... multiple instances of an object-manager!

    It is well agreed upon that singletons is bad practice and mostly just lazy implementations because of they are easy to use, however when they eventually become a problem they can be extremely frustrating to get rid of. This is why it has a bad reputation and also why mostly everyone discourages new programmers to stay clear.

    That being said, singletons can be used and are used in many code bases but it needs to be a very carefully thought through design decision and almost always must be a last-resort. Your code could easily be done without singleton, hence why I said it was bad.

    And as a last little note, you didn't even implement the singleton properly because your constructor is publicly available and you didn't remove/private the copy-constructors.
    Short and simple answer: singletons are fine. its not a bad practice at all, it's just another pattern that can be used and is replaced by more complicated fancy things nowadays. singletons ftw

  9. #7
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Singletons as a design pattern is fine, just like global variables are fine.

    The bad practice I was talking about with singletons have to do with implementation and usage or should I say abuse of the pattern.

    What I'm not saying is never use singletons, which I would never say because there are legitimate application of it. For example if you're making a logger for your program, a singleton implementation is perfectly fine.

    My point is don't use singletons just because its easy and fast, it will come back to haunt you and encouraging people to look at them as just another pattern will help them cause problems for themselves when they eventually abuse it.

  10. #8
    Master674's Avatar Elite User
    Reputation
    487
    Join Date
    May 2008
    Posts
    578
    Thanks G/R
    2/23
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt View Post
    Using singletons is proof of bad programming discipline as they can be avoided in 99.9% of cases they are used.

    As for your example of "can you envision a reason to create multiple instances of an object manager class" and yes I can. When I did my framework I carefully planned it out so it could be used both internally and externally and because of this it also needs to be able to have multiple object-manager instances because when handling multiple instances of wow, you need... multiple instances of an object-manager!

    It is well agreed upon that singletons is bad practice and mostly just lazy implementations because of they are easy to use, however when they eventually become a problem they can be extremely frustrating to get rid of. This is why it has a bad reputation and also why mostly everyone discourages new programmers to stay clear.

    That being said, singletons can be used and are used in many code bases but it needs to be a very carefully thought through design decision and almost always must be a last-resort. Your code could easily be done without singleton, hence why I said it was bad.

    And as a last little note, you didn't even implement the singleton properly because your constructor is publicly available and you didn't remove/private the copy-constructors.
    To add to that answer:

    Singletons make your code incredibly hard to unit test and mock. With a proper software architecture you would be able to replace your object manager implementation with a mock interface. This would enable you to write proper unit tests for every class that depends on your object manager.

    Theres a very good reason why the S.T.U.P.I.D. acronym lists Singleton in it.

    • Singleton
    • Tight Coupling
    • Untestability
    • Premature Optimization
    • Indescriptive Naming
    • Duplication

    vs.

    • Single Responsibility Principle
    • Open/Closed Principle
    • Liskov Substitution Principle
    • Interface Segregation Principle
    • Dependency Inversion Principle


    Check out Boost.DI for an example of how to use dependency injection in C++ and get rid of the ugly singletons.

  11. #9
    CodeBytes's Avatar Member
    Reputation
    14
    Join Date
    Feb 2020
    Posts
    39
    Thanks G/R
    7/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt
    And as a last little note, you didn't even implement the singleton properly because your constructor is publicly available and you didn't remove/private the copy-constructors.
    Obvious copy pasta. I think it's safe to assume everyone here is familiar with what a Singleton entails. The fact that you even brought it up suggests that this issue upsets you.

    Originally Posted by ejt
    As for your example of "can you envision a reason to create multiple instances of an object manager class" and yes I can. When I did my framework I carefully planned it out so it could be used both internally and externally and because of this it also needs to be able to have multiple object-manager instances because when handling multiple instances of wow, you need... multiple instances of an object-manager!
    It was an example, but your comment got me thinking about my implementation. In the case of multiple instances of wow, it would be best to use multiple instances of an object manager. On the surface it doesn't seem necessary, because a guid is--after all--a globally unique identifier. However, there could be multiple instances of the object with said guid--for example, multiple wow clients running separate instances of the same dungeon. So in this case I'll have to modify my code. The humor in the irony of the situation does not elude me. Nevertheless, I've only been working on this pet project of mine for a little over two months, and with barely any time to spare. These hobbies are a process, and are refined over time.

    You said your object manager is used both internally and externally. Are you simply referring to a shared library between an external program and an internal dll, or are you talking about something else?

    Finally, as much as I enjoy a good programmer's spar, I'll pass on this one. This is a topic that's been wrung dry.

  12. #10
    ejt's Avatar Contributor
    Reputation
    209
    Join Date
    Mar 2008
    Posts
    166
    Thanks G/R
    3/111
    Trade Feedback
    0 (0%)
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    When using wrongly defined singletons in your own code for yourself its all good however when releasing it in a public forum people with little to no knowledge of what a singleton is will use it and cause problems for themselves. For me personally it's not an issue because I've learned from my mistakes using singletons already and learned when and how to use them so I'm just warning others of the issues with such implementation. Personally it doesn't matter to me if you use singletons for every single class in your project or how you chose to implement them.

    Different instances of wow will obviously have different addresses of the object manager so you either need to have separate instances of a object manager class or do some weird work-around for using it as a singleton. I don't think I need to go into detail as to why the singleton for object manager across multiple wow instances would be a bad idea. But hey, if your only goal is to only be internal and never use multiple instances of your object manager, go ahead and make it a singleton.

    As for how I did it, I made the framework a separate static library so it can be added into any project (exe or dll) and used together with my memory library which is also built with internal and external in mind so it does most of the heavy lifting.

    In the end singletons are like politics, one side things they're good another thinks they're bad.

  13. #11
    CodeBytes's Avatar Member
    Reputation
    14
    Join Date
    Feb 2020
    Posts
    39
    Thanks G/R
    7/7
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ejt
    As for how I did it, I made the framework a separate static library so it can be added into any project (exe or dll) and used together with my memory library which is also built with internal and external in mind so it does most of the heavy lifting.
    This is how I do it too. When I say object manager, I don't mean World of Warcraft's s_curMgr. I mean my own object manager, which stores and manipulates the objects found in each instance of the client. I have a GameWindow class which is not singleton, and a GameWindowMgr class which is. Each WoW client is a GameWindow, and all of the GameWindows are managed by the GameWindowMgr singleton. Likewise, I have entities (Player, Unit, Creature, etc). Each entity represents an object which is detected by my clients. I have a singleton class, ObjectMgr, which manages all of my entities; however, I found a case where the latter is not appropriate, so my ObjectMgr class will no longer be a singleton.

    Computer science is always moving, and new generations find new ways of doing things. This innovation is good, but doesn't mean the old ways should be immediately shunned or totally abolished. Anyway, I updated the original code.

    Originally Posted by Master674
    Theres a very good reason why the S.T.U.P.I.D. acronym lists Singleton in it.

    • Singleton
    • Tight Coupling
    • Untestability
    • Premature Optimization
    • Indescriptive Naming
    • Duplication
    It should be added "When used inappropriately". Optimization is only bad when it's premature. Unfortunately for the guy who put together this acronym, "Inappropriate Singletons" would spoil the fun.

Similar Threads

  1. plz help me to understand function call
    By codedemen in forum WoW Memory Editing
    Replies: 3
    Last Post: 04-20-2015, 02:10 AM
  2. Replies: 4
    Last Post: 10-31-2012, 10:10 AM
  3. Calling an internal function through DLL Injection
    By shikyo in forum WoW Memory Editing
    Replies: 5
    Last Post: 02-05-2010, 06:30 AM
  4. POC Class to Manage Lua Calls and Return Values
    By Xarg0 in forum WoW Memory Editing
    Replies: 7
    Last Post: 01-22-2010, 10:38 AM
  5. What Class to make?
    By iceken in forum World of Warcraft General
    Replies: 17
    Last Post: 09-19-2006, 08:17 AM
All times are GMT -5. The time now is 12:48 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search