Source Code Nether's C++ Console V1.3 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,

I have been working at my memory class aswell as a few other small misc applications, I just wanted to share my work with you as im pretty proud of it now :D
I have included a ReadMe.txt it shows you everything you need to know. Please Leave Feedback <3

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)

About Class V1.3:

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 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).
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("Process.exe"); //Declare Class Constructor With Process Name
DWORD Base = 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.readP<int>(0x76999A1, "\x2C\x5B\?", true); //Input Offsets In Order As Char* | ATTENTION: MUST ALWAYS Put '?' At The End Of Your Array (true)RETURNS THE VALUE
mem.readP<int>(Base+0x3699B, "\x2C\x5B\?", false); //(false)RETURNS THE ADDRESS

//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 AOBAddress = mem.AOBscan(0x76999A1, 0x76999C1, "\x8B\x3C\x28\xDD", 4); //Start Scan At Address 0x76999A1 And Read Every Byte From There To 0x76999C1, Looking For Char* Array (Returns Address)
DWORD AOBAddress1 = mem.AOBscan(Base+0x6999A1, Base+0x6999C1, "\x8B\x3C\x28\xDD", 4); //Declare How Many Bytes Your Searching For (4)
mem.write<int>(AOBAddress, 1337); //Example Of Usage
mem.write<int>(AOBAddress1, 1337); //Example Of Usage

//AOB Scan With Pointers
DWORD StartAddy = mem.readP<int>(0x76999A1, "\x2C\x5B\?", false);
DWORD EndAddy = mem.readP<int>(0x76999A1, "\xB2\x68\x8B\?", false);
DWORD AOBAddress = mem.AOBscan(StartAddy, EndAddy, "\x8B\x3C\x28\xDD", 4);

//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 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].

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

Updates To Come V1.4:

Cleaner Code + More Efficient.
More Comments + Improved Explanations.
Add Some Sort Of Memory Integrity Check Function.
Hopefully Get Feedback And Ideas For New Functions.
Freeze Value Function Using WatchPoint(Breakpoints) If Possible, I Think Breakpointing Addresses Are Only Viable In A Dll.
Advanced Error Handeling.
Support For Reading & Writing Strings In ASCII (Plain Text - String).

C++:
#ifndef INCLUDES_H //If Not Defined
#define INCLUDES_H //Define Now

#pragma once //Define Once

#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 "ProcMem.h" //Memory Class Header

#endif

C++:
#ifndef PROCMEM_H
#define PROCMEM_H

#include "Includes.h" //Include External Header Containing Global Includes

class ProcMem{

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
	DWORD dwProt2; //Storage For VirtualProtectEx
	DWORD dwCaveAddress; //Storage For Codecave Address

	//MISC
	BOOL On; //Boolean For Patch Function (On/Off)
	BOOL iOn; //Boolean For Inject Function (On/Off)
	
public:
	
	//PUBLIC STORAGE
	DWORD dwBase; //Storage For Process Base Address

	//FUNCTION PROTOTYPES
	ProcMem(char* ProcessName);
	DWORD AOBscan(DWORD dwStart, DWORD dwEnd, char *Bytes, int ilength);
	BOOL Inject(DWORD dwAddress, char *Inj_Bts, char *Def_Bts, BOOL Type);

#pragma region MEMORY FUNCTIONS

	//Get Length Of Array's
	int iLength(char *Array){
	
		int length = NULL;
 		
		for(int i = 1; i < 100; i++)
		{
			length++; //Increase length Until We See '?'
			if(Array[i] == '?') //Use '?' At The End Of An Array So It Knows When To Stop Counting
			{
				break;
			}
		}  
		return length;
	} 

	//READ MEMORY
	template <class cData>
	
	cData read(DWORD dwAddress)
	{
       cData Read; //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, &Read, 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 Read; //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 readP(DWORD dwAddress, char *Offset, BOOL Type){

		int iSize = iLength(Offset); //Get Size Of *Array
		cData ReadP;  	  
		DWORD dwTMP; //Storage For Address + Red Bytes

		ReadP =	read<cData>((DWORD)dwAddress); //Store The Value At 'dwAddress' In ReadP (cData Var)	

		for(int i = 0; i < iSize; i++) //Loop/Count From 0 (First Array Element) To Array Size End
		{			
		    dwTMP = ReadP + Offset[i]; //Store 'ReadP' Value (hex) + Offsett[i] As Hex Value (Pointer dwAddress)
			ReadP =	read<cData>((DWORD)dwTMP); //Read The New Value And Store Inside ReadP (Hex Value = Pointer dwAddress)
		}  	

		if(!Type)
		{
			return dwTMP; //Return Address
		}else
		{
			return ReadP; //Return Value
		}
	}

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

		int iSize = iLength(Offset);
      	DWORD dwTMP;
		cData ReadP;	  	

		ReadP =	read<cData>((DWORD)dwAddress);	

		for(int i = 0; i < iSize; i++) //Scan For Offsets
		{					
		    dwTMP = ReadP + Offset[i]; //Declaring Address For Each Byte To Read
			ReadP =	read<cData>((DWORD)dwTMP); //Read Offsets So You Can Calculate Next Address
		}
		write<cData>(dwTMP, Val); //Identical To Read Pointer, But Instead We Write To The Address Instead Of Reading It	
	}	

	//PATCH MEMORY

	void Patch(DWORD dwAddress, char *Patch_Bts, char *Default_Bts){

		int iSize = iLength(Default_Bts);	

		if(!On){
	
			for(int i = 0; i < iSize; i++)	
			{	
				DWORD dwTMP = dwAddress + i; 		
				write<BYTE>(dwTMP, Patch_Bts[i]); //Write Inject_Bts (Bytes) To The Address		
			}

		}else{
	 
			for(int i = 0; i < iSize; i++)	 
			{		
				DWORD dwTMP = dwAddress + i; 		
				write<BYTE>(dwTMP, Default_Bts[i]); //Re-Write Original(Default) Bytes Back To The Address        
			}        
		}
		
		On = !On;
	}

#pragma endregion	

};

#endif
 
Last edited:

Nether

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

using namespace std;

ProcMem::ProcMem(char* ProcessName){

#pragma region Get Process ID

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

	pEntry.dwSize = sizeof(PROCESSENTRY32); //Declare Entry Point Structure Size [pEntry - Holds Process List] (Populating Structure)

	if(Process32First(hPID, &pEntry)) //Check The First Process To See If Its The One We Want (Could Possibly Remove But Will Cause Console To Skip First Process)
	{	
		do
		{					
			if(strcmp(pEntry.szExeFile, ProcessName) == 0 ) //Compare If String1 (pEntry.szExeFile)-[Structure Containing Process List] Is Identical To String2 (ProcessName)			
			{						
				dwPID = pEntry.th32ProcessID; //Store Process ID Into The Variable dwPID					
				break; //Exit The Loop			
			}	
		}while(Process32Next(hPID, &pEntry)); //Loop Through All Running Processes Scanning For szExeFile Parameter (From pEntry Structure)
	}
	CloseHandle(hPID); //Close Handle - Not Needed Anymore

#pragma endregion

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

        HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); //Take A Seperate Snapshot Of The Process
        
        mEntry.dwSize = sizeof(MODULEENTRY32); //Set Size Of mEntry And Store Module Information Inside The Structure (mEntry)

		if(!Module32First(hModule, &mEntry)) //Error Handeling, If Your Reading A 64-Bit Process But Compile As 32-Bit It Will Throw Error
		{ 
		  cout << "ERROR 2: The Target Process Has A Different Bit Structure, Make Sure You Have The Correct Build (32-bit | 64-bit)" << endl;
		  system("pause");
		  exit(2);
		} 

		Module32First(hModule, &mEntry); //Check If Address Is Valid
	    dwBase = (DWORD) mEntry.modBaseAddr; //Store Process Base Address (dwBase)

        CloseHandle( hModule ); //Close Handle - Not Needed Anymore
	}
	else 
	{
	    cout << "ERROR 1: The Process Could Not Be Found, Check Application Name" << endl;
	    system("pause");
	    exit(1);
	}		
}

DWORD ProcMem::AOBscan(DWORD dwStart, DWORD dwEnd, char *Bytes, int ilength){

	//VARIABLES
	int iBytesToRead = 0; //Counter For Red Bytes
	char rBytes; //Storage To Hold A Single Byte To Read (Compare Read To Char *Array)

	//SCAN FUNCTION
	for(dwStart; dwStart < dwEnd; dwStart++) //Increase Start Address Till It Reaches End Address
	{
		rBytes = read<BYTE>(dwStart); //Reads Single Bytes And Stores Them Into rBytes
		
		//Wildcard Support - Check If First Array Element Is '?'
		while (Bytes[iBytesToRead] == '?'){									
			iBytesToRead++; //Increase Untill We See A Real Byte In Our Char *Array					
		}

		if(rBytes == Bytes[iBytesToRead]) //When A Byte That Has Been Red Matches One Of Our *Array Elemts
		{
			do{		

				dwStart++; //Increase The Address By 1 To Scan The Next Byte		
				iBytesToRead++; //Increase The *Array Index To Read/Compare		
				rBytes = read<BYTE>(dwStart); //Reads The Next Byte
		
				//Wildcard Support - Check If Array Elements Include '?' and skip		
				while (Bytes[iBytesToRead] == '?') //Skip To Next Byte To Read		
				{ 								
					dwStart++; 				
					iBytesToRead++; 				
					rBytes = read<BYTE>(dwStart); //Reads The Next Byte		
				}

			}while(rBytes == Bytes[iBytesToRead]); //While rBytes Matches An Element In Our *Array Keep Scanning Till We Reach *Array Length

			if(iBytesToRead == ilength) //If Our Count Has Reached The Array Size
			{			
				return dwStart - iBytesToRead; //Return The Address - The Ammount Of Bytes Red
			}	
		}		
	}	

	cout << "ERROR 3: The Bytes Could Not Be Found In This Memory Region, Check Your Start/End Address And Bytes" << endl;
	system("pause");			
	exit(3);
	return dwStart - iBytesToRead;
}

BOOL ProcMem::Inject(DWORD dwAddress, char *Inj_Bts, char *Def_Bts, BOOL Type){
	
	//Variable Size Initializers
	int iSize = iLength(Inj_Bts); //Declare Array Length
	int dSize = iLength(Def_Bts); //Declare Array Length

	if(!iOn){
			
		dwCaveAddress = (DWORD)VirtualAllocEx(hProcess, NULL,  iSize + 5, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); //Allocate A Memory Region To Write (Create Codecave)
 
		for(int i = 0; i <= iSize; i++)
		{			
			write<BYTE>(dwCaveAddress+i, Inj_Bts[i]); //Write Inj_Bts To Codecave
		}	

		DWORD dwRetJmp = dwAddress + dSize - (dwCaveAddress) - (iSize + 5) ; //Calculate Distance In Bytes
		write<BYTE>(dwCaveAddress + iSize, Type ? 0xE9 : 0xE8); //Write Jmp/Call To The First Byte
		write<DWORD>(dwCaveAddress + iSize + 1, dwRetJmp); //Write The Return Jmp To The Next++ Address

		//Calculate Distance In Bytes (-5 Bytes, Due To A Jmp Needs 5 Bytes)
		DWORD dwBaseJmp = dwCaveAddress - dwAddress - 5;
	
		//Write The Jump To The Original Address 	  
		write<BYTE>(dwAddress, Type ? 0xE9 : 0xE8); //Write Jmp/Call To The First Byte	
		write<DWORD>(dwAddress + 1, dwBaseJmp); //Write The Return Jmp To The Next++ Byte

		//If Array Is More Than 5 Bytes	
		if(dSize >= 5)
		{				
			for(int i = 5; i < dSize; i++)
			{						
				write<BYTE>(dwAddress + i, 0x90); //NOP Remaining Bytes	
			} 
		}else{		
			cout << "ERROR 4: The Default Bytes Can't Be Less Than 5. You'll Need To Use The Next Instruction Atleast 5 Bytes Away" << endl;		
			system("pause");	
			exit(4);	
		}
	}	
				
	if(iOn){					
		for(int i = 0; i < dSize; i++)
		{					
			write<BYTE>(dwAddress + i, Def_Bts[i]);	//Restore Original Bytes To Start Address			
		}	
		VirtualFreeEx(hProcess, (LPVOID)dwCaveAddress, iSize + 5, MEM_DECOMMIT); //DeAllocate The Memory In The Codecave
	}

    return iOn = !iOn; //Set iOn To Opposite So When Called Again It Executs The Off Statement (Bottom)
}


C++:
#include "Includes.h"

//GLOBAL VARIABLES & DECLARATIONS
ProcMem mem("BlackOps.exe"); // Create Class Object
DWORD Base = mem.dwBase; // Declare Process Module Base dwAddress For Easier Use

using namespace std;

int main( void )
{
	int iTimer; //HotKey Limiter
	iTimer = clock(); 

	while(1){
		if(clock() - iTimer > 400)	
		{		
			if(GetAsyncKeyState(VK_F2))						
			{		
				iTimer = clock();
				mem.Inject(Base+0x36999B, "\xC7\x46\x3C\x0\x0\x0\x0\?", "\x83\x7E\x3C\x0\x74\x6A\?", true); //Fast Trigger
				//mem.Patch(0x6563F8, "\x90\x90\x90\x90\x90\?", "\xE8\xC3\x12\xF1\xFF\?"); //No Recoil
				//mem.Inject(Base+0x1C8B39, "\xC7\x86\x84\x1\x0\x0\x0\x0\x0\x0\?", "\x89\xBE\x84\x1\x0\x0\?", true); //Instant KIll
				cout << "Address Toggled" << endl;
			}
		}
	}

	system("pause");
	return 0;
}

The Addresses Shown Here Are Real (Latest Version Of BlackOps 1 Zombies)

Credits:
Fleep - Provided Method For Hotkeys To Activate Only Once When Pushed.
Agent Smith - 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).
 

Attachments

Last edited:

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Update: Add The Following Code If You Wish To Get Module Bases For Any Module (like client.dll etc)

ProcMem.h
C++:
DWORD Module(LPSTR lModule); //PROTOTYPE
ProcMem.cpp
C++:
DWORD ProcMem::Module(LPSTR lModule){
       
	HANDLE hModule = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); //Take A Seperate Snapshot Of The Process
         
	mEntry.dwSize = sizeof(MODULEENTRY32); //Set Size Of mEntry And Store Module Information Inside The Structure (mEntry)

	while(Module32Next(hModule, &mEntry)){		
		if(strcmp(mEntry.szModule, lModule) == 0)			
		{				
			return (DWORD)mEntry.modBaseAddr;				
			break;		
		}
	}
	
	return 0;
}
Source.cpp
C++:
DWORD dwClient = mem.Module("client.dll");
DWORD dwEngine = mem.Module("engine.dll");
I am aware of the issues with the AOB Scan - Working On It ATM (temp fix, make sure last byte is not a wildcard, just keep going till you get a real byte ill upload updated version soon.
 
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