Solved ModuleBaseAddress + Pointer

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Hi guys,
So i'm trying to find a DMA address I found with the pointer scan:
"gamedll_x64_rwdi.dll"+01A72580
with the offsets of {764, 38, 468}

But i'm having a little trouble. I'm able to find the module address (at least I think) using:

C++:
DWORD GetModuleBaseAddress(DWORD processId, TCHAR *szModuleName)
{
	DWORD moduleBase = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE) {
		MODULEENTRY32 moduleEntry;
		moduleEntry.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &moduleEntry)) {
			do {
				if (strcmp(moduleEntry.szModule, szModuleName) == 0) {
					moduleBase = (DWORD)moduleEntry.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &moduleEntry));
		}
		CloseHandle(hSnapshot);
	}
	return moduleBase;
}
However, I'm a little confused on adding the offset to it. Is it a pointer i'm adding? If I add the pointer or if I add it as a regular address, I don't get the value I'm looking for..
C++:
					DWORD dwEngine = GetModuleBaseAddress(dwProcID, (TCHAR*)("gamedll_x64_rwdi.dll"));
						if (dwEngine == 0x0) {
							cout << "Looking for engine.dll" << endl;
						}

					DWORD test = { 0x01A72580 };
					DWORD buffer;
					ReadProcessMemory(hProcHandle, (LPCVOID)test, &buffer, sizeof(buffer), NULL);
					DWORD both = dwEngine + buffer;
					DWORD test2;
					ReadProcessMemory(hProcHandle, (LPCVOID)both, &test2, sizeof(test2), NULL);
					cout << "TEST: " << test2 << endl;
This code returns 0, i've had it return a couple other values, but none of them return the pointer i'm looking for (even converting it to hexadecimal).

Free blowjob to anyone that can help me out :FeelsBadMan:
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
Let me combine mine and mambda's post:

C++:
typedef unsigned long long QWORD;

#ifdef _WIN64
#define RETURN_TYPE QWORD
#else
#define RETURN_TYPE DWORD
#endif

RETURN_TYPE GetModuleBaseAddressA(DWORD processId, char *szModuleName)
{
	RETURN_TYPE RetVal;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 ME32;
		ME32.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &ME32))
		{
			do
			{
				if (!strcmp(ME32.szModule, szModuleName))
				{
					RetVal = (RETURN_TYPE)ME32.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &ME32));
		}
		CloseHandle(hSnapshot);
	}
	return RetVal;
}

#undef RETURN_TYPE
And:
C++:
DWORD dwOffsets[] = { 0x01A72580, 0x764, 0x38, 0x468 };
QWORD qwBaseaddress = GetModuleBaseAddressA(dwProcID, "gamedll_x64_rwdi.dll");
QWORD qwBuffer = qwBaseaddress;

for (UINT i = 0; i != 3 && qwBuffer != 0; ++i)
{
	qwBuffer += dwOffsets[i];
	if (!ReadProcessMemory(hProc, reinterpret_cast<void*>(qwBuffer), &qwBuffer, sizeof(QWORD), nullptr))
	{
		qwBuffer = 0;
		break;
	}
}

QWORD qwFinaladdress = 0;
if (qwBuffer)
{
	qwFinaladdress = qwBuffer + dwOffsets[3];
}
 
Last edited:

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,298
37,938
269
you dont cast a char* to a wchar like that. just put an L infront of it.

I.e. char* thisString = "Hello";
wchar_t* thisStringW = L"Hello";

unless the compiler is doing something funky and allowing that to work
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
^ and:
Read the pointer like this:

C++:
DWORD dwOffsets[] = { 0x01A72580, 0x764, 0x38, 0x468 };
DWORD dwBaseaddress = GetModuleBaseAddress(dwProcID, "gamedll_x64_rwdi.dll");
DWORD dwBuffer = dwBaseaddress;

for(UINT i = 0; i != 3 && dwBuffer != 0; ++i) //run the loop for AmountOfOffsets -1 on times and if dwBuffer is 0 stop the loop
{
     dwBuffer += dwOffsets[i]; //add the offset
     if(!ReadProcessMemory(hProc, reinterpret_cast<void*>(dwBuffer), &dwBuffer, 4, nullptr))
     {
          //if rpm fails stop the loop
          dwBuffer = 0;
          break;
     }
}

DWORD dwFinaladdress = 0;
if(dwBuffer)
{
     dwFinaladdress = dwBuffer + dwOffsets[3];
}
 

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Thanks for replies. My compiler is spitting out a bunch of errors, but it's letting me run it lol.
I don't quite understand the char casting part. if I do this my compiler yells at me:
C++:
wchar_t* moduleName = L"gamedll_x64_rwdi.dll";
DWORD dwBaseAddress = GetModuleBaseAddress(dwProcID, moduleName);
But regardless, I'm able to do a readprocessmemory but i've found that the address i'm getting has a value of 0. So perhaps GetModuleBaseAddress is returning the wrong value?
dwBaseAddress returns value 1913192448 and when I add the first offset and convert it to hex I get 73B02580 which points to nothing so that is why RPM is returning 0. But what am I doing wrong?
Sorry for the noobness, I am very unqualified for this lol. Thanks so much for helping me out though
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
Thanks for replies. My compiler is spitting out a bunch of errors, but it's letting me run it lol.
I don't quite understand the char casting part. if I do this my compiler yells at me:
C++:
wchar_t* moduleName = L"gamedll_x64_rwdi.dll";
DWORD dwBaseAddress = GetModuleBaseAddress(dwProcID, moduleName);
But regardless, I'm able to do a readprocessmemory but i've found that the address i'm getting has a value of 0. So perhaps GetModuleBaseAddress is returning the wrong value?
dwBaseAddress returns value 1913192448 and when I add the first offset and convert it to hex I get 73B02580 which points to nothing so that is why RPM is returning 0. But what am I doing wrong?
Sorry for the noobness, I am very unqualified for this lol. Thanks so much for helping me out though
Set your project to multibyte instead of annoying unicode in the project settings.

char* moduleName = "gamedll_x64_rwdi.dll";
DWORD dwBaseAddress = GetModuleBaseAddress(dwProcID, moduleName);

And are you sure that the pointer is working? Better double check with CE.
 

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Turns out GetModuleBaseAddress is returning a bogus result. I forgot my game is 64 bit. I have another thread with this exact problem lol.
I tried changing DWORD to DWORD_PTR, it gives a different output but still not right:
C++:
DWORD_PTR GetModuleBaseAddress(DWORD processId, TCHAR *szModuleName)
{
	DWORD_PTR moduleBase = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE) {
		MODULEENTRY32 moduleEntry;
		moduleEntry.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &moduleEntry)) {
			do {
				if (strcmp(moduleEntry.szModule, szModuleName) == 0) {
					moduleBase = (DWORD_PTR)moduleEntry.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &moduleEntry));
		}
		CloseHandle(hSnapshot);
	}
	return moduleBase;
}
I tried looking for the PEB address and doing it that way but I got waaaayyy too confused, too complex of code for me
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
Turns out GetModuleBaseAddress is returning a bogus result. I forgot my game is 64 bit. I have another thread with this exact problem lol.
I tried changing DWORD to DWORD_PTR, it gives a different output but still not right:
C++:
DWORD_PTR GetModuleBaseAddress(DWORD processId, TCHAR *szModuleName)
{
	DWORD_PTR moduleBase = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE) {
		MODULEENTRY32 moduleEntry;
		moduleEntry.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &moduleEntry)) {
			do {
				if (strcmp(moduleEntry.szModule, szModuleName) == 0) {
					moduleBase = (DWORD_PTR)moduleEntry.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &moduleEntry));
		}
		CloseHandle(hSnapshot);
	}
	return moduleBase;
}
Oh, if the target process is a 64-bit process you need to code your hack as a 64-bit program, too (check CreateToolhelp32Snapshot: th32ProcessID).
DWORD_PTR is a type you shouldn't use. It's "name" is misleading as f*ck. Let's take a look at the typedef of DWORD_PTR:
C++:
typedef ULONG_PTR DWORD_PTR;
typedef __w64 unsigned long ULONG_PTR;
See? DWORT_PTR isn't a pointer. It's just an unsigned 32-bit value (the __w64 thingy doesn't make it a pointer, let's just ignore it for now).

If you want to store addresses in your 64-bit app you should use ULONGLONGs or QWORDs (or just void*/BYTE* if you want actual pointer types). Define a QWORD like this:
C++:
typedef unsigned long long QWORD;
This function should do it:
C++:
QWORD GetModuleBaseAddressA(DWORD processId, char *szModuleName)
{
#ifdef _WIN64
	QWORD Ret = 0;
#else
	DWORD Ret = 0;
#endif
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 ME32;
		ME32.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &ME32))
		{
			do
			{
				if (!strcmp(ME32.szModule, szModuleName))
				{
#ifdef _WIN64
					Ret = (QWORD)ME32.modBaseAddr;
#else
					Ret = (DWORD)ME32.modBaseAddr;
#endif
					break;
				}
			} while (Module32Next(hSnapshot, &ME32));
		}
		CloseHandle(hSnapshot);
	}
	return Ret;
}
You still have to compile your hack as a 64-bit app of course but this function should work for both 32-bit and 64-bit processes.


I tried looking for the PEB address and doing it that way but I got waaaayyy too confused, too complex of code for me
CreateToolhelp32Snapshot basically just loops through the PEB^^
 
Last edited:

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Вroihon;38588 said:
Oh, if the target process is a 64-bit process you need to code your hack as a 64-bit program, too (check CreateToolhelp32Snapshot: th32ProcessID).
DWORD_PTR is a type you shouldn't use. It's "name" is misleading as f*ck. Let's take a look at the typedef of DWORD_PTR:
C++:
typedef ULONG_PTR DWORD_PTR;
typedef __w64 unsigned long ULONG_PTR;
See? DWORT_PTR isn't a pointer. It's just an unsigned 32-bit value (the __w64 thingy doesn't make it a pointer, let's just ignore it for now).

If you want to store addresses in your 64-bit app you should use ULONGLONGs or QWORDs (or just void*/BYTE* if you want actual pointer types). Define a QWORD like this:
C++:
typedef unsigned long long QWORD;
This function should do it:
C++:
QWORD GetModuleBaseAddressA(DWORD processId, char *szModuleName)
{
#ifdef _WIN64
	QWORD Ret = 0;
#else
	DWORD Ret = 0;
#endif
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 ME32;
		ME32.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &ME32))
		{
			do
			{
				if (!strcmp(ME32.szModule, szModuleName))
				{
#ifdef _WIN64
					Ret = (QWORD)ME32.modBaseAddr;
#else
					Ret = (DWORD)ME32.modBaseAddr;
#endif
					break;
				}
			} while (Module32Next(hSnapshot, &ME32));
		}
		CloseHandle(hSnapshot);
	}
	return Ret;
}
You still have to compile your hack as a 64-bit app of course but this function should work for both 32-bit and 64-bit processes.



CreateToolhelp32Snapshot basically just loops through the PEB^^
Omg i'm so close I can taste it. So I call the function and it returns some strange value "140710490406912"
But I was debugging and stepping through the function and I found this:

"Error reading characters of string"? Is that what is causing the crazy output?
--edit--
Oh I compiled as 64 bit too
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,298
37,938
269
no the type is a unsigned char * so it thinks its a string but its not a string lol
Look at the base address in cheat engine, compare to what your program outputs.

btw using @brohions method you can also do this

#ifdef _WIN64
#define returnType long long
#else
#define returnType long
#endif

then whenever you're going to use DWORD or QWORD just use returnType

and then if you want to be clean
#undef returnType

at the end

edit: also dont post addresses in decimal cause it'll always look weird no matter what, post them in hex. most of the time you'll have a flat address like F89000 , F321200 , xxxx like that.

If you want to be super sure that you have the proper base address, read process memory the first 2 bytes, if it's 0x45something ( basically, if the string is "MZ" ) then you've got the dos header and youve got the module you want
 

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Ok so in cheat engine it shows:

I'm just assuming that the module is = 1409C0370 - 01A72580 which is 13ef4ddf0
But my program outputs 863125A (when converted to hex) but i'm not sure why? :confused:
 

Broihon

edgy 12 y/o
Escobar Tier VIP
Fleep Tier Donator
Dec 22, 2013
1,746
40,528
316
Ok so in cheat engine it shows:

I'm just assuming that the module is = 1409C0370 - 01A72580 which is 13ef4ddf0
But my program outputs 863125A (when converted to hex) but i'm not sure why? :confused:
No, [bla.dll + 0x01A72580] = 0x1409C0370
And from what you posted before (click) the bla.dll is/was equivalent to 140710490406912 or 0x7FF9B6CC0000 which is a possible result.

mambda, indeed. That's much smoother xD
 

PwndDepot

I has a status
Dank Tier VIP
Trump Tier Donator
Dank Tier Donator
Nov 5, 2014
239
7,748
19
Вroihon;38593 said:
Let me combine mine and mambda's post:

C++:
typedef unsigned long long QWORD;

#ifdef _WIN64
#define RETURN_TYPE QWORD
#else
#define RETURN_TYPE DWORD
#endif

RETURN_TYPE GetModuleBaseAddressA(DWORD processId, char *szModuleName)
{
	RETURN_TYPE RetVal;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, processId);
	if (hSnapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 ME32;
		ME32.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &ME32))
		{
			do
			{
				if (!strcmp(ME32.szModule, szModuleName))
				{
					RetVal = (RETURN_TYPE)ME32.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &ME32));
		}
		CloseHandle(hSnapshot);
	}
	return RetVal;
}

#undef RETURN_TYPE
And:
C++:
DWORD dwOffsets[] = { 0x01A72580, 0x764, 0x38, 0x468 };
QWORD qwBaseaddress = GetModuleBaseAddressA(dwProcID, "gamedll_x64_rwdi.dll");
QWORD qwBuffer = qwBaseaddress;

for (UINT i = 0; i != 3 && qwBuffer != 0; ++i)
{
	qwBuffer += dwOffsets[i];
	if (!ReadProcessMemory(hProc, reinterpret_cast<void*>(qwBuffer), &qwBuffer, sizeof(QWORD), nullptr))
	{
		qwBuffer = 0;
		break;
	}
}

QWORD qwFinaladdress = 0;
if (qwBuffer)
{
	qwFinaladdress = qwBuffer + dwOffsets[3];
}
BLOWJOBS, BLOWJOBS FOR EVERYONE!!!!!
Who knew coding a simple little 64 bit hack would cause so much trouble :p
THANK YOU GUYS!!!!!!!!!!!!!
 

mambda

headass
Escobar Tier VIP
Trump Tier Donator
Jun 25, 2014
2,298
37,938
269
hey i think i like blowjobs, woooooooooooooooooooooooooooooooooooooooooooooooooooooooo
 
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