Source Code Garry's Mod C++ External "Base"

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

audi200

Newbie
Apr 16, 2017
1
12
0
Hello, I made this in a few minutes and I guess it would be a good thing to release here. It's not a full cheat but it has access to client.dll and server.dll using SlimMem, well commented. Also excuse the bad code, I'm very bad at C++.

main.cpp
C++:
#include <iostream>
#include <Windows.h>
#include <string>
#include "SlimMem.h"

SlimUtils::SlimMem mem; // Access to SlimMem
DWORD pid; // Process ID to Garry's Mod

/*
 * Initialize everything
*/
void main()
{
	std::cout << "Waiting for hl2.exe" << std::endl;
	while (!SlimUtils::SlimMem::GetPID(L"hl2.exe", &pid)) // While SlimMem can't find the process
	{
		Sleep(300); // Wait for 300 milliseconds
	}

	std::cout << "Opening hl2.exe" << std::endl;
	if (!mem.Open(pid, SlimUtils::ProcessAccess::Full))
	{
		std::cout << "Failed to open process hl2.exe" << std::endl << GetLastError << std::endl; // Print error message
	}

	std::cout << "Success opening hl2.exe" << std::endl;


	/*
	 * Get client.dll and print results
	 */
	auto client = mem.GetModule(L"client.dll"); // Grab client.dll
	if (client == nullptr) // If client.dll is a null pointer
	{
		std::cout << "Couldn't find module client.dll" << std::endl;
	}
	else
	{
		system("cls"); // Clear console
		std::cout << " ------------" << std::endl;
		std::cout << "| client.dll |" << std::endl;
		std::cout << " ------------" << std::endl;
		std::cout << "dwSize: 0x" << std::hex << client->dwSize << std::endl; // Print client.dlls DWORD size
		std::cout << "ptrBase: 0x" << std::hex << client->ptrBase << std::endl; // Print client.dlls pointer base
	}


	/*
	 * Get server.dll and print results
	 */
	auto server = mem.GetModule(L"server.dll"); // Grab server.dll
	if (server == nullptr) // If server.dll is a null pointer
	{
		std::cout << "Couldn't find module server.dll" << std::endl;
	}
	else
	{
		std::cout << " ------------" << std::endl;
		std::cout << "| server.dll |" << std::endl;
		std::cout << " ------------" << std::endl;
		std::cout << "dwSize: 0x" << std::hex << server->dwSize << std::endl; // Print server.dlls DWORD size
		std::cout << "ptrBase: 0x" << std::hex << server->ptrBase << std::endl; // Print server.dlls pointer base
	}

	system("PAUSE");
}
SlimMem.cpp
C++:
#include "SlimMem.h"

namespace SlimUtils {
#pragma region Constructors/Destructors
	SlimMem::SlimMem(const SlimMem & copy)
	{
		DuplicateHandle(GetCurrentProcess(), copy.m_hProc, GetCurrentProcess(), &m_hProc, NULL, FALSE, DUPLICATE_SAME_ACCESS);
	}

	SlimMem::~SlimMem()
	{
		this->Close();
	}
#pragma endregion

#pragma region Open/Close
	void SlimMem::Close()
	{
		m_mModules.clear();

		//Close the handle to the process in case it's still open
		if (IsProcessHandleValid(m_hProc)) {
			ProperlyCloseHandle(m_hProc);
		}
	}

	bool SlimMem::Open(const wchar_t * lpwstrProcessName, ProcessAccess flags)
	{
		return this->Open(lpwstrProcessName, (DWORD)flags);
	}

	bool SlimMem::Open(const wchar_t * lpwstrProcessName, DWORD flags)
	{
		DWORD pid;
		if (GetPID(lpwstrProcessName, &pid))
			return this->Open(pid, flags);
		return false;
	}

	bool SlimMem::Open(DWORD dwPID, ProcessAccess flags)
	{
		return this->Open(dwPID, (DWORD)flags);
	}

	bool SlimMem::Open(DWORD dwPID, DWORD dwFlags)
	{
		if (this->HasProcessHandle())
			return false;

		m_hProc = OpenProcess(dwFlags | PROCESS_DUP_HANDLE, false, dwPID);
		m_dwPID = dwPID;
		if (this->HasProcessHandle())
			this->ParseModules();

		return this->HasProcessHandle();
	}
#pragma endregion

#pragma region Utility
	/*
	Attempts to find a process with a given name and sets the given PID
	Returns whether a matching process was found or not
	*/
	BOOL SlimMem::GetPID(const wchar_t * lpwstrProcessName, DWORD* pid)
	{
		PROCESSENTRY32W proc;
		proc.dwSize = sizeof(PROCESSENTRY32W);
		HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		*pid = -1;

		if (!IsHandleValid(hSnap))
			return false;

		if (Process32FirstW(hSnap, &proc)) {
			do {
				if (wcscmp(lpwstrProcessName, proc.szExeFile) == 0)
				{
					ProperlyCloseHandle(hSnap);
					*pid = proc.th32ProcessID;
					return true;
				}
			} while (Process32NextW(hSnap, &proc));
		}

		ProperlyCloseHandle(hSnap);
		return false;
	}

	/*
	Caches basic information of modules loaded by the opened-process

	*/
	bool SlimMem::ParseModules()
	{
		if (!this->HasProcessHandle())
			return false;

		m_mModules.clear();

		MODULEENTRY32W mod;
		mod.dwSize = sizeof(MODULEENTRY32W);

		HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, m_dwPID);
		if (!IsHandleValid(hSnap))
			return false;

		if (Module32FirstW(hSnap, &mod)) {
			do {
				try {
					if (m_mModules.find(std::wstring(mod.szModule)) == m_mModules.end())
						m_mModules[ToLower(mod.szModule)] = std::make_unique<SlimModule>(mod, *this);
				}
				catch (...) {
#ifdef REPORT_ERRORS
					std::cout << "[SlimMem] Failed to parse module \"" << mod.szModule << "\"" << std::endl;
#endif
				}
			} while (Module32NextW(hSnap, &mod));
		}

		ProperlyCloseHandle(hSnap);
		return true;
	}

	SigScanResult SlimMem::PerformSigScan(const BYTE * bufPattern, const char * lpcstrMask, const wchar_t * lpwstrModuleName, DWORD startFromOffset)
	{
		auto module = this->GetModule(lpwstrModuleName);
		if (module == nullptr)
			return SigScanResult(false);
		std::string mask(lpcstrMask);

		if (mask.empty())
			return SigScanResult(false);

		if (module->dwSize <= startFromOffset)
			return SigScanResult(false);

		if (startFromOffset > module->dwSize - mask.size())
			return SigScanResult(false);

		BYTE *dump = new BYTE[module->dwSize];

		SIZE_T bytesRead;
		if (!ReadProcessMemory(this->m_hProc, (LPCVOID)module->ptrBase, dump, module->dwSize, &bytesRead) || bytesRead != module->dwSize)
			return SigScanResult(false);

		bool found = false;
		for (DWORD i = startFromOffset; i < module->dwSize - mask.size(); i++) {
			found = true;
			for (DWORD idx = 0; idx < mask.size(); idx++) {
				if (mask[idx] == 'x' && bufPattern[idx] != dump[i + idx]) {
					found = false;
					break;
				}
			}
			if (found) {
				SigScanResult result(true, i, dump + i, mask.size());
				delete[] dump;
				return result;
			}
		}

		delete[] dump;

		return SigScanResult(false);
	}

	const SlimModule* SlimMem::GetModule(const wchar_t * lpwstrModuleName) const
	{
		std::wstring name = ToLower(std::wstring(lpwstrModuleName));
		auto val = m_mModules.find(name);
		if (val == m_mModules.end())
			return nullptr;

		return (*val).second.get();
	}

#pragma endregion
}
SlimMem.h
C++:
#pragma once

/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** SlimMem.h
** A simple to use memory-manipulation class
**
** Author: Zat
** More information: https://www.unkn0wncheats.me/forum/c-and-c/167302-slimmem-simple-use-memory-manipulation-class.html
** -------------------------------------------------------------------------*/

#include <windows.h>	//Windows-functions (OpenProcess, RPM, WPM, etc)
#include <tlhelp32.h>	//Functions that gather process-information
#include <Psapi.h>		//Functions that gather module-information
#include <map>			//Data-container that saves parsed modules 
#include <string>		//String/WString implementation
#include <cctype>		//tolower-function that converts a char to lowercase
#include <algorithm>	//transform-function that is used to apply the tolower-function to a wstring
#include <cassert>		//Used for debugging
#include <type_traits>	//Used to restrict usage of template functions Read and Write to specific types
#include <iostream>		//cout
#include <memory>		//unique_ptr

namespace SlimUtils {

	//Exclude module-names from SlimModule-structs
#define VERYSLIM_SLIMMODULE
	//Enable error-reports
#define REPORT_ERRORS

	inline bool IsProcessHandleValid(HANDLE h) { return h > 0 && h != INVALID_HANDLE_VALUE; }
	inline bool IsHandleValid(HANDLE h) { return h != INVALID_HANDLE_VALUE; }
	inline BOOL ProperlyCloseHandle(HANDLE h) {
		auto const b = CloseHandle(h);
		assert(b);
		return b;
	}


	static std::wstring ToLower(std::wstring string) {
		transform(string.begin(), string.end(), string.begin(), tolower);
		return string;
	}

	struct SlimModule;
	struct SigScanResult;
	class SlimMem;

	/*
	Contains basic information about a single module
	*/
	struct SlimModule {
		std::uintptr_t ptrBase;
		DWORD  dwSize;

		SlimModule(const MODULEENTRY32W& mod, const SlimMem& mem) {
			ptrBase = (std::uintptr_t)mod.modBaseAddr;
			dwSize = mod.modBaseSize;
		}
	};

	/*
	Holds information about a signature-scan
	*/
	struct SigScanResult {
		bool m_Success;
		BYTE *m_Data;
		DWORD m_DataLength;
		DWORD m_Offset;

		SigScanResult() : m_Success(false), m_Offset(0), m_DataLength(0), m_Data(nullptr) {
		}

		SigScanResult(bool p_Success) : m_Success(p_Success), m_Offset(0), m_DataLength(0), m_Data(nullptr) {
		}

		SigScanResult(bool p_Success, DWORD p_Offset, BYTE *p_Data, DWORD p_DataLength) : m_Success(p_Success), m_Offset(p_Offset), m_DataLength(p_DataLength) {
			if (p_Data != nullptr) {
				m_Data = new BYTE[m_DataLength];
				memcpy_s(m_Data, m_DataLength, p_Data, m_DataLength);
			}
		}

		SigScanResult(const SigScanResult& other) : SigScanResult(other.m_Success, other.m_Offset, other.m_Data, other.m_DataLength) {
		}

		~SigScanResult() {
			if (m_Data != nullptr)
				delete[] m_Data;
		}

		SigScanResult& operator=(const SigScanResult& other) {
			if (this->m_Data != nullptr) {
				delete[] this->m_Data;
				this->m_Data = nullptr;
			}
			this->m_Success = other.m_Success;
			this->m_Offset = other.m_Offset;

			if (other.m_Data != nullptr) {
				this->m_DataLength = other.m_DataLength;
				this->m_Data = new BYTE[other.m_DataLength];
				memcpy_s(this->m_Data, this->m_DataLength, other.m_Data, other.m_DataLength);
			}
			return *this;
		}

		template <typename T>
		bool Read(T& value, DWORD index) const {
			if (index + sizeof(T) >= m_DataLength)
				return false;

			value = *(T*)(reinterpret_cast<DWORD>(m_Data) + index);
			return true;
		}
	};

	/*
	Offers a simple collection of combination of process-access flags
	*/
	enum ProcessAccess : DWORD
	{
		Full = PROCESS_ALL_ACCESS,
		ReadOnly = PROCESS_VM_OPERATION | PROCESS_VM_READ,
		WriteOnly = PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
		ReadWrite = ReadOnly | WriteOnly
	};

	/*
	A class that provides basic functions that are used to write to/read from process memory
	*/
	class SlimMem {
	public:
		SlimMem() : m_hProc(INVALID_HANDLE_VALUE) { }
		SlimMem(const SlimMem& copy);
		~SlimMem();

		bool Open(const wchar_t* lpwstrProcessName, ProcessAccess flags);
		bool Open(const wchar_t* lpwstrProcessName, DWORD dwFlags);
		bool Open(DWORD dwPID, ProcessAccess flags);
		bool Open(DWORD dwPID, DWORD dwFlags);
		void Close();

		bool HasProcessHandle() const { return IsProcessHandleValid(m_hProc); }
		const SlimModule* GetModule(const wchar_t* lpwstrModuleName) const;
		bool ParseModules();
		SigScanResult PerformSigScan(const BYTE *bufPattern, const char* lpcstrMask, const wchar_t* lpwstrModuleName, DWORD startFromOffset = 0);

		template <typename T>
		T Read(std::uintptr_t ptrAddress) const;

		template <typename T>
		bool Read(std::uintptr_t ptrAddress, T& value) const;

		template <typename T>
		T ReadPtr(std::uintptr_t ptrAddress, std::initializer_list<std::uintptr_t> ilOffsets) const;

		template <typename T>
		bool Write(std::uintptr_t ptrAddress, T value) const;

		static BOOL GetPID(const wchar_t* lpwstrProcessName, DWORD* pid);
	private:
		HANDLE m_hProc;
		DWORD m_dwPID;
		std::map<std::wstring, std::unique_ptr<SlimModule>> m_mModules;
	};

#pragma region Read/Write
	/*
	Reads data from memory
	Returns the value read from memory; Returns default-value in case an error occured
	*/
	template<typename T>
	inline T SlimMem::Read(std::uintptr_t ptrAddress) const
	{
		static_assert(std::is_trivially_copyable<T>::value, "Invalid RPM/WPM type");

		T val = T();
		if (!this->HasProcessHandle())
			return val;

		ReadProcessMemory(this->m_hProc, (LPCVOID)ptrAddress, &val, sizeof(T), NULL);
		return val;
	}

	/*
	Reads data from memory
	Returns whether the operation was successful or not!
	*/
	template<typename T>
	inline bool SlimUtils::SlimMem::Read(std::uintptr_t ptrAddress, T & value) const
	{
		static_assert(std::is_trivially_copyable<T>::value, "Invalid RPM/WPM type");

		SIZE_T bytesRead;

		if (!this->HasProcessHandle())
			return false;

		return ReadProcessMemory(m_hProc, (LPCVOID)ptrAddress, &value, sizeof(T), &bytesRead) && bytesRead == sizeof(T);
	}

	/*
	Reads data from memory
	Returns the value read from memory; Returns default-value in case an error occured
	*/
	template<typename T>
	inline T SlimMem::ReadPtr(std::uintptr_t ptrAddress, std::initializer_list<std::uintptr_t> ilOffsets) const
	{
		static_assert(std::is_trivially_copyable<T>::value, "Invalid RPM/WPM type");

		if (!this->HasProcessHandle())
			return false;
		for (auto it = ilOffsets.begin(); it != ilOffsets.end(); it++) {
			if ((std::uintptr_t*)(it + 1) == ilOffsets.end()) {
				//Read value
				return this->Read<T>(ptrAddress + *it);
			}
			else {
				//Read offset
				ptrAddress = this->Read<std::uintptr_t>(ptrAddress + *it);
			}
		}
		return T();
	}

	/*
	Writes data to memory
	Returns whether the operation was successful or not!
	*/
	template<typename T>
	inline bool SlimMem::Write(std::uintptr_t ptrAddress, T value) const
	{
		static_assert(std::is_trivially_copyable<T>::value, "Invalid RPM/WPM type");

		if (!this->HasProcessHandle())
			return false;
		return WriteProcessMemory(this->m_hProc, (LPVOID)ptrAddress, &value, sizeof(T), NULL);
	}
#pragma endregion
}
 
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