Memory Module

Modify locations in memory manually. I don’t have much more to say about it. Below is an example.

Download: http://cdbarrett.com/dump/gm_memory.zip

Source:




//---------- Includes
#include "../../gmodinterface/gmluamodule.h"

//---------- Setup Module
GMOD_MODULE( Init, Shutdown );

/*------------------------------------
	SetPointerOffsetFloat
------------------------------------*/
LUA_FUNCTION( SetPointerOffsetFloat )
{

	// checktypes
	if( Lua()->GetType( 1 ) == GLua::TYPE_NIL )
	{

		return 0;

	}
	Lua()->CheckType( 2, GLua::TYPE_NUMBER );
	Lua()->CheckType( 3, GLua::TYPE_NUMBER );

	// get the pointer
	void* data = Lua()->GetUserData( 1 );

	// offset
	int Offset = Lua()->GetInteger( 2 );

	// value
	float Value = Lua()->GetNumber( 3 );

	// set
	*(float*)( (char*)data + Offset ) = Value;

	return 0;
	
}

/*------------------------------------
	SetPointerOffsetInt
------------------------------------*/
LUA_FUNCTION( SetPointerOffsetInt )
{

	// checktypes
	if( Lua()->GetType( 1 ) == GLua::TYPE_NIL )
	{

		return 0;

	}
	Lua()->CheckType( 2, GLua::TYPE_NUMBER );
	Lua()->CheckType( 3, GLua::TYPE_NUMBER );

	// get the pointer
	void* data = Lua()->GetUserData( 1 );

	// offset
	int Offset = Lua()->GetInteger( 2 );

	// value
	int Value = Lua()->GetInteger( 3 );

	// set
	*(int*)( (char*)data + Offset ) = Value;

	return 0;
	
}

/*------------------------------------
	GetPointerOffsetFloat
------------------------------------*/
LUA_FUNCTION( GetPointerOffsetFloat )
{

	// checktypes
	if( Lua()->GetType( 1 ) == GLua::TYPE_NIL )
	{

		return 0;

	}
	Lua()->CheckType( 2, GLua::TYPE_NUMBER );
	Lua()->CheckType( 3, GLua::TYPE_NUMBER );

	// get the pointer
	void* data = Lua()->GetUserData( 1 );

	// offset
	int Offset = Lua()->GetInteger( 2 );

	// set
	Lua()->Push( *(float*)( (char*)data + Offset ) );

	return 1;
	
}

/*------------------------------------
	SetPointerOffsetInt
------------------------------------*/
LUA_FUNCTION( GetPointerOffsetInt )
{

	// checktypes
	if( Lua()->GetType( 1 ) == GLua::TYPE_NIL )
	{

		return 0;

	}
	Lua()->CheckType( 2, GLua::TYPE_NUMBER );
	Lua()->CheckType( 3, GLua::TYPE_NUMBER );

	// get the pointer
	void* data = Lua()->GetUserData( 1 );

	// offset
	int Offset = Lua()->GetInteger( 2 );

	// set
	Lua()->Push( (float)*(int*)( (char*)data + Offset ) );

	return 1;
	
}

/*------------------------------------
	SetPointerOffsetVector
------------------------------------*/
LUA_FUNCTION( SetPointerOffsetVector )
{

	// checktypes
	if( Lua()->GetType( 1 ) == GLua::TYPE_NIL )
	{

		return 0;

	}
	Lua()->CheckType( 2, GLua::TYPE_NUMBER );
	Lua()->CheckType( 3, GLua::TYPE_VECTOR );

	// get the pointer
	void* data = Lua()->GetUserData( 1 );

	// offset
	int Offset = Lua()->GetInteger( 2 );

	// set
	*(Vector*)( (char*)data + Offset ) = *(Vector*)Lua()->GetUserData( 3 );

	return 0;
	
}

/*------------------------------------
	Init
------------------------------------*/
int Init( lua_State* L )
{

	// make table
	Lua()->NewGlobalTable( "memory" );

	// add to table
	ILuaObject* memory = Lua()->GetGlobal( "memory" );
	if( memory )
	{

		// methods
		memory->SetMember( "SetFloat", SetPointerOffsetFloat );
		memory->SetMember( "SetInteger", SetPointerOffsetInt );
		memory->SetMember( "SetVector", SetPointerOffsetVector );
		memory->SetMember( "GetFloat", GetPointerOffsetFloat );
		memory->SetMember( "GetInteger", GetPointerOffsetInt );

	}

	return 0;

}

/*------------------------------------
	Shutdown
------------------------------------*/
int Shutdown( lua_State* L )
{

	return 0;

}



Extending CTakeDamageInfo to include SetDamageType.
[lua]

// require the memory module
require( “memory” );

// Damage = 44
// MaxDamage = 48
// BaseDamage = 52
// DamageType = 56
// DamageForce = 0
// DamagePosition = 12
// ReportedPosition = 24

//---------- Offsets
local OFFSET_DAMAGETYPE = 56;
local OFFSET_DAMAGEPOSITION = 12;
local OFFSET_BASEDAMAGE = 52;
local OFFSET_MAXDAMAGE = 48;

//---------- Extend Metatable
local meta = FindMetaTable( “CTakeDamageInfo” );
if( meta ) then

/*------------------------------------
	SetDamageType
------------------------------------*/
function meta:SetDamageType( dmgtype )

	// directly set
	memory.SetInteger( self, OFFSET_DAMAGETYPE, dmgtype );

end

/*------------------------------------
	GetDamageType
------------------------------------*/
function meta:GetDamageType( )

	// directly set
	return memory.GetInteger( self, OFFSET_DAMAGETYPE );

end

/*------------------------------------
	SetDamagePosition
------------------------------------*/
function meta:SetDamagePosition( vec )

	// directly set
	memory.SetVector( self, OFFSET_DAMAGEPOSITION, vec );

end

/*------------------------------------
	SetBaseDamage
------------------------------------*/
function meta:SetBaseDamage( dmg )

	// directly set
	memory.SetFloat( self, OFFSET_BASEDAMAGE, dmg );

end

/*------------------------------------
	SetMaxDamage
------------------------------------*/
function meta:SetMaxDamage( dmg )

	// directly set
	memory.SetFloat( self, OFFSET_MAXDAMAGE, dmg );

end

end

/------------------------------------
EntityTakeDamage
------------------------------------
/
local function EntityTakeDamage( victim, inflictor, attacker, amount, dmginfo )

// set to DMG_BURN
dmginfo:SetDamageType( DMG_BURN | DMG_DISSOLVE );

end
hook.Add( “EntityTakeDamage”, “Engine:EntityTakeDamage”, EntityTakeDamage );
[/lua]

It’s up to you to find the offsets yourself. I provided you with some of the offsets for CTakeDamageInfo already. When gmod updates are released offsets are bound to change, so keep that in mind.

Very useful, I can see some cool stuff being done with this.

So it lets you get/modify values from userdata? That’s pretty slick. Gmod should have this by default. Otherwise it looks like it could be very unpredictable though.

Could I do something ridiculous like changing an entity’s entindex with this?

I don’t know if this is a stupid question or not, but I’m guessing this modifies memory in Gmod’s memory space, not the entire computer’s memory right?

Now I can crash my client 5 orders of magnitude faster! :3: Thanks

Edit:

Wouldn’t that be nice. :3:

Then don’t use it. This isn’t my problem.

Wow nice, I had thought about memory fuctions for GMOD but never managed to think of any uses, but extending metatables is an awesome use for it. So doubley awesome as far as I am concerned.

Is it possible for this to make VAC trip out if run on a client?

I’m not entirely sure. It could be possible. I advise caution if people are going to use it on the client. If used properly it shouldn’t be a problem. This is really only meant to change variables on the game classes. Which change via the game anyway. I’ve only been using it on the server though.

I wonder if you can stream this to the client somehow…
Anyways, where did you get your pointer offsets?

Edit:

Wait never mind, I’ll get them myself as you said.

To get the offsets you first have to know the value of what you’re looking for. Looking at the class definition in the sourcesdk is a great help. Just loop through the pointer starting at offset 0 until you find the value you’re looking for. Then double check by making the value change somehow and looking at that offset again. If it changes to what you expect, that’s the right offset.

Oh well, I’ll just do
[lua]
for i= 1, 9999999 do
memory.SetInteger(_G, math.random(-1337,1337), math.random(-1337,1337))
end
[/lua]
And see how long I last. :downs:

Thanks, I’ll see what I can poke up.

Editing memory is useful, but I fail to see how in Gmod. I suppose it could be useful in a very few select circumstances, but mostly, I see people using this to create horrible errors. Also, variables for LUA scripts are going to change location in memory each time they’re created, so your only going to be able to interact with source variables dependably.

Oh wow.
With a little bit of ingenuity, there’s a lot that could be done with this.
We might start seeing client-side cheats as a result, but I don’t think that’s really a big deal.

It’s a very nice module, Jinto. The trouble now is thinking of anything to do with it.

The only people that would be able to make use of something like this would be the sort of people that would know how to not make GMod not crash 50% of the time.

edit: I guess you could add impulse commands to the UserCmd object. I guess that would have been very useful during that impulse 51 exploit.

Is it possible to change convar flags with this?

File gone!

Please reupload or fix the link.

Any chance for a re-upload or link fix? Or did this get broken over time or something.