Source Code Nether's V1.4 C++ Memory Class

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Hey Guys,

After days of study and working on other projects I have been able to update almost everything about my previous class. Unfortunatley C++ wants to be anoying and gives me problems for my return jump inject function so that will have to be fixed, I wanted to release now as im working on some new projects mainly internally(and VB Memory Class). I would really love some feedback on this - i know you may be busy but if you ever get a chance to look at the code and let me know what could be updated I would really apreciate it.

UPDATES:

Cleaned Code + Updated some small things such >0 to !.
Changed Char Array End Sequence Character To '*'.
Updated Error Handling.
Added De-Constructor.
All Handle's Now Correctly Close When Finished With.
Updated Read/Write Functions (Protection).
Merged ProcMem Class Into Includes.
Updated ReadMe File.
Added GetProcess Function - Was Unstable In Constructor.
Shortened Write Pointer Function.
Removed Unnecessary brackets.
Organized Header Class Into Correct Order.
Included Lean And Mean To exclude unused headers, faster compiling time.
included <stdint.h> for more precise data reading/writing data options.
Added Null Pointer Support For Reading Pointers.
Read/Write Pointers can now be accessed via same name, just write what you need.
Formatted Code As Much As Possible.
Added Notations (Hungarian/Google mix)

IMPORTANT: Use '*' now at the end of char arrays instead of '?'

To-Do List:

Add Functionality For Reading/Writing Strings.
Update Again With C++ 11 Features.(already added a few and some includes)
fix inject function.

Usage:
Source.cpp
C++:
#include "Includes.h"
using namespace std;

//Create Class Object
ProcMem mem; 

int main( void )
{
    mem.GetProcess("BlackOps.exe"); //Declare Process
    DWORD Base = mem.dwBase;
    DWORD Client = mem.Module("client.dll");

    while(1)
    {
        if(GetAsyncKeyState(VK_HOME) & 1)
        {
            //WRITE MEMORY & POINTERS
            mem.Write<int>(Base+0x5FFFB6, 1337);
            mem.Write<int>(Base+0x5FFFB6, "\x48\xCC\x9F\*", 1337);
            mem.Write<string>(0x4CEDE2, "herro"); //If you uncheck unicdoe in CE address view, youll see your text, i will add support for unicode later              

            //READ MEMORY & POINTERS
            mem.Read<int>(Base+0x5FFFB6);
            mem.Read<int>(Base+0x5FFFB6, "\x48\xCC\x9F\*", true); //True Return Value | False Returns Address

            //PATCH MEMORY
            mem.Patch(0xFB8623C, "\x90\x90\x90\x90\*", "\x8B\xC3\xD1\x62\*");

            //AOB SCAN MEMORY
            mem.AOB_Scan(Client+0x55FB67, Client+0x5FFFFF, "\?\xB9\xC7\x24\x46\?\?\x32\x12\*", false); //false returns the address at the bytes | true returns the address after bytes

            //CODECAVE MEMORY INJECTION JMP/CALL
            mem.Inject(0xBFAFA81, "\xC7\xCC\x99\xBB\x23\x89\*", "\x77\x54\x8B\xC3\xD1\x62\*", true); // true = jmp | false = call
        }
    }
    return 0;
}

C++:
Includes.h
#ifndef INCLUDES_H //If Not Defined
#define INCLUDES_H //Define Now
#define WIN32_LEAN_AND_MEAN //Excludes Headers We Wont Use (Increase Compile Time)

#include <iostream> //Constains Input/Output Functions (cin/cout etc..)
#include <windows.h> //Standard Windows Header
#include <TlHelp32.h> //Contains Read/Write Functions
#include <string> //Support For Strings
#include <ctime> //Time Information (Create Timers etc..)
#include <stdint.h> //Declare Specific Data Types int16_t | int32_t etc (for reading writing)
#include <cmath> //Math Functions






ProcMem.cpp
#include "Includes.h"

using namespace std;
ProcMem::ProcMem(){
    //Constructor For Class, Do Not Remove!
}

void ProcMem::GetProcess(char* ProcessName){

    #pragma region Get Process ID

    //Create Handle & Snapshot To View All Active Processes
    HANDLE hPID = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 

    //Declare Structure Size And Populate It With Active Process Information
    pEntry.dwSize = sizeof(PROCESSENTRY32); 

    //Check The First Process To See If Its The One We Want
    if (Process32First(hPID, &pEntry)) 
    {    
        //Loop Through All Running Processes Scanning For szExeFile Parameter Of pEntry
        do
        {        
            //Compare If String1 (pEntry.szExeFile) Is Identical To String2 (ProcessName)
            if (!strcmp(pEntry.szExeFile, ProcessName)) 
            {
                //Store Process ID Into The Variable dwPID
                dwPID = pEntry.th32ProcessID;     
                break; 
            }                        
        }while (Process32Next(hPID, &pEntry)); 
    }

    //Clean Up! (Close Handle - Not Needed Anymore)
    CloseHandle(hPID);

#pragma endregion

    if (dwPID)
    {
        //Give Our Handle All Access Rights 
     hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); 

        //Take A Module Snapshot Of The Process (Grab All Loaded Modules)
HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 

        //Declare Structure Size And Populate It With Loaded Modules
mEntry.dwSize = sizeof(MODULEENTRY32); 

        //Error Handeling, If Your Reading A 64-Bit Process But Compile As 32-Bit It Will Throw Error
        if(!Module32First(hModule, &mEntry)) 
            exit(2);

        //Check The First Module, Is Always Process.exe And Grab Address And Store It In dwBase
        Module32First(hModule, &mEntry);
     dwBase = (DWORD)mEntry.modBaseAddr;

        //Clean Up! (Close Handle - Not Needed Anymore)
CloseHandle( hModule ); 
    }

    else 
        exit(1);
}

DWORD ProcMem::AOB_Scan(DWORD dwStart, DWORD dwEnd, char *Bytes, BOOL Type){

    //VARIABLES
    int iBytesToRead = 0; //Counter For Scan
    BYTE rBytes; //Storage To Hold A Single Byte To Read (Compare Read To Char *Array)
    int length = GetLength(Bytes); //Size Of *Array (*Bytes)

    //Increase Start Address Till It Reaches The End Address
    for(dwStart; dwStart < dwEnd; dwStart++) 
    {
        //Wildcard Support - Check If First Array Element Is '?' And Keep Inreasing Array Index Till We See A Byte
        while (Bytes[iBytesToRead] == '?')                                    
            iBytesToRead++; 

        //Read Bytes And Store Them In rBytes To Compare
        rBytes = Read<BYTE>(dwStart);
        
        //When A Byte That Has Been Red Matches One Of Our *Array Elements
        if (rBytes == Bytes[iBytesToRead]) 
        {
            do{        
                dwStart++; //Increment The Address By 1 To Scan The Next Byte        
                iBytesToRead++; //Increment The *Array Index To Read/Compare        
                rBytes = Read<BYTE>(dwStart); //Read The Next Byte
            
                //Wildcard Checker, If You Have Wildcards In The Middle/End Off Array
                while (Bytes[iBytesToRead] == '?')         
                {                         
                    dwStart++;                 
                    iBytesToRead++;                 
                    rBytes = Read<BYTE>(dwStart);    
                }
                
            }while (rBytes == Bytes[iBytesToRead]); //While rBytes Matches An Element In Our *Array Keep Scanning Till We Reach *Array Length    
            
            //Reset Counter To Carry On Searching Bytes If Bytes Not Found
            if(iBytesToRead != length)
                iBytesToRead = 0;
        }
                
        //Scan Complete Outcomes
        if (iBytesToRead >= length)    
        {                    
            if (Type)            
                return dwStart - iBytesToRead; //Return The Address - The Ammount Of Bytes Red                        
            else                
                return dwStart; //Return The Address After Bytes            
        }        
    }    
    return 3;
}

BOOL ProcMem::Inject(DWORD dwAddress, char *Inj_Bts, char *Def_Bts, BOOL Type){
    
    //Get Array Lengths
    int i_ISize = GetLength(Inj_Bts);
    int i_DSize = GetLength(Def_Bts); 

    if (!bIOn)
    {
        //Create Codecave
        dwCaveAddress = (DWORD)VirtualAllocEx(hProcess, NULL, i_ISize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

        cout << hex << dwCaveAddress << endl;

        //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);

        //NOP All Bytes In The Array Past The 5th Byte    
        if (i_DSize >= 5)
        {
            for (int i = 5; i < i_DSize; i++)    
                Write<BYTE>(dwAddress + i, 0x90);
        }
        else return 4;
    }    
        
    if (bIOn)
    {            
        //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);
    }
return bIOn = !bIOn; //Set bIOn To Opposite So When Called Again It Executs The Off Statement (Bottom)
} 

DWORD ProcMem::Module(LPSTR lModule){

    //Take A Module Snapshot Of The Process (Grab All Loaded Modules)
    HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 

    //Declare Structure Size And Populate It With Loaded Modules
    mEntry.dwSize = sizeof(MODULEENTRY32); 

    //Check All Modules Except First As That Is Always Process.exe And Return The Module Base (E.g client.dll)
    do 
    {
        if (!strcmp(mEntry.szModule, lModule))        
        {    
            CloseHandle(hModule); //Clean Up! (Close Handle - Not Needed Anymore)
            return (DWORD)mEntry.modBaseAddr;
        }
    }while (Module32Next(hModule, &mEntry));
    
    CloseHandle(hModule); //Clean Up! (Close Handle - Not Needed Anymore)            
    return 5;
        
}

ProcMem::~ProcMem(){

    //Clean Up! (Close Handle - Not Needed Anymore)
    CloseHandle(hProcess);
}


Credits:
@Agent Smith - Is a good friend :D and pointed me in the right direction as to where I could study as i hate being spoonfed :p

Hungarian Notation - Wi - Mixed with google styling
Google C++ Styling Guide - Helped me realize alot of things I was doing wrong, i wil ltry to follow this style of coding in future projects :)

Since I cant upload rar files, as my net is so bad right now i cant upload the source(or to virus scans) so i will have to post it, Mods - feel free to to put into a zip file and remove posts below

PS: If anyone can tell me why my return jump in the inject function is failing i would really apreciate it, i know the maths is correct as its exactly how i did it in VB change in languages doesnt change equations only the way they are written so :)
 

Attachments

Last edited:

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Includes.h
C++:
#ifndef INCLUDES_H //If Not Defined
#define INCLUDES_H //Define Now
#define WIN32_LEAN_AND_MEAN //Excludes Headers We Wont Use (Increase Compile Time)

#include <iostream> //Constains Input/Output Functions (cin/cout etc..)
#include <windows.h> //Standard Windows Header
#include <TlHelp32.h> //Contains Read/Write Functions
#include <string> //Support For Strings
#include <ctime> //Time Information (Create Timers etc..)
#include <stdint.h> //Declare Specific Data Types int16_t | int32_t etc (for reading writing)
#include <cmath> //Math Functions

class ProcMem{

public:
	
	//PUBLIC STORAGE
	DWORD dwBase; //Storage For Process Base Address

	//FUNCTION PROTOTYPES
	ProcMem(); //Constructor
	~ProcMem(); //DeConstructor
	void GetProcess(char* ProcessName);
	DWORD AOB_Scan(DWORD dwStart, DWORD dwEnd, char *Bytes, BOOL Type);
	BOOL Inject(DWORD dwAddress, char *Inj_Bts, char *Def_Bts, BOOL Type);
	DWORD Module(LPSTR lModule);

#pragma region MEMORY FUNCTIONS

	//Get Length Of *Array's
	int GetLength(char *chArray){
	
		//Variables
		int iLength = NULL;
 		
		//Loop Through *chArray To Get Ammount Of Bytes
		for(int i = 1; i < 100; i++)
		{
			iLength++;
			if (chArray[i] == '*')
				break;	
		} 
		return iLength;
	} 

	//READ MEMORY
	template <class cData>
	
	cData Read(DWORD dwAddress)
	{
       cData vRead; //Generic Variable To Store Data
	   VirtualProtectEx(hProcess, (LPVOID)dwAddress, sizeof(cData), PAGE_EXECUTE_READWRITE, &dwProt); //Remove Read/Write Protection By Giving It New Permissions
       ReadProcessMemory(hProcess, (LPVOID)dwAddress, &vRead, sizeof(cData), NULL); //Win API - Reads Data At Specified Location 
	   VirtualProtectEx(hProcess, (LPVOID)dwAddress, sizeof(cData), dwProt, &dwProt2); //Restore The Old Permissions After You Have Red The dwAddress
	   return vRead; //Returns Value At Specified dwAddress
	}
    
	//WRITE MEMORY
	template <class cData>
	
	void Write(DWORD dwAddress, cData ValueToWrite)
	{	
		VirtualProtectEx(hProcess, (LPVOID)dwAddress, sizeof(cData), PAGE_EXECUTE_READWRITE, &dwProt);	
		WriteProcessMemory(hProcess, (LPVOID)dwAddress, &ValueToWrite, sizeof(cData), NULL);	
		VirtualProtectEx(hProcess, (LPVOID)dwAddress, sizeof(cData), dwProt, &dwProt2);
	}
	
	//READ MEMORY - Pointer
	template <class cData>
	
	cData Read(DWORD dwAddress, char *Offset, BOOL Type){

		//Variables
		cData vReadP; //Generic Data Type
		int iSize = GetLength(Offset); //Size Of *Array Of Offsets 	  
		DWORD dwTMP; //Storage For Address + Red Bytes

		//Read The Hex Value Of The dwAddress
		vReadP = Read<cData>((DWORD)dwAddress);	

		//Loop Through Each Offset & Store Hex Value (Address) In dwTMP
		for (int i = 0; i < iSize; i++)
		{			
		    dwTMP = vReadP + Offset[i];
			vReadP = Read<cData>((DWORD)dwTMP);

			//If Pointer Is 0 Return Error
			if (!vReadP)
				return 6;
		}  	
		
		if (!Type)
			return dwTMP; //FALSE - Return Address
		else
			return vReadP; //TRUE - Return Value
	}

	//WRITE MEMORY - Pointer
	template <class cData>
	
	void Write(DWORD dwAddress, char *Offset, cData Val){

		//Variables  
		DWORD dwTMP; //Storage For Address + Red Bytes
	
		//Read Pointers
		dwTMP = Read<cData>(dwAddress, Offset, false);

		//Write To The Address Stored In dwTMP
		Write<cData>(dwTMP, Val); 	
	}	

	//PATCH MEMORY
	void Patch(DWORD dwAddress, char *Patch_Bts, char *Default_Bts){
 
		//Get Size Of Char *Array
		int iSize = GetLength(Default_Bts);		

		if (!bOn)
		{
			//Loop Through Each Address(BYTE) Writing Inject_Bts[i]
			for(int i = 0; i < iSize; i++)	
			{	
				DWORD dwTMP = dwAddress + i;		
				Write<BYTE>(dwTMP, Patch_Bts[i]);	
			}
		}
		else
		{
			//Re-Write Original Bytes (Default_Bts[i]) Back To The Address++ 
			for(int i = 0; i < iSize; i++)	 
			{		
				DWORD dwTMP = dwAddress + i;			
				Write<BYTE>(dwTMP, Default_Bts[i]);        
			}        
		}	

		//Set bOn To Opposite So When Called Again It Executs The Off Statement
		bOn = !bOn; 
	}

#pragma endregion	

private:

	//HANDLES
	HANDLE hProcess; //Main Handle
	
	//ENTRY POINTS
	MODULEENTRY32 mEntry; //Declare Module Entry Structure
	PROCESSENTRY32 pEntry; //Declare Process Entry Structure

	//STORAGE
    DWORD dwPID; //Storage For Process ID
	DWORD dwProt; //Storage For VirtualProtectEx Previous Protection
	DWORD dwProt2; //Storage For VirtualProtectEx New Protection Var
	DWORD dwCaveAddress; //Storage For Codecave Address	

	//MISC
	BOOL bOn; //Boolean For Patch Function (On/Off)
	BOOL bIOn; //Boolean For Inject Function (On/Off)
};
#endif
 

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
ProcMem.cpp
C++:
#include "Includes.h"

using namespace std;

ProcMem::ProcMem(){
	//Constructor For Class, Do Not Remove!
}

void ProcMem::GetProcess(char* ProcessName){

	#pragma region Get Process ID

	//Create Handle & Snapshot To View All Active Processes
	HANDLE hPID = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 

	//Declare Structure Size And Populate It With Active Process Information
	pEntry.dwSize = sizeof(PROCESSENTRY32); 

	//Check The First Process To See If Its The One We Want
	if (Process32First(hPID, &pEntry)) 
	{	
		//Loop Through All Running Processes Scanning For szExeFile Parameter Of pEntry
		do
		{		
			//Compare If String1 (pEntry.szExeFile) Is Identical To String2 (ProcessName)
			if (!strcmp(pEntry.szExeFile, ProcessName)) 
			{
				//Store Process ID Into The Variable dwPID
				dwPID = pEntry.th32ProcessID; 	
				break; 
			}						
		}while (Process32Next(hPID, &pEntry)); 
	}

	//Clean Up! (Close Handle - Not Needed Anymore)
	CloseHandle(hPID);

#pragma endregion

	if (dwPID)
	{
		//Give Our Handle All Access Rights 
	    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); 

		//Take A Module Snapshot Of The Process (Grab All Loaded Modules)
        HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 
        
		//Declare Structure Size And Populate It With Loaded Modules
        mEntry.dwSize = sizeof(MODULEENTRY32); 

		//Error Handeling, If Your Reading A 64-Bit Process But Compile As 32-Bit It Will Throw Error
		if(!Module32First(hModule, &mEntry)) 
			exit(2);

		//Check The First Module, Is Always Process.exe And Grab Address And Store It In dwBase
		Module32First(hModule, &mEntry);
	    dwBase = (DWORD)mEntry.modBaseAddr;

		//Clean Up! (Close Handle - Not Needed Anymore)
        CloseHandle( hModule ); 
	}

	else 
		exit(1);
}

DWORD ProcMem::AOB_Scan(DWORD dwStart, DWORD dwEnd, char *Bytes, BOOL Type){

	//VARIABLES
	int iBytesToRead = 0; //Counter For Scan
	BYTE rBytes; //Storage To Hold A Single Byte To Read (Compare Read To Char *Array)
	int length = GetLength(Bytes); //Size Of *Array (*Bytes)

	//Increase Start Address Till It Reaches The End Address
	for(dwStart; dwStart < dwEnd; dwStart++) 
	{
		//Wildcard Support - Check If First Array Element Is '?' And Keep Inreasing Array Index Till We See A Byte
		while (Bytes[iBytesToRead] == '?')									
			iBytesToRead++; 

		//Read Bytes And Store Them In rBytes To Compare
		rBytes = Read<BYTE>(dwStart);
		
		//When A Byte That Has Been Red Matches One Of Our *Array Elements
		if (rBytes == Bytes[iBytesToRead]) 
		{
			do{		
				dwStart++; //Increment The Address By 1 To Scan The Next Byte		
				iBytesToRead++; //Increment The *Array Index To Read/Compare		
				rBytes = Read<BYTE>(dwStart); //Read The Next Byte
			
				//Wildcard Checker, If You Have Wildcards In The Middle/End Off Array
				while (Bytes[iBytesToRead] == '?') 		
				{ 						
					dwStart++; 				
					iBytesToRead++; 				
					rBytes = Read<BYTE>(dwStart);	
				}
				
			}while (rBytes == Bytes[iBytesToRead]); //While rBytes Matches An Element In Our *Array Keep Scanning Till We Reach *Array Length	
			
			//Reset Counter To Carry On Searching Bytes If Bytes Not Found
			if(iBytesToRead != length)
				iBytesToRead = 0;
		}
				
		//Scan Complete Outcomes
		if (iBytesToRead >= length)	
		{					
			if (Type)			
				return dwStart - iBytesToRead; //Return The Address - The Ammount Of Bytes Red						
			else				
				return dwStart; //Return The Address After Bytes			
		}		
	}	
	return 3;
}

BOOL ProcMem::Inject(DWORD dwAddress, char *Inj_Bts, char *Def_Bts, BOOL Type){
	
	//Get Array Lengths
	int i_ISize = GetLength(Inj_Bts);
	int i_DSize = GetLength(Def_Bts); 

	if (!bIOn)
	{
		//Create Codecave
		dwCaveAddress = (DWORD)VirtualAllocEx(hProcess, NULL,  i_ISize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
 
		cout << hex << dwCaveAddress << endl;

		//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);

		//NOP All Bytes In The Array Past The 5th Byte	
		if (i_DSize >= 5)
		{
			for (int i = 5; i < i_DSize; i++)	
				Write<BYTE>(dwAddress + i, 0x90);
		}
		else return 4;
	}	
		
	if (bIOn)
	{			
		//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);
	}
    return bIOn = !bIOn; //Set bIOn To Opposite So When Called Again It Executs The Off Statement (Bottom)
} 

DWORD ProcMem::Module(LPSTR lModule){
       
	//Take A Module Snapshot Of The Process (Grab All Loaded Modules)
	HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 
         
	//Declare Structure Size And Populate It With Loaded Modules
	mEntry.dwSize = sizeof(MODULEENTRY32); 

	//Check All Modules Except First As That Is Always Process.exe And Return The Module Base (E.g client.dll)
	do 
	{
		if (!strcmp(mEntry.szModule, lModule))		
		{	
			CloseHandle(hModule); //Clean Up! (Close Handle - Not Needed Anymore)
			return (DWORD)mEntry.modBaseAddr;
		}
	}while (Module32Next(hModule, &mEntry));
	
	CloseHandle(hModule); //Clean Up! (Close Handle - Not Needed Anymore)			
	return 5;
		
}

ProcMem::~ProcMem(){

	//Clean Up! (Close Handle - Not Needed Anymore)
	CloseHandle(hProcess);
}
 
Last edited:

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
ReadMe.txt

C++:
About Class V1.4:

This Class Was Created By Nether For www.guidedhacking.com And Was Designed For Use Via Console
Applications, You Can Adapt The Ideology Of Many Of These Functions To Forms And Dll's.

I Have Tried My Best To Comment As Much Code As Possible, I Will Continue To Comment More
And Re-Comment Functions I May Have Explained Incorrectly - Please Let Me Know If You Have Any Ideas.

If You Find Any Bugs, Or Code That Could Be Improved To Be More Efficient Please Contact Me
Via https://www.GuidedHacking.com/ (Profile Nether).

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Credits:

Fleep - Provided Method For Hotkeys To Activate Only Once When Pushed.
AgentSmith - Opened My Eyes To A Lot Of Things I Was Doing Wrong And Steered Me In The Right Direction.
NTValk - Helped Me When I Posted For Help On GH (Was Awhile Ago, Still Deserves Credit As This Has Been A Journey Of Learning And Everything Helps).
Agent Smith - Provided Me With Some Very Useful Pages For Learning And Helped Me Get A Better Understanding Of The Language.
Random Posts On GuidedHacking From Members, I Was Able To Pick Up A Few Things From These Threads/Posts.
Everyone At GuidedHacking Who Supported Me.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Features:

Read & Write Memory (Pointer Support)
AOB Scan - Scan An Area Of Memory For An Address With Specific Bytes
Patch - Patch OpCodes
Code Injection - Allocate A Random Area Of Memory To Write A Jmp/Call (Codecave) 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Usage:

//Declarations
ProcMem mem; //Declare Class Object
mem.GetProcess("Process.exe");
DWORD dwBase = mem.dwBase; //Define Process Base

//Basic Memory Functions
mem.Read<int>(0x76999A1); //Basic Read Memory (You Must Declare What Type/Size Of Data You Are Reading <short> | <2> etc)
mem.Read<int>(Base+0x3699B); //Process.exe+0x3699B (Using Base)
mem.Write<int>(0x76999A1, 1337); //Basic Write
mem.Write<float>(Base+0x3699B, 13.37); //Example Of Writing A <float>

//Pointer Memory Functions (readP - Returns The Address)
mem.Read<int>(0x76999A1, "\x2C\x5B\*", true); //Input Offsets In Order As Char* | ATTENTION: MUST ALWAYS Put '*' At The End Of Your Array (true)RETURNS THE ADDRESS
mem.Read<int>(Base+0x3699B, "\x2C\x5B\*", false); //(false)RETURNS THE VALUE

//Patch Memory Function
mem.Patch(0x76999A1, "\x90\x90\x90\*", "\x4B\x0\x8F\*"); //Input The Bytes You Want To Patch And Also The Default Bytes
mem.Patch(Base+0x3699B, "\x90\x90\x90\*", "\x4B\x0\x8F\*"); //Process.exe+0x3699B (Using Base)

//AOB Scan Function - DO NOT USE '?' At The End Of This Array
DWORD dwAOBAddress = mem.AOB_Scan(0x76999A1, 0x76999C1, "\x8B\x3C\x28\xDD\*", true); //Start Scan At Address 0x76999A1 And Read Every Byte From There To 0x76999C1, Looking For Char* Array (Returns Address)
DWORD dwAOBAddress1 = mem.AOB_Scan(Base+0x6999A1, Base+0x6999C1, "\x8B\x3C\x28\xDD\*", false); //false = Returns Address After Searched Bytes
mem.Write<int>(AOBAddress, 1337); //Example Of Usage
mem.Write<int>(AOBAddress1, 1337); //Example Of Usage

//AOB Scan With Pointers
DWORD dwStartAddy = mem.readP<int>(0x76999A1, "\x2C\x5B\*", false);
DWORD dwEndAddy = mem.readP<int>(0x76999A1, "\xB2\x68\x8B\*", false);
DWORD dwAOBAddress = mem.AOB_Scan(StartAddy, EndAddy, "\x8B\x3C\x28\xDD\*", true);

//Code Injection Function (Codecave)
mem.Inject(Base+0x1C8B39, "\xC7\x86\x84\x1\x0\x0\x0\x0\x0\x0\*", "\x89\xBE\x84\x1\x0\x0\*", true); //Input Bytes To Write/Inject Followed By The Default Bytes At The Address (Use CE AA Script To Get Bytes) (true = JMP)
mem.Inject(0x38B39, "\xC7\x86\x84\x1\x0\x0\x0\x0\x0\x0\*", "\x89\xBE\x84\x1\x0\x0\*", false); //Call Jmp Function (false) [Has Not Been Fully Tested]

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Notes:

Compile As Release
When Compiling Check You Are Building The Correct Build (x64 | x32) For The Target Process.
Do Not Have 2x Inject Functions In A Row (They Will Conflict), Have Them In Seperate Statements.
When Using The Patch Or Inject Function, Have Them Set To A Hotkey So You Can Turn On/Off.
You Can Use Pointers With The AOB Scan/Patch/Inject Functions, Adapt The AOB Scan Example For Others.
I Aim To Release A Tutorial For Creating A Memory Class Before Moving Onto Creating Dll's - Still Have Few More Updates For This Class (Mainly Comments + Code Improvments).

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Error Exit/Return Codes:

1 = The Process Could Not Be Found, Make Sure You Have Correctly Name The Process In The Constructor In Source.cpp [ProcMem mem("Process.exe");] Names Are Case Sensitive.
2 = You Are Trying To Grab Information From A (32|64) Bit Application With The Wrong Build - Double Check Your Build.
3 = AOB Scan Failure, You Have Either Got The Wrong Start/End Address Or Bytes Double Check All.
4 = Code Injection Failure - The Default Bytes Must Be More Than 5 [E.G Address Has 2 Bytes, You Must Use The Bytes Of The Next Insctruction(Address) 5 Bytes Away].
5 = Could Not Find Module Name, Check Spelling (Case Sensitive).
6 = Invalid Pointer, Check Your Offsets.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Updates To Come V1.5:

Add Some Sort Of Memory Integrity Check Function.
Hopefully Get Feedback And Ideas For New Functions.
Advanced Error Handeling Using Exceptions.
Support For Reading & Writing Strings In ASCII (Plain Text - String).
Fix Inject Function.
 

Syperus

RTFM
Meme Tier VIP
Dank Tier Donator
Oct 29, 2012
432
2,638
7
Looks like your project is coming along nicely. I haven't really looked into your coding, but it looks clean. Have you thought about using vectors for your pointers? I recommend it over arrays as it allows you to resize on the fly. It'll make your project more universal as you can resize based on how many offsets the pointer has so you, or anyone else, wouldn't have to hard-code them. Just a thought maybe for a future update! Good Work!!
 
Last edited:

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Looks like your project is coming along nicely. I haven't really looked into your coding, but it looks clean. Have you thought about using vectors for your pointers? I recommend it over arrays as it allows you to resize on the fly. It'll make your project more universal as you can resize based on how many offsets the pointer has so you, or anyone else, wouldn't have to hard-code them. Just a thought maybe for a future update! Good Work!!
thanks for the idea dude, i do actualy have a few pages on vectors bookmarked i do plan to fully read them, but im also guessing with vectors you would need to do something like this:

C++:
<vector> T [3] = {0x1, 0x2, 0x3};
mem.write(Address, T);
ofc thats not how you write vectors but thats what it would kind of look like correct?
 

NTvalk

Hacker
Meme Tier VIP
Jul 6, 2013
499
3,108
8
thanks for the idea dude, i do actualy have a few pages on vectors bookmarked i do plan to fully read them, but im also guessing with vectors you would need to do something like this:

C++:
<vector> T [3] = {0x1, 0x2, 0x3};
mem.write(Address, T);
ofc thats not how you write vectors but thats what it would kind of look like correct?
Correct, vectors are easier too.
But i personally still prefer arrays, just because it is less "managed". Since this is a memory class, i would personally go for unmanaged code, pure C.
It surely is possible with vectors tho.

PS: With managed I mean that memory management is hidden from you, it's managed by the OS etc. With arrays you can see what is happening.

And also i forgot to say, good work :D
 
Last edited:

Syperus

RTFM
Meme Tier VIP
Dank Tier Donator
Oct 29, 2012
432
2,638
7
Well it's
C++:
vector <datatype> variable
but yes they are better than arrays imo. Arrays are still useful for simple storage, bit I prefer vectors over them cause of the options available. You could have the user input the offsets and vsize++ per iteration in a for loop or however you want to do it. :)
 

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Well it's
C++:
vector <datatype> variable
but yes they are better than arrays imo. Arrays are still useful for simple storage, bit I prefer vectors over them cause of the options available. You could have the user input the offsets and vsize++ per iteration in a for loop or however you want to do it. :)
its good, i guess i just like having the write/read function all in one line so using a char array makes sense for me :p, but i may be tempted to use vectors for aob scan since you could be scanning a huge area of memory and might be safer using vectors :p
 

Fleep

Founder
Meme Tier VIP
May 20, 2012
572
11,023
6
Excellent work, if you can please provide a zip file with the header file and cpp files so that it makes it easier for people to use your class.

Also that will allow you to keep track of how many people have downloaded it. :)

Fleep
 

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Excellent work, if you can please provide a zip file with the header file and cpp files so that it makes it easier for people to use your class.

Also that will allow you to keep track of how many people have downloaded it. :)

Fleep
Thanks :), currently my net drops every few seconds so it times out before i can upload it to the site, I would apreciaite if you or a mod could add it to a project and upload as zip, as im having to wait till an engineer comes out to fix problems at the network box outside, everyone in the area is suffering :(
 
Last edited:
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods