Jump to content


Photo

Some warden stuff (unfinished)


  • Please log in to reply
1 reply to this topic

#1 Master674

Master674

    Newbie

  • Administrators
  • 3 posts

Posted 22 November 2014 - 05:41 PM

Some warden stuff I was implementing... not tested and unfinished (I just started with it)

 

WardenClient.h:

/**************************************
 *    This file is part of Genesis    *
 *       Copyright (C) 2012-2014      *
 **************************************/

#pragma once

namespace Genesis {
namespace Game {
    class WardenClient {
        SINGLETON_CLASS(WardenClient) = default;

    public:
        #pragma pack(push, 4)
        struct RawModule {
           /**
            * Warden header that describes the size and base of the module.
            */
            struct Win32Loader {
                uintptr_t  modBaseAddr;   // @0
                size_t     moduleSize;    // @4 / @8 (x64)
            } *win32Loader;
        };

        struct ImportTable {
            const char  *moduleName;      // @0
            const void **importProc;      // @4 / @8 (x64)
        };
        #pragma pack(pop)

       /**
        * \brief    Initialize and attach hooks (if a module is present).
        *           If no module is present, the static hooks are applied.
        */
        void initialize();

       /**
        * \brief    Remove all warden hooks and shutdown.
        */
        void shutdown();

       /**
        * \brief    Get a pointer to the current RawModule structure.
        * \returns  A pointer to the RawModule structure or nullptr.
        */
        RawModule* getRawModule() const;

       /**
        * \brief    Get a pointer to the current ImportTable structure.
        * \returns  A pointer to the ImportTable structure or nullptr.
        */
        ImportTable* getImports(RawModule *rawModule, size_t *count) const;

       /**
        * \brief    Sets the log level of this class.
        * \param    level  The log level to set.
        */
        void setLogLevel(LogLevel level) const {
            getLogger()->setLogLevel(level);
        }

    private:
       /**
        * \brief    Attach hooks to the given warden module.
        * \param    rawModule  The raw warden module.
        * \returns  True if successful, false otherwise.
        */
        bool attachModuleHooks(RawModule *rawModule);

       /**
        * \brief    Detach hooks if present.
        */
        void detachModuleHooks();

       /**
        * \brief    Scans the warden module for the internal memcpy function.
        * \returns  A pointer to the memcpy function or nullptr.
        */
        uintptr_t findCopyMemory(RawModule* rawModule) const;

    private:
        typedef RawModule* (__cdecl *Warden__RawModule__Create_t) (const void *buffer, size_t size);
        Warden__RawModule__Create_t Warden__RawModule__Create = nullptr;
        static RawModule* __cdecl Warden__RawModule__CreateHook(const void *buffer, size_t size);

        typedef void (__cdecl *Warden__RawModule__Destroy_t) (RawModule *rawModule);
        Warden__RawModule__Destroy_t Warden__RawModule__Destroy = nullptr;
        static void __cdecl Warden__RawModule__DestroyHook(RawModule *rawModule);

        typedef void* (__cdecl *WardenModule__CopyMemory_t) (void *dst, const void *src, size_t size);
        WardenModule__CopyMemory_t WardenModule__CopyMemory = nullptr;
        static void* __cdecl WardenModule__CopyMemoryHook(void *dst, const void *src, size_t size);

    private:
        DEF_LOGGER(getLogger, "WardenClient", LogLevel::Error);

        template <typename T>
        void attachDetour(T *pDelegate, void *pRedirect) const {
            if (*pDelegate != nullptr && pRedirect != nullptr)
                sMemory.detourFunction(reinterpret_cast<void**>(pDelegate), pRedirect);
        }

        template <typename T>
        void removeDetour(T *pDelegate) const {
            if (*pDelegate != nullptr)
                sMemory.removeDetour(reinterpret_cast<void**>(pDelegate));
        }
    };
} //--> Game
} //--> Genesis

#define sWardenClient Genesis::Game::WardenClient::Instance()

WardenClient.cpp:

 

/**************************************
 *    This file is part of Genesis    *
 *       Copyright (C) 2012-2014      *
 **************************************/

#include "PCH/StdAfx.h"
#include "WardenClient.h"
#include "GameOffsets.h"
#include "Utils/SharkMemory.h"

namespace Genesis {
namespace Game {
    void WardenClient::initialize() {
        Warden__RawModule__Create = (Warden__RawModule__Create_t) sGameOffsets.Warden.RawModule.Create;
        Warden__RawModule__Destroy = (Warden__RawModule__Destroy_t) sGameOffsets.Warden.RawModule.Destroy;

        attachDetour(&Warden__RawModule__Create, Warden__RawModule__CreateHook);
        attachDetour(&Warden__RawModule__Destroy, Warden__RawModule__DestroyHook);

        if (RawModule *rawModule = getRawModule()) {
            if (!attachModuleHooks(rawModule))
                throw NX(Utils::RuntimeError, "Failed to attach warden hooks!");
        }
    }

    void WardenClient::shutdown() {
        removeDetour(&Warden__RawModule__Create);
        removeDetour(&Warden__RawModule__Destroy);
        detachModuleHooks();
    }

    bool WardenClient::attachModuleHooks(RawModule *rawModule) {
        uintptr_t copyMemory = findCopyMemory(rawModule);
        if (!copyMemory)
            return false;

        WardenModule__CopyMemory = (WardenModule__CopyMemory_t) copyMemory;
        attachDetour(&WardenModule__CopyMemory, WardenModule__CopyMemoryHook);
        return true;
    }

    void WardenClient::detachModuleHooks() {
        removeDetour(&WardenModule__CopyMemory);
        WardenModule__CopyMemory = nullptr;
    }

    WardenClient::RawModule* WardenClient::getRawModule() const {
        return sMemory.getMemory<RawModule*>(sGameOffsets.Warden.CurrentModule);
    }

    WardenClient::ImportTable* WardenClient::getImports(RawModule *rawModule, size_t *count) const {
        RawModule::Win32Loader* ldr = rawModule->win32Loader;
        if (!ldr || !ldr->modBaseAddr)
            return nullptr;

#ifdef _M_IX86
        *count = sMemory.getMemory<uint32_t>(ldr->modBaseAddr + 0x2C);
        uintptr_t offImportRel = sMemory.getMemory<uintptr_t>(ldr->modBaseAddr + 0x28);
#elif _M_X64

#endif
        if (!offImportRel)
            return nullptr;
        return reinterpret_cast<ImportTable*>(offImportRel + ldr->modBaseAddr);
    }

    uintptr_t WardenClient::findCopyMemory(RawModule *rawModule) const {
#ifdef _M_IX86
        const byte pattern[] = {
            0x56,                    /* push esi          */
            0x57,                    /* push edi          */
            0xFC,                    /* cld               */
            0x8B, 0x54, 0x24, 0x14,  /* mov edx, [esp+14] */
            0x8B, 0x74, 0x24, 0x10   /* mov esi, [esp+10] */
        };

        const char mask[] = "xxxxxxxxxxx";
#elif _M_X64

#endif
        if (RawModule::Win32Loader* l = rawModule->win32Loader)
            return sMemory.findPattern(l->modBaseAddr, l->moduleSize, pattern, mask);
        return 0;
    }

    WardenClient::RawModule* __cdecl WardenClient::Warden__RawModule__CreateHook(const void *buffer, size_t size) {
        RawModule *rawModule = sWardenClient.Warden__RawModule__Create(buffer, size);
        if (rawModule && !sWardenClient.attachModuleHooks(rawModule))
            throw NX(Utils::RuntimeError, "Failed to attach warden hooks!");

        return rawModule;
    }

    void __cdecl WardenClient::Warden__RawModule__DestroyHook(RawModule *rawModule) {
        sWardenClient.detachModuleHooks();
        sWardenClient.Warden__RawModule__Destroy(rawModule);
    }

    void* __cdecl WardenClient::WardenModule__CopyMemoryHook(void *dst, const void *src, size_t size) {
        if (src != nullptr && size != 0) {
            uintptr_t scanStart = reinterpret_cast<uintptr_t>(src);
            uintptr_t imageBase = sGameOffsets.getAppImageBase();
            uintptr_t imageSize = sGameOffsets.getAppImageSize();

            if (scanStart + size > imageBase && scanStart < imageBase + imageSize) {
                std::ostringstream message;

                void* ofsScanStart = reinterpret_cast<void*>(scanStart - imageBase);
                message << "Scanned offset 0x" << ofsScanStart << ", size: " << size << " (";

                const byte* buffer = static_cast<const byte*>(src);
                for (size_t i = 0; i < size; ++i) {
                    if (i != 0)
                        message << ' ';

                    message << std::hex << std::setfill('0') << std::setw(2)
                            << std::uppercase << static_cast<int>(buffer[i]);
                }

                message << ')';
                getLogger()->fine(message.str());
            }
        }

        return sWardenClient.WardenModule__CopyMemory(dst, src, size);
    }
} //--> Game
} //--> Genesis

Feel free to use it/add some new stuff.


  • 1

#2 JuJuBoSc

JuJuBoSc

    Newbie

  • Members
  • Pip
  • 3 posts

Posted 22 November 2014 - 07:57 PM

the copy memory pattern for x64 : (PBYTE)"\x48\x83\xEC\x08\x56\x57\xFC\x48\x8B\xF9", "xxxxxxxxxx"


  • 1




2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users