• 那天发代码的时候,我发错模块了,结果少了几个操作类,比如Process类,Module类,今天补上完整的,

    写外挂类的非常方便

    Procmem.h

    #ifndef PROCMEM_H //If Not Defined
    #define PROCMEM_H //Define Now
    
    #define WIN32_LEAN_AND_MEAN //Excludes Headers We Wont Use (Increase Compile Time)
    
    #include <windows.h> //Standard Windows Functions/Data Types
    #include <iostream> //Constains Input/Output Functions (cin/cout etc..)
    #include <TlHelp32.h> //Contains Read/Write Functions
    #include <string> //Support For Strings
    #include <sstream> //Supports Data Conversion
    
    class ProcMem{
    protected:
    
        //STORAGE
        HANDLE hProcess;
        DWORD dwPID, dwProtection, dwCaveAddress;
    
        //MISC
        BOOL bPOn, bIOn, bProt;
    
    public:
    
        //MISC FUNCTIONS
        ProcMem();
        ~ProcMem();
        int chSizeOfArray(char *chArray); //Return Size Of External Char Array
        int iSizeOfArray(int *iArray); //Return Size Of External Int Array
        bool iFind(int *iAry, int iVal); //Return Boolean Value To Find A Value Inside An Int Array
    
    #pragma region TEMPLATE MEMORY FUNCTIONS
    
        //REMOVE READ/WRITE PROTECTION
        template <class cData>
        void Protection(DWORD dwAddress)
        {
            if (!bProt)
                VirtualProtectEx(hProcess, (LPVOID)dwAddress, sizeof(cData), PAGE_EXECUTE_READWRITE, &dwProtection); //Remove Read/Write Protection By Giving It New Permissions
            else
                VirtualProtectEx(hProcess, (LPVOID)dwAddress, sizeof(cData), dwProtection, &dwProtection); //Restore The Old Permissions After You Have Red The dwAddress
    
            bProt = !bProt;
        }
    
        //READ MEMORY 
        template <class cData>
        cData Read(DWORD dwAddress)
        {
            cData cRead; //Generic Variable To Store Data
            ReadProcessMemory(hProcess, (LPVOID)dwAddress, &cRead, sizeof(cData), NULL); //Win API - Reads Data At Specified Location 
            return cRead; //Returns Value At Specified dwAddress
        }
    
        //READ MEMORY - Pointer
        template <class cData>
        cData Read(DWORD dwAddress, char *Offset, BOOL Type)
        {
            //Variables
            int iSize = iSizeOfArray(Offset) - 1; //Size Of *Array Of Offsets 
            dwAddress = Read<DWORD>(dwAddress); //HEX VAL
    
            //Loop Through Each Offset & Store Hex Value (Address)
            for (int i = 0; i < iSize; i++)
                dwAddress = Read<DWORD>(dwAddress + Offset[i]);
    
            if (!Type)
                return dwAddress + Offset[iSize]; //FALSE - Return Address
            else
                return Read<cData>(dwAddress + Offset[iSize]); //TRUE - Return Value
        }
    
        //WRITE MEMORY
        template <class cData>
        void Write(DWORD dwAddress, cData Value)
        {
            WriteProcessMemory(hProcess, (LPVOID)dwAddress, &Value, sizeof(cData), NULL);
        }
    
        //WRITE MEMORY - Pointer
        template <class cData>
        void Write(DWORD dwAddress, char *Offset, cData Value)
        {
            Write<cData>(Read<cData>(dwAddress, Offset, false), Value);
        }
    
        //MEMORY FUNCTION PROTOTYPES
        virtual void Process(char* ProcessName); //Return Handle To The Process
        virtual void Patch(DWORD dwAddress, char *chPatch_Bts, char *chDefault_Bts); //Write Bytes To Specified Address
        virtual void Inject(DWORD dwAddress, char *chInj_Bts, char *chDef_Bts, BOOL Type); //Jump To A Codecave And Write Memory
        virtual DWORD AOB_Scan(DWORD dwAddress, DWORD dwEnd, char *chPattern); //Find A Byte Pattern
        virtual DWORD Module(LPSTR ModuleName); //Return Module Base Address
    
    #pragma endregion   
    
    };
    #endif
    

    ProcMem.cpp

    #include "ProcMem.h"
    
    using namespace std;
    
    #pragma region Misc Functions
    
    ProcMem::ProcMem(){
        //Constructor For Class, Do Not Remove!
    }
    
    ProcMem::~ProcMem(){
        //De-Constructor
        //Clean Up! (Close Handle - Not Needed Anymore)
        CloseHandle(hProcess);
    }
    
    /* This Function Returns The Length Of External Char Arrays, SizeOf(Array) Fails For External Arrays. */
    int ProcMem::chSizeOfArray(char *chArray){
    
        //Loop Through *chArray To Get Amount Of Bytes
        for (int iLength = 1; iLength < MAX_PATH; iLength++)
            if (chArray[iLength] == '*')
                return iLength;
    
        cout << "\nLENGTH: Failed To Read Length Of Array\n";
        return 0;
    }
    
    /* This Function Returns The Length Of External Int Arrays, SizeOf(Array) Fails For External Arrays. */
    int ProcMem::iSizeOfArray(int *iArray){
    
        //Loop Through *chArray To Get Amount Of Bytes
        for (int iLength = 1; iLength < MAX_PATH; iLength++)
            if (iArray[iLength] == '*')
                return iLength;
    
        cout << "\nLENGTH: Failed To Read Length Of Array\n";
        return 0;
    }
    
    /* This Function Finds The Specified Value Inside Of Arrays And Returns A Boolean Value,
    /* Used For Triggerbot To Find The Current Crosshair Entity i_NearEntity Inside The Enemy Array. */
    bool ProcMem::iFind(int *iAry, int iVal){
    
        for (int i = 0; i < 64; i++)
            if (iVal == iAry[i] && iVal != 0)
                return true;
    
        return false;
    }
    
    #pragma endregion
    
    #pragma region Memory Functions
    
    /* This Function Will Return A Handle To The Process So We Can Write & Read Memeory From The Process. */
    void ProcMem::Process(char* ProcessName){
    
        //Variables
        HANDLE hPID = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); //Snapshot To View All Active Processes
        PROCESSENTRY32 ProcEntry;
        ProcEntry.dwSize = sizeof(ProcEntry); //Declare Structure Size And Populate It
    
        //Loop Through All Running Processes To Find Process
        do
            if (!strcmp(ProcEntry.szExeFile, ProcessName))
            {
            //Store Process ID
            dwPID = ProcEntry.th32ProcessID;
            CloseHandle(hPID);
    
            //Give Our Handle All Access Rights 
            hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
            return;
            }
        while (Process32Next(hPID, &ProcEntry));
    
        cout << "\nPROCESS: Process Not Found\n";
        system("pause");
        exit(0);
    }
    
    /* This Function Will Write Specified Bytes To The Address, And Can Also Be Reverted Back To Normal
    /* Just Call It Again As It Works On A Boolean. */
    void ProcMem::Patch(DWORD dwAddress, char *Patch_Bts, char *Default_Bts){
    
        //Variables
        int iSize = chSizeOfArray(Default_Bts);
    
        //Loop Through Addresses Writing Bytes
        if (!bPOn)
            for (int i = 0; i < iSize; i++)
                Write<BYTE>(dwAddress + i, Patch_Bts[i]);
        else
            for (int i = 0; i < iSize; i++)
                Write<BYTE>(dwAddress + i, Default_Bts[i]);
    
        bPOn = !bPOn;
    }
    
    /* This Function Is Similiar To Cheat Engine's Code Injection Function, It's Able To Create JMP's
    /* To A Codecave And Write New Memory. Untested CALL Command */
    void ProcMem::Inject(DWORD dwAddress, char *Inj_Bts, char *Def_Bts, BOOL Type){
    
        //Variables
        int i_ISize = chSizeOfArray(Inj_Bts);
        int i_DSize = chSizeOfArray(Def_Bts);
    
        if (!bIOn)
        {
            //NOP All Bytes In The Array Past The 5th Byte  
            if (i_DSize > 5)
                for (int i = 6; i < i_DSize; i++)
                    Write<BYTE>(dwAddress + i, 0x90);
            else { cout << "\nINJECTION: Default Bytes Must Be More Than 5\n"; return; }
    
            //Create Codecave
            dwCaveAddress = (DWORD)VirtualAllocEx(hProcess, NULL, i_ISize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    
            //Calculate Jmp/Return Distances In Bytes To Write
            DWORD dwRetJmp = (dwAddress + i_DSize) - dwCaveAddress - 5; //(NextInstruction - CaveAddress - 5) - is correct equation.
            DWORD dwBaseJmp = dwCaveAddress - dwAddress - 5; //Base Jmp
    
            //Loop Through Each Address Writing Inj_Bts Inside The Codecave
            for (int i = 0; i <= i_ISize; i++)
                Write<BYTE>(dwCaveAddress + i, Inj_Bts[i]);
    
            //Write The Return Distance In Bytes (E9 = Jmp | E8 = Call) To The Original Address
            Write<BYTE>(dwCaveAddress + i_ISize, Type ? 0xE9 : 0xE8);
            Write<DWORD>(dwCaveAddress + i_ISize + 1, dwRetJmp);
    
            //Write The Jump From The Original Address To The Codecave
            Write<BYTE>(dwAddress, Type ? 0xE9 : 0xE8);
            Write<DWORD>(dwAddress + 1, dwBaseJmp);
    
        }
        else{
            //Restore Original Bytes
            for (int i = 0; i < i_DSize; i++)
                Write<BYTE>(dwAddress + i, Def_Bts[i]);
    
            //Clean Up! (DeAllocate CodeCave)
            VirtualFreeEx(hProcess, (LPVOID)dwCaveAddress, i_ISize + 5, MEM_DECOMMIT);
        }
        bIOn = !bIOn;
    }
    
    /* Basic Byte Scanner, Will Return The Start Address Of The Specififed Byte Pattern.
    /* To-Do: Re-Write Using Memory_Page Functions To Grab Blocks Of Memory And Scan
    /* It Inside This Console, Maybe Study Multi-Threading For Faster Scanning. */
    DWORD ProcMem::AOB_Scan(DWORD dwAddress, DWORD dwEnd, char *Bytes){
    
        //VARIABLES
        int iBytesToRead = 0, iTmp = 0;
        int length = chSizeOfArray(Bytes);
        bool bTmp = false;
    
        //Check If The Start Of The Array Has Wildcards, So We Can Change The Count
        if (Bytes[0] == '?')
        {
            for (; iBytesToRead < MAX_PATH; iBytesToRead++)
                if (Bytes[iBytesToRead] != '?')
                {
                iTmp = (iBytesToRead + 1);
                break;
                }
        }
    
        //Increase Start Address Till It Reaches The End Address While Reading Bytes
        for (; dwAddress < dwEnd; dwAddress++)
        {
            if (iBytesToRead == length)
                return dwAddress - iBytesToRead;
    
            if (Read<BYTE>(dwAddress) == Bytes[iBytesToRead] || (bTmp && Bytes[iBytesToRead] == '?'))
            {
                iBytesToRead++;
                bTmp = true;
            }
            else
            {
                iBytesToRead = iTmp;
                bTmp = false;
            }
        }
    
        cout << "\nAOB_SCAN: Failed To Find Byte Pattern\n";
        return 0;
    }
    
    /* Returns The Base Address Of The Specified Module Inside The Target Process
    /* e.g.[ Module("client.dll"); ]. */
    DWORD ProcMem::Module(LPSTR ModuleName){
    
        //Variables
        HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); //Take A Module Snapshot Of The Process (Grab All Loaded Modules)
        MODULEENTRY32 mEntry; //Declare Module Entry Structure
        mEntry.dwSize = sizeof(mEntry); //Declare Structure Size And Populate It With Loaded Modules
    
        //Scan For Module By Name
        do
            if (!strcmp(mEntry.szModule, ModuleName))
            {
            CloseHandle(hModule);
            return (DWORD)mEntry.modBaseAddr;
            }
        while (Module32Next(hModule, &mEntry));
    
        cout << "\nMODULE: Process Platform Invalid\n";
        return 0;
    }
    
    #pragma endregion
    

    注意:部分代码收集自网络,如果侵权或违法任何规定,我们将在24小时内删除。