Question C++ ASI/DLL Hooking/Memory editing

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

K^2

Newbie
Full Member
Mar 25, 2013
13
202
0
Good morning all,

I'm trying to editing the values of certain memory addresses for Grand Theft Auto: Vice City, The loading bar colors to be precise, Addresses are as follows on GTAModding:

C++:
0x4A6C33 -  Moving Loading Bar Color (red) [Byte] 
0x4A6C2E -  Moving Loading Bar Color (Green) [Byte] 
0x4A6C29 -  Moving Loading Bar Color (Blue) [Byte]
I'm using Microsoft Detours 1.5

Vice City does not require a ASI loader because it's audio system (mss32.dll) loads any ASI file it finds in it's directory.
Now, the loading screen appears after clicking "Start game" -> "New game".

I pulled this address from IDA after searching "loadsc0" which is the image displayed as the loading screen background:

C++:
4A5C40
which I converted to:

C++:
0x4A5C40
So I've defined all the loading bar color address as well as the address to the function I want to hook and the pointer to that original function here:

C++:
DWORD Moving_Loading_Bar_Color_R = 0x4A6C33; //Byte
DWORD Moving_Loading_Bar_Color_G = 0x4A6C2E; //Byte
DWORD Moving_Loading_Bar_Color_B = 0x4A6C29; //Byte
#define LoadingScreenAddress 0x4A5C40
int (_cdecl* LoadingScreen)(int);
DWORD dwProtect;
My Dllmain is as follows, Detours the original function to set the R, G and B values of the moving loading bar:

C++:
BOOL APIENTRY Dllmain(HANDLE hModule, DWORD nReason, LPVOID lpReserved)
{
	switch(nReason)
	{
	case DLL_PROCESS_ATTACH:
		LoadingScreen = (int(_cdecl*)(int))DetourFunction((PBYTE)LoadingScreenAddress, (PBYTE)MovingBarColorRSet);
		LoadingScreen = (int(_cdecl*)(int))DetourFunction((PBYTE)LoadingScreenAddress, (PBYTE)MovingBarColorGSet);
		LoadingScreen = (int(_cdecl*)(int))DetourFunction((PBYTE)LoadingScreenAddress, (PBYTE)MovingBarColorBSet);
		break;

	case DLL_PROCESS_DETACH:
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	}
	return TRUE;
}
My own functions are here:

C++:
int MovingBarColorRSet(int MR, DWORD dwSize)
{
	VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_R, PAGE_READWRITE, &dwProtect);
	MR = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_R);
	MR = 140;
	return LoadingScreen(MR);
}

int MovingBarColorGSet(int MG)
{
	VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_G, PAGE_READWRITE, &dwProtect);
	MG = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_G);
	MG = 0;
	return LoadingScreen(MG);
}

int MovingBarColorBSet(int MB)
{
	VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_B, PAGE_READWRITE, &dwProtect);
	MB = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_B);
	MB = 0;
	return LoadingScreen(MB);
}
As I understand these should unprotect the memory, grab the value of the specified memory addresses (R, G and B of the moving loading bar) set R to 140 and G and B to 0 then return to the original function with the value I passed it therefor changing the color of the loading bar.

But it doesn't work and to be honest it seems as though my ASI file isn't even being detected or loaded because nothing happens.

Am I doing this correctly, I mean:

Correctly detouring the function and correctly finding the values of the addresses and correctly changing then passing them.

Any help would be greatly appreciated, I'm sorry for the long post but I've been pondering over this for weeks and tried so many different methods.

Thank you all for the help you give and the knowledge you lend.
 

squeenie

Hacker
Meme Tier VIP
Dank Tier Donator
Mar 6, 2013
677
5,478
37
I don't own this game so I cant help you too much.

C++:
int MovingBarColorRSet(int MR, DWORD dwSize)
{
    VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_R, PAGE_READWRITE, &dwProtect);
    MR = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_R);
    MR = 140;
    return LoadingScreen(MR);
}
Why does this once also take a dword?
You also need to set the Protection back before returning the original loading function.
 
  • Like
Reactions: SICGames88

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
C++:
int MovingBarColorRSet(int MR, DWORD dwSize)
{
    VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_R, PAGE_READWRITE, &dwProtect);
    MR = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_R);
    MR = 140;
    return LoadingScreen(MR);
}
 
int MovingBarColorGSet(int MG)
{
    VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_G, PAGE_READWRITE, &dwProtect);
    MG = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_G);
    MG = 0;
    return LoadingScreen(MG);
}
I haven't looked in DLL's much but why are you returning 0 - this is maybe your problem?
also make 3 different loading screen names as it looks like its probably conflicting and going to the wrong place in memory.

Also instead of declaring them first use the actual address in place of ("Moving_Loading_Bar_Color_G") - just for debugging purposes
as from experience these things can be easily missed, I once spent an hour trying to fix a problem and it was just because it wasn't reading properly.

Also what squeenie said about setting the protection back, when i go on my computer i will post an example of my virtualprotect function although its abit different from yours since you already have access to the application but youll understand it abit clearer

I might be wrong as this is DLL's but I hope its solved your problem or got you one step closer to finding out what the problem is.
 
Last edited:

K^2

Newbie
Full Member
Mar 25, 2013
13
202
0
C++:
int MovingBarColorRSet(int MR, DWORD dwSize)
{
    VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_R, PAGE_READWRITE, &dwProtect);
    MR = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_R);
    MR = 140;
    return LoadingScreen(MR);
}
 
int MovingBarColorGSet(int MG)
{
    VirtualProtect( (void*)LoadingScreenAddress, Moving_Loading_Bar_Color_G, PAGE_READWRITE, &dwProtect);
    MG = *reinterpret_cast<int *>(Moving_Loading_Bar_Color_G);
    MG = 0;
    return LoadingScreen(MG);
}
I haven't looked in DLL's much but why are you returning 0 - this is maybe your problem?
also make 3 different loading screen names as it looks like its probably conflicting and going to the wrong place in memory.

Also instead of declaring them first use the actual address in place of ("Moving_Loading_Bar_Color_G") - just for debugging purposes
as from experience these things can be easily missed, I once spent an hour trying to fix a problem and it was just because it wasn't reading properly.

Also what squeenie said about setting the protection back, when i go on my computer i will post an example of my virtualprotect function although its abit different from yours since you already have access to the application but youll understand it abit clearer

I might be wrong as this is DLL's but I hope its solved your problem or got you one step closer to finding out what the problem is.
Thank you both for your reply.

It is returning 0 because that is the value I need to pass to the blue color of R, G and B.

I need to set:

R - 140
G - 0
B- 0

So I get a specific color.

Also, I know my ASI file would already have access to the memory since the game apparently loads any ASI file found in it's directory.
But I wanted to unprotect just incase that was my problem.

Getting the right values with this is difficult because Vice City cannot be run in windowed mode (I've tried DirectX programs) and the loading screen is only shown for a couple of seconds after clicking "New game".

I'm quite baffled as to how the addresses have managed to get on GTAModding in the first place, how would the person who got them know what to look for.

Personally I think the Loading bar memory addresses are fine, I just don't think I've got the right function to hook.

I need to hook a function that is accessed after the "New game" click since that's when the loading screen appears.

But I'm not a very fluent IDA user, does anyone have any decent experience with that?

Anyway, thank you I'll try your suggestions and if you have any more then please don't hesitate to post.
 
Last edited:

Nether

The Angel Of Verdun
Meme Tier VIP
Dank Tier Donator
Dec 11, 2013
293
3,738
16
Thank you both for your reply.

It is returning 0 because that is the value I need to pass to the blue color of R, G and B.

I need to set:

R - 140
G - 0
B- 0

So I get a specific color.

Also, I know my ASI file would already have access to the memory since the game apparently loads any ASI file found in it's directory.
But I wanted to unprotect just incase that was my problem.

Getting the right values with this is difficult because Vice City cannot be run in windowed mode (I've tried DirectX programs) and the loading screen is only shown for a couple of seconds after clicking "New game".

I'm quite baffled as to how the addresses have managed to get on GTAModding in the first place, how would the person who got them know what to look for.

Personally I think the Loading bar memory addresses are fine, I just don't think I've got the right function to hook.

I need to hook a function that is accessed after the "New game" click since that's when the loading screen appears.

But I'm not a very fluent IDA user, does anyone have any decent experience with that?

Anyway, thank you I'll try your suggestions and if you have any more then please don't hesitate to post.
Aha yeah makes sense RGB sorry i didnt notice before, here is my virtualprotectex function although you will want to just use virtualprotect:

C++:
	//WRITE MEMORY
	template <class cData>
	
	void write(DWORD (Address), cData ValueToWrite)
	{	
		VirtualProtectEx(hProcess, (LPVOID)(Address), sizeof(ValueToWrite), PAGE_EXECUTE_READWRITE, &Prot); // Remove protection on protected addresses	
		WriteProcessMemory(hProcess, (LPVOID)(Address), &ValueToWrite, sizeof(ValueToWrite), NULL);	
		VirtualProtectEx(hProcess, (LPVOID)(Address), sizeof(ValueToWrite), Prot, &Prot); // Restore protection to address after write
	}
if you go on MSDN you should see how to use virtual protect - although i think it is just the same as this, and if your sure about addresses and no actual code errors try using virtual protect and if that doesn't work check that you are reading/writing correct addresses as even when ive declared addresses before ive spent hours trying to figure it out and it was just because i had (DWORD) instead of (DWORD*), if you want to skype let me know - i cant say i would be of much help but i would love to try :) - i am pretty nifty with cheat engine and IDA so if you want me to show you how to check the addresses are correct let me know
 
Last edited:

K^2

Newbie
Full Member
Mar 25, 2013
13
202
0
Aha yeah makes sense RGB sorry i didnt notice before, here is my virtualprotectex function although you will want to just use virtualprotect:

C++:
	//WRITE MEMORY
	template <class cData>
	
	void write(DWORD (Address), cData ValueToWrite)
	{	
		VirtualProtectEx(hProcess, (LPVOID)(Address), sizeof(ValueToWrite), PAGE_EXECUTE_READWRITE, &Prot); // Remove protection on protected addresses	
		WriteProcessMemory(hProcess, (LPVOID)(Address), &ValueToWrite, sizeof(ValueToWrite), NULL);	
		VirtualProtectEx(hProcess, (LPVOID)(Address), sizeof(ValueToWrite), Prot, &Prot); // Restore protection to address after write
	}
if you go on MSDN you should see how to use virtual protect - although i think it is just the same as this, and if your sure about addresses and no actual code errors try using virtual protect and if that doesn't work check that you are reading/writing correct addresses as even when ive declared addresses before ive spent hours trying to figure it out and it was just because i had (DWORD) instead of (DWORD*), if you want to skype let me know - i cant say i would be of much help but i would love to try :)
Thank you Nether, I have Skype, is it alright if you could message me your Skype name then I can explain my situation better over instant messaging.
 
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