Need help simulating keys using memory addresses

jx455

Member
Joined
Feb 4, 2017
Messages
9
Reaction score
1
Hi, I'm trying to simulate a left mouse click in SA:MP using memory addresses. 

0xB73458 Controls block
+0x22 = [WORD] Fire
0 = OFF
255 = ON

Here is my code:

Code:
*(WORD*)(0xB73458 + 0x22) = 255;


I thought it must be write protected.

Code:
unsigned long oldProtection;
VirtualProtect((LPVOID)0xB7347A, 1, PAGE_EXECUTE_READWRITE, &oldProtection); 


^ How come my gun won't fire when I set the value of 0xB7347A to 255? For some reason it only works when I make a cleo.

3@ = 0xB73458 
3@ += 34
write_memory 3@ size 4 value 255 virtual_protect 0 <-- Works?
 
Joined
Dec 31, 2015
Messages
712
Reaction score
27
Because you need a really quick loop in order to write it, think it's easier to emulate it with C++ rather than write a memory
 

y0mike

Active member
Joined
May 10, 2014
Messages
97
Reaction score
41
Location
mizus girl's house
can easily be done using MTA's classes
[shcode=cpp]

#define CLASS_CPad 0xB73458
#define MAX_HORN_HISTORY 5
#define STEERINGBUFFERLENGTH 10


class CControllerState
{
public:
signed short LeftStickX; // move/steer left (-128?)/right (+128)
signed short LeftStickY; // move back(+128)/forwards(-128?)
signed short RightStickX; // numpad 6(+128)/numpad 4(-128?)
signed short RightStickY;

signed short LeftShoulder1;
signed short LeftShoulder2;
signed short RightShoulder1; // target / hand brake
signed short RightShoulder2;

signed short DPadUp; // radio change up
signed short DPadDown; // radio change down
signed short DPadLeft;
signed short DPadRight;

signed short Start;
signed short Select;

signed short ButtonSquare; // jump / reverse
signed short ButtonTriangle; // get in/out
signed short ButtonCross; // sprint / accelerate
signed short ButtonCircle; // fire

signed short ShockButtonL;
signed short ShockButtonR; // look behind

signed short m_bChatIndicated;
signed short m_bPedWalk;
signed short m_bVehicleMouseLook;
signed short m_bRadioTrackSkip;

CControllerState () {
memset ( this, 0, sizeof ( CControllerState ) );
}
};


class CPadSAInterface
{
public:
CControllerState NewState; // 0
CControllerState OldState; // 48

signed short SteeringLeftRightBuffer[ STEERINGBUFFERLENGTH ]; // 96
signed long DrunkDrivingBufferUsed; // 116

//120
CControllerState PCTempKeyState;
//168
CControllerState PCTempJoyState;
//216
CControllerState PCTempMouseState;
//264
BYTE Phase; // needed for switching into right state (analogue, pressure sensitive etc)
WORD Mode; // Configuration of keys as selected by the player
signed short ShakeDur; // How long will shake go on for (in msecs)
WORD DisablePlayerControls; // If TRUE then the player cannot move, shoot, etc.
BYTE ShakeFreq; // What is the frequency of the shake
bool bHornHistory[ MAX_HORN_HISTORY ]; // Store last 4 states of the horn key TRUE on else FALSE
BYTE iCurrHornHistory; // Where to store new history value
BYTE JustOutOfFrontEnd; // Number of frames we want some of the controls disabled for.
bool bApplyBrakes; // If TRUE then apply the brakes to the player's vehicle
bool bDisablePlayerEnterCar; // Script can set this so that the Enter Car button can be used to pick up objects
bool bDisablePlayerDuck; // Script can set this
bool bDisablePlayerFireWeapon; // Script can set this
bool bDisablePlayerFireWeaponWithL1; // Script can set this - for Judith's mission where L1 is needed to pick up objects
bool bDisablePlayerCycleWeapon; // Script can set this
bool bDisablePlayerJump; // Script can set this
bool bDisablePlayerDisplayVitalStats; // Script can set this
DWORD LastTimeTouched; // The time the last input was applied by the player
signed long AverageWeapon; // Average value of the weapon button (analogue) since last reset
signed long AverageEntries;

DWORD NoShakeBeforeThis;
BYTE NoShakeFreq;
};


DWORD Main ( VOID )
{
// just a test
CPadSAInterface* pPad = reinterpret_cast< CPadSAInterface* >( CLASS_CPad );
while ( true )
{
if ( pPad != nullptr )
{
if ( GetAsyncKeyState ( VK_LSHIFT ) )
{
pPad->NewState.ButtonCircle = 255;
}
}
}
return NULL;
}
[/shcode]
 
Joined
Feb 18, 2005
Messages
2,965
Reaction score
271
But there's no difference between "*(WORD*)(0xB73458 + 0x22) = 255;" and "pPad->NewState.ButtonCircle = 255;".
AFAIK, you need to do it in the same thread as the game engine, by hooking some random func. before key processing.
 

jx455

Member
Joined
Feb 4, 2017
Messages
9
Reaction score
1
springfield said:
But there's no difference between "*(WORD*)(0xB73458 + 0x22) = 255;" and "pPad->NewState.ButtonCircle = 255;".
AFAIK, you need to do it in the same thread as the game engine, by hooking some random func. before key processing.

pPad->NewState.ButtonCircle = 255; worked with this code

Code:
void main()
{
	while ( true )
	{
		if ( GetAsyncKeyState( VK_F5 ) )
		{
			//*(WORD*)(0xB73458 + 0x22) = 255; works too
			CPadSAInterface *pPad = reinterpret_cast< CPadSAInterface *>( CLASS_CPad );
			if (pPad != nullptr)
			{
				pPad->NewState.ButtonCircle = 0xFF;
			}
		}
	}
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
	if ( ul_reason_for_call == DLL_PROCESS_ATTACH )
	{
		CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE )&main, 0, 0, 0 );
	}
	return TRUE;
}

But neither work in sobeit. So yeah, there's no difference between the two.
 

y0mike

Active member
Joined
May 10, 2014
Messages
97
Reaction score
41
Location
mizus girl's house
springfield said:
But there's no difference between "*(WORD*)(0xB73458 + 0x22) = 255;" and "pPad->NewState.ButtonCircle = 255;".
AFAIK, you need to do it in the same thread as the game engine, by hooking some random func. before key processing.

Yeah theres no difference, its just more ideal to use, and easier imo. I didn't hook any function, I simply used CreateThread on Main and it worked.

jx455 said:
springfield said:
But there's no difference between "*(WORD*)(0xB73458 + 0x22) = 255;" and "pPad->NewState.ButtonCircle = 255;".
AFAIK, you need to do it in the same thread as the game engine, by hooking some random func. before key processing.

pPad->NewState.ButtonCircle = 255; worked with this code

Code:
void main()
{
 while ( true )
 {
 if ( GetAsyncKeyState( VK_F5 ) )
 {
 //*(WORD*)(0xB73458 + 0x22) = 255; works too
 CPadSAInterface *pPad = reinterpret_cast< CPadSAInterface *>( CLASS_CPad );
 if (pPad != nullptr)
 {
 pPad->NewState.ButtonCircle = 0xFF;
 }
 }
 }
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
 if ( ul_reason_for_call == DLL_PROCESS_ATTACH )
 {
 CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE )&main, 0, 0, 0 );
 }
 return TRUE;
}

But neither work in sobeit. So yeah, there's no difference between the two.

AFAIK there is already a DllMain in s0beit in main.cpp, so you can try using CreateThread in that instead of making your own, which is what it seems like. Or you can try calling a function like below in a hook such as Present or a game func. as springfield said.
[shcode=cpp]
void SomeFunction ()
{
    CPadSAInterface* pPad = reinterpret_cast< CPadSAInterface* >( CLASS_CPad );
    if ( pPad != nullptr )
    {
        if ( GetAsyncKeyState ( VK_LSHIFT ) )
        {
            pPad->NewState.ButtonCircle = 255;
        }
    }
}
[/shcode]
 
Top