-
那天发代码的时候,我发错模块了,结果少了几个操作类,比如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小时内删除。
(完整版)C++内存操作类
最新推荐文章于 2025-07-24 10:54:09 发布